我是 R 新手,我正在为我的个人项目/练习构建 R 代码。我使用的数据是关于香港人种族认同的调查。我使用了来自http://data.hkupop.hku.hk/v3/hkupop/ethnic_identity/ch.html的2019 年数据。
在删除 NA 值并将列减少到我需要的列之后,我注意到数据高度不平衡,因此我尝试使用欠采样、ROSE 和 SMOTE。(数量从 1015 次大幅减少到 573 次)
我从集合中删除了以下列#
df_f <- df[,-c(1,2,5,6,8,9,11,12,14,15,17,18,20,21,25,26,27,29,32,33,34,35,37)]
但是,这不是二进制数据,因此我不得不强制 eth_id 中的因素组合成 0 = 1&3(香港人和香港中国人)和 1 = 2&4(中国人和中国香港公民)
我如何结合这些因素
df_p$eth_id <- recode(df_p$eth_id, "c('1', '3')='1+3';c('2', '4') = '2+4'")
library(plyr)
revalue(df_p$eth_id, c('1+3' = 0)) -> df_p$eth_id
revalue(df_p$eth_id, c('2+4' = 1)) -> df_p$eth_id
- 0 = 香港公民 + 香港中国公民
- 1 = 中国公民 + 中国香港公民
我如何重命名列
df_f <- df_f %>%
rename(
eth_id = Q001,
HongKonger = Q002A,
Chinese = Q003A,
PRC = Q004A,
CH_race = Q005A,
Asian = Q006A,
global = Q007A,
class1 = mid,
housing1 = type,
housing2 = housingv2,
pi = inclin
)
我如何处理我的 NA 和不必要的异常值
对于 [,2:7] 列,我将它们的值更改为 0 用于 NA,例如,df_f$HongKonger <- ifelse(is.na(df_f$HongKonger),0,df_f$HongKonger)
依此类推。
对于其他人,我删除了这样的 NA:
df_p <- na.omit(df_p, cols= c("eth_id","sex","agegp","edugp","occgp","class","class2","housing1","housing2","pi"), invert=FALSE)
在我的数据集的这一点上,我剩下 14 列,我将它们重命名(请参阅上文)。我上传了我用于 ROSE 和 SMOTE 的数据的最终结构 :-)
此外,我还删除了异常值的行,例如:
删除无法识别的种族身份(8881 或级别 = 5)
df_f <- df_f[!df_f$Q001 == "8881",] table(df_f$Q001)
df_f <- df_f[!df_f$eth_id == "Don't know / hard to say",]
- 这些代码必须仔细编写,如果您在重命名之前运行它,请使用 eth_id 代替 Q001,反之亦然。
现在,当我运行 ROSE 时,我不断收到此错误:Error in [<-.data.frame
( *tmp*
, , indY, value = c(1L, 1L, 1L, 1L, 1L, : 在数据帧的下标分配中不允许缺失值。
这是非常具有误导性的,因为我确保完全删除 NA 值(因为与此相关的所有问题都与 NA 问题有关,这不适用于我的问题),我什至将所有因子值都更改为数值。(因为我认为程序不理解?因子值。)
我还收到 SMOTE 的此错误消息:名称错误(dn)<- dnn:尝试将属性设置为 NULL。这个马克
es me even more confused to the level that I am doubting the data itself being not applicable to machine learning.
Here is the final structure of my data for your reference:
'data.frame': 573 obs. of 14 variables:
$ eth_id : Factor w/ 2 levels "0","1": 2 2 1 2 1 1 1 1 1 1 ...
$ HongKonger: num 9 0 0 0 0 2 0 2 0 8 ...
$ Chinese : num 9 9 1 3 7 0 7 9 0 0 ...
$ PRC : num 8 9 1 3 7 3 1 0 1 0 ...
$ CH_race : num 12 10 0 3 7 3 0 7 3 4 ...
$ Asian : num 0 7 6 0 0 2 2 0 0 6 ...
$ global : num 0 0 0 0 0 3 7 0 10 0 ...
$ sex : num 1 2 2 1 2 1 1 2 1 2 ...
$ agegp : num 6 5 2 2 6 5 2 4 6 1 ...
$ edugp : num 2 3 2 3 1 2 2 2 3 3 ...
$ class1 : num 3 3 3 5 3 3 4 4 4 3 ...
$ housing1 : num 1 1 2 2 1 2 1 2 1 1 ...
$ housing2 : num 3 3 1 4 3 1 2 1 3 3 ...
$ pi : num 3 2 1 2 1 1 1 4 1 1 ...
- attr(*, "na.action")= 'omit' Named int 14 24 46 52 58 67 77 84 94 129 ...
..- attr(*, "names")= chr "25" "44" "82" "90" ...
#How I divided the data into train and test set
set.seed(123)
index <- createDataPartition(df_p$eth_id, p = 0.7, list = FALSE)
train_data <- df_p[index, ]
test_data <- df_p[-index, ]
head(test_data)
str(train_data)
#How I used ROSE for under-sampling
library(ROSE)
ovun.sample(formula = train_data$eth_id ~ ., data = train_data, method="under", N = 250,seed = 123)$data
我如何将 ROSE 用于“两者”
ovun.sample(formula = train_data$eth_id ~ . , data = train_data, method="both",
na.action=options("na.omit")$na.action,p=0.5,seed = 123)$data
我如何使用 SMOTE
SMOTE(form = train_data$eth_id ~., data = train_data, perc.over = 100, k = 5, perc.under = 200)
我不断得到: 1)对于 ROSE:([<-.data.frame
, *tmp*
, indY, value = c(1L, 1L, 1L, 1L, 1L, 中的错误):在数据帧的下标分配中不允许缺少值
2) 对于 SMOTE: Error in names(dn) <- dnn : 尝试将属性设置为 NULL
- 我也很困惑将所有因素更改为数值会使其仍然有效。
谢谢你,谢谢你提前分享你的知识。