Я новичок в R и создаю коды R для своего личного проекта / упражнения. Данные, которые я использую, касаются опроса этнической принадлежности людей из Гонконга. Я использовал данные 2019 из http://data.hkupop.hku.hk/v3/hkupop/ethnic_identity/ch.html.
После удаления значений NA и сокращения столбцов до значения, необходимого для меня, я заметил, что данные сильно разбалансированы, поэтому я попытался использовать недостаточную выборку, ROSE ипоражал. (число значительно уменьшилось с 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: Ошибка в [<-.data.frame
(*tmp*
,, indY, значение = c (1L, 1L, 1L, 1L, 1L,:пропущенные значения недопустимы в подписанных назначениях фреймов данных.
Это очень вводит в заблуждение, потому что я полностью удалил значения NA (потому что все вопросы, связанные с этим, были связаны с проблемой NA, которая неприменимамой), и я даже изменил все мои значения факторов на числовые (потому что я думал, что программа не понимает? значения факторов.)
Я также получаю это сообщение об ошибке для SMOTE: Ошибка в именах (dn) <- dnn: попытка установить атрибут в NULL. Это mak </p>
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: ошибка в именах (dn) <- dnn: atmpt для установки атрибута в NULL </p>
- Я также запутался, если изменить все факторы на числовое значение, это сделало бы его действительным.
Спасибо и спасибо, что поделилисьзнание впереди.