Поліпшення класифікації SVM діабету


10

Я використовую SVM для прогнозу діабету. Для цього я використовую набір даних BRFSS . Набір даних має розміри і перекошений. Відсоток s у цільовій змінній становить тоді як s складають решта .432607×136Y11%N89%

Я використовую тільки 15з 136незалежних змінних з набору даних. Однією з причин скорочення набору даних було те, що більше одиниць тренувань, коли рядки, що містять NAs, опускаються.

Ці 15змінні були відібрані після використання статистичних методів, таких як випадкові дерева, логістична регресія та з'ясування, які змінні є істотними з отриманих моделей. Наприклад, після проведення логістичної регресії ми використовували p-valueдля впорядкування найбільш значущих змінних.

Чи правильний мій метод вибору змінної? Будь-які пропозиції щодо дуже вітаються.

Далі йде моя Rреалізація.

library(e1071) # Support Vector Machines

#--------------------------------------------------------------------
# read brfss file (huge 135 MB file)
#--------------------------------------------------------------------
y <- read.csv("http://www.hofroe.net/stat579/brfss%2009/brfss-2009-clean.csv")
indicator <- c("DIABETE2", "GENHLTH", "PERSDOC2", "SEX", "FLUSHOT3", "PNEUVAC3", 
    "X_RFHYPE5", "X_RFCHOL", "RACE2", "X_SMOKER3", "X_AGE_G", "X_BMI4CAT", 
    "X_INCOMG", "X_RFDRHV3", "X_RFDRHV3", "X_STATE");
target <- "DIABETE2";
diabetes <- y[, indicator];

#--------------------------------------------------------------------
# recode DIABETE2
#--------------------------------------------------------------------
x <- diabetes$DIABETE2;
x[x > 1]  <- 'N';
x[x != 'N']  <- 'Y';
diabetes$DIABETE2 <- x; 
rm(x);

#--------------------------------------------------------------------
# remove NA
#--------------------------------------------------------------------
x <- na.omit(diabetes);
diabetes <- x;
rm(x);

#--------------------------------------------------------------------
# reproducible research 
#--------------------------------------------------------------------
set.seed(1612);
nsamples <- 1000; 
sample.diabetes <- diabetes[sample(nrow(diabetes), nsamples), ]; 

#--------------------------------------------------------------------
# split the dataset into training and test
#--------------------------------------------------------------------
ratio <- 0.7;
train.samples <- ratio*nsamples;
train.rows <- c(sample(nrow(sample.diabetes), trunc(train.samples)));

train.set  <- sample.diabetes[train.rows, ];
test.set   <- sample.diabetes[-train.rows, ];

train.result <- train.set[ , which(names(train.set) == target)];
test.result  <- test.set[ , which(names(test.set) == target)];

#--------------------------------------------------------------------
# SVM 
#--------------------------------------------------------------------
formula <- as.formula(factor(DIABETE2) ~ . );
svm.tune <- tune.svm(formula, data = train.set, 
    gamma = 10^(-3:0), cost = 10^(-1:1));
svm.model <- svm(formula, data = train.set, 
    kernel = "linear", 
    gamma = svm.tune$best.parameters$gamma, 
    cost  = svm.tune$best.parameters$cost);

#--------------------------------------------------------------------
# Confusion matrix
#--------------------------------------------------------------------
train.pred <- predict(svm.model, train.set);
test.pred  <- predict(svm.model, test.set);
svm.table <- table(pred = test.pred, true = test.result);
print(svm.table);

Я бігав з (навчання = і тест = ) зразків, оскільки це швидше в моєму ноутбуці. Матриця плутанини для тестових даних ( зразків), які я отримую, є досить поганою.1000700300300

    true
pred   N   Y
   N 262  38
   Y   0   0

Мені потрібно покращити своє передбачення для Yкласу. Насправді мені потрібно бути максимально точним, Yнавіть якщо я погано виступаю N. Будь-які пропозиції щодо підвищення точності класифікації були б вдячні.


Я думаю, що ваш SVM взагалі не працює, але не знаю чому! також може бути краще нормалізувати ваші дані ...
user4581

Y 90%

Нормалізація даних - найкраще почати. Почніть з цього. Ви також можете спробувати здійснити пошук, також нелінійне ядро ​​може показати кращий результат. (Це залежить від вашого прикордонного положення, можливо, нормалізації повинно бути достатньо)
404Dreamer_ML

Ви також можете спробувати kernlabзамість цього e1071- він нормалізується автоматично і має деякі евристики, що полегшує завантаження першої моделі.

Відповіді:


9

У мене є 4 пропозиції:

  1. Як ви обираєте змінні, які потрібно включити до вашої моделі? Можливо, вам не вистачає деяких ключових показників з більшого набору даних.
  2. Майже всі показники, які ви використовуєте (наприклад, секс, курець тощо), слід розглядати як фактори. Трактувати ці змінні як числові помилково і, ймовірно, сприяє помилці у вашій моделі.
  3. Чому ви використовуєте SVM? Чи пробували ви простіші методи, такі як лінійний дискримінантний аналіз чи навіть лінійна регресія? Можливо, простий підхід до більшого набору даних дасть кращий результат.
  4. Спробуйте пакет карет . Це допоможе вам перехресно визначити точність моделі, вона буде паралельна, що дозволить вам працювати швидше, і це полегшує вивчення різних типів моделей.

Ось приклад коду для карети:

library(caret)

#Parallize
library(doSMP)
w <- startWorkers()
registerDoSMP(w)

#Build model
X <- train.set[,-1]
Y <- factor(train.set[,1],levels=c('N','Y'))
model <- train(X,Y,method='lda')

#Evaluate model on test set
print(model)
predY <- predict(model,test.set[,-1])
confusionMatrix(predY,test.set[,1])
stopWorkers(w)

Ця модель LDA перемагає ваш SVM, і я навіть не виправляв ваші фактори. Я впевнений, що якщо ви перекодуєте секс, курець тощо як фактори, ви отримаєте кращі результати.


Я отримую таку помилку task 1 failed - "could not find function "predictionFunction"". Я знаю, що це не форум, але якщо у вас є якісь коментарі, будь ласка, дайте мені знати.
Ананд

1
@Anand: відкрийте новий сеанс R як адміністратор (або запустіть sudo R на mac / linux). Запустити. update.packages.Коли це закінчено, закрийте R та повторно відкрийте звичайний (не адміністратор) сеанс. Запустіть свій код, за винятком розділів "SVM" та "Матриця плутанини". Потім запустіть мій код. Якщо ви все-таки отримаєте помилку, будь ласка, опублікуйте рядок, який повернув помилку, а також точну помилку.
Зак

1
@Anand: Також переконайтеся, що ви використовуєте останню версію R (2.14) та використовуєте останню версію caret. Можна оновити карету, запустивши install.packages('caret')знову.
Зак

@Anand: Чудово! Ви можете використовувати різні методи trainфункції, такі як nb(наївні баєси), glm(логістична регресія) svmLinearта svmRadial. Для встановлення svm потрібно багато часу.
Зак

3

Якщо ви використовуєте лінійне ядро, то, можливо, вибір функцій є поганою ідеєю, і регуляризація може запобігти переналагодженню більш ефективно, ніж може вибрати вибір функції. Зауважте, що межі продуктивності, які SVM приблизно реалізує, не залежать від розміру простору функцій, який був однією з точок продажу SVM.


2

У мене ця проблема була недавно, і я знайшов пару речей, які допомагають. По-перше, спробуйте модель Naive Bayes (пакунок klaR), яка іноді дає кращі результати, коли клас меншості в проблемі класифікації крихітний. Крім того, якщо ви вирішите дотримуватися SVM, ви, можливо, захочете спробувати мізерний клас міноритарності. По суті, ви хочете включити більше прикладів класу меншин або синтетично створити випадки для класу меншості

Цей документ: http: //www.it.iitb.ac.in/~kamlesh/Page/Reports/highlySkewed.pdf

Деякі обговорення та приклади цих прийомів реалізовані у Weka, але можливе введення їх також у R також.


Дякуємо за корисні коментарі. Дозвольте спробувати ваші пропозиції.
Ананд

1

Окрім того, що вже було сказано, ви закріплюєте свою найкращу модель для використання лінійного ядра. Ви повинні передбачити використання найкращої моделі, яка була налаштована, включаючи те саме ядро, яке було використано / знайдено у вашому етапі настройки (я вважаю, що це RBF, оскільки ви налаштовуєте гаму).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.