Amélioration de la classification SVM du diabète

10

432607×136Y11%N89%

J'utilise uniquement 15des 136variables indépendantes de l'ensemble de données. L'une des raisons de la réduction de l'ensemble de données était d'avoir plus d'échantillons d'apprentissage lorsque les lignes contenant NAs sont omises.

Ces 15variables ont été sélectionnées après l'exécution de méthodes statistiques telles que les arbres aléatoires, la régression logistique et la découverte des variables significatives à partir des modèles résultants. Par exemple, après avoir effectué une régression logistique, nous avons utilisé p-valuepour classer les variables les plus significatives.

Ma méthode de sélection des variables est-elle correcte? Toutes les suggestions sont les bienvenues.

Ce qui suit est ma Rmise en œuvre.

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

J'ai besoin d'améliorer mes prévisions pour la Yclasse. En fait, je dois être aussi précis que possible avec Ymême si je donne de mauvais résultats avec N. Toute suggestion visant à améliorer la précision de la classification serait grandement appréciée.

Anand
la source
Je suppose que votre SVM ne fonctionne pas du tout, mais je ne sais pas pourquoi! peut aussi être préférable de normaliser vos données ...
user4581
Y 90%
Normaliser les données est la meilleure chose à faire. Commencez par ça. Vous pouvez également essayer de rechercher le noyau non linéaire peut également afficher un meilleur résultat. (Cela dépend de votre prévision de frontière, la normalisation devrait être suffisante)
404Dreamer_ML
Vous pouvez également essayer kernlabau lieu de e1071- il effectue automatiquement la normalisation et possède des heuristiques facilitant l'amorçage du premier modèle.

Réponses:

9

J'ai 4 suggestions:

  1. Comment choisissez-vous les variables à inclure dans votre modèle? Vous manquez peut-être certains des indicateurs clés de l'ensemble de données plus large.
  2. Presque tous les indicateurs que vous utilisez (comme le sexe, le fumeur, etc.) doivent être traités comme des facteurs. Traiter ces variables sous forme numérique est incorrect et contribue probablement à l'erreur dans votre modèle.
  3. Pourquoi utilisez-vous un SVM? Avez-vous essayé des méthodes plus simples, telles que l'analyse discriminante linéaire ou même la régression linéaire? Peut-être qu'une approche simple sur un plus grand ensemble de données donnera un meilleur résultat.
  4. Essayez le package caret . Il vous aidera à valider la précision des modèles, il est parallélisé, ce qui vous permettra de travailler plus rapidement et vous permettra d'explorer facilement différents types de modèles.

Voici un exemple de code pour le signe d'insertion:

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)

Ce modèle LDA bat votre SVM, et je n'ai même pas corrigé vos facteurs. Je suis sûr que si vous recodez le sexe, le fumeur, etc. comme facteurs, vous obtiendrez de meilleurs résultats.

Zach
la source
J'obtiens l'erreur suivante task 1 failed - "could not find function "predictionFunction"". Je sais que ce n'est pas un forum mais si vous avez des commentaires, faites-le moi savoir.
Anand
1
@Anand: Ouvrez une nouvelle session R en tant qu'administrateur (ou exécutez sudo R sur mac / linux). Exécuter update.packages.Lorsque cela est terminé, fermez R et rouvrez une session normale (non administrateur). Exécutez votre code à l'exception des sections "SVM" et "Confusion matrix". Ensuite, exécutez mon code. Si vous obtenez toujours une erreur, veuillez publier la ligne qui a renvoyé une erreur, ainsi que l'erreur exacte.
Zach
1
@Anand: Assurez-vous également que vous utilisez la dernière version de R (2.14) et que vous utilisez la dernière version de caret. Vous pouvez mettre à jour le curseur en exécutant à install.packages('caret')nouveau.
Zach
@Anand: Génial! Vous pouvez ajouter différentes méthodes pour la trainfonction, telles que nb(bayes naïves), glm(régression logistique) svmLinearet svmRadial. Le svm prendra beaucoup de temps pour s'adapter.
Zach
3

Si vous utilisez un noyau linéaire, il est possible que la sélection de fonctionnalités soit une mauvaise idée et que la régularisation puisse empêcher un sur-ajustement plus efficace que la sélection de fonctionnalités. Notez que les limites de performances qu'implémente approximativement le SVM sont indépendantes de la dimension de l'espace des fonctionnalités, qui était l'un des arguments de vente du SVM.

Dikran Marsupial
la source
2

J'ai eu ce problème récemment et j'ai trouvé quelques choses qui aident. Tout d'abord, essayez un modèle Naive Bayes (package klaR) qui vous donne parfois de meilleurs résultats lorsque la classe minoritaire dans un problème de classification est minuscule. De plus, si vous choisissez de vous en tenir à un SVM, vous voudrez peut-être essayer de suréchantillonner la classe minoritaire. Essentiellement, vous voudrez inclure plus d'exemples de la classe minoritaire ou créer synthétiquement des cas pour la classe minoritaire

Ce document: http: //www.it.iitb.ac.in/~kamlesh/Page/Reports/highlySkewed.pdf

A une discussion et des exemples de ces techniques implémentées dans Weka, mais les implémenter vous-même dans R est également possible.

Dan
la source
Merci pour les commentaires utiles. Laissez-moi essayer vos suggestions.
Anand
1

En plus de ce qui a déjà été mentionné, vous fixez votre meilleur modèle pour utiliser un noyau linéaire. Vous devez prédire en utilisant le meilleur modèle qui a été réglé, y compris le même noyau qui a été utilisé / trouvé dans votre étape de réglage (qui, je suppose, est RBF puisque vous ajustez le gamma).

benbo
la source