Mejora de la clasificación SVM de diabetes

10

Estoy usando SVM para predecir la diabetes. Estoy usando el conjunto de datos BRFSS para este propósito. El conjunto de datos tiene las dimensiones de y está sesgado. El porcentaje de s en la variable objetivo es mientras que los s constituyen el restante .432607×136Y11%N89%

Estoy utilizando solamente 15de 136variables independientes del conjunto de datos. Una de las razones para reducir el conjunto de datos fue tener más muestras de entrenamiento cuando NAse omiten las filas que contienen s.

Estas 15variables se seleccionaron después de ejecutar métodos estadísticos como árboles aleatorios, regresión logística y descubrir qué variables son significativas a partir de los modelos resultantes. Por ejemplo, después de ejecutar la regresión logística, solíamos p-valueordenar las variables más significativas.

¿Es correcto mi método de selección de variables? Cualquier sugerencia es muy bienvenida.

La siguiente es mi Rimplementación.

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);

Corrí con (entrenamiento = y prueba = ) muestras ya que es más rápido en mi computadora portátil. La matriz de confusión para los datos de prueba ( muestras) que obtengo es bastante mala.1000700300300

    true
pred   N   Y
   N 262  38
   Y   0   0

Necesito mejorar mi predicción para la Yclase. De hecho, necesito ser lo más preciso posible Yincluso si me desempeño mal N. Cualquier sugerencia para mejorar la precisión de la clasificación sería muy apreciada.

Anand
fuente
Supongo que tu SVM no funciona en absoluto, ¡pero no sé por qué! también puede ser mejor normalizar sus datos ...
user4581
Sí, básicamente predice Ycualquier entrada. Esto significa que será correcto del tiempo.  90%
Anand
Normalizar los datos es lo mejor para comenzar. Comience por eso. También puede intentar buscar, también el núcleo no lineal puede mostrar un mejor resultado. (Depende de su previsión fronteriza, la normalización debería ser suficiente)
404Dreamer_ML
También puede intentarlo en kernlablugar de hacerlo e1071: se normaliza automáticamente y tiene algunas heurísticas que facilitan el arranque del primer modelo.

Respuestas:

9

Tengo 4 sugerencias:

  1. ¿Cómo elige las variables para incluir en su modelo? Quizás le faltan algunos indicadores clave del conjunto de datos más grande.
  2. Casi todos los indicadores que está utilizando (como sexo, fumador, etc.) deben tratarse como factores. Tratar estas variables como numéricas es incorrecto y probablemente esté contribuyendo al error en su modelo.
  3. ¿Por qué estás usando un SVM? ¿Intentó algún método más simple, como el análisis discriminante lineal o incluso la regresión lineal? Quizás un enfoque simple en un conjunto de datos más grande arrojará un mejor resultado.
  4. Prueba el paquete caret . Le ayudará a validar la precisión del modelo, está paralelizado, lo que le permitirá trabajar más rápido, y facilita la exploración de diferentes tipos de modelos.

Aquí hay un código de ejemplo para caret:

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)

Este modelo LDA supera tu SVM, y ni siquiera solucioné tus factores. Estoy seguro de que si recodifica Sexo, Fumador, etc. como factores, obtendrá mejores resultados.

Zach
fuente
Me sale el siguiente error task 1 failed - "could not find function "predictionFunction"". Sé que este no es un foro, pero si tiene algún comentario, hágamelo saber.
Anand
1
@Anand: abra una nueva sesión de R como administrador (o ejecute sudo R en mac / linux). Ejecutar update.packages.Cuando termine, cierre R y vuelva a abrir una sesión normal (no administrativa). Ejecute su código, excepto las secciones "SVM" y "Matriz de confusión". Entonces ejecuta mi código. Si aún recibe un error, publique la línea que devolvió un error, junto con el error exacto.
Zach
1
@Anand: Además, asegúrese de estar ejecutando la última versión de R (2.14) y de utilizar la última versión de caret. Puede actualizar caret ejecutando install.packages('caret')nuevamente.
Zach
@ Anand: ¡Genial! Puede colocar diferentes métodos para la trainfunción, como nb(bayes ingenuos), glm(regresión logística) svmLineary svmRadial. Los svm tardarán mucho en adaptarse.
Zach
3

Si está utilizando un núcleo lineal, entonces es posible que la selección de características sea una mala idea, y que la regularización pueda evitar un ajuste excesivo más eficaz que la selección de características. Tenga en cuenta que los límites de rendimiento que el SVM implementa aproximadamente son independientes de la dimensión del espacio de características, que era uno de los puntos de venta del SVM.

Dikran Marsupial
fuente
2

Recientemente tuve este problema y encontré un par de cosas que ayudan. Primero, pruebe un modelo Naive Bayes (paquete klaR) que a veces le da mejores resultados cuando la clase minoritaria en un problema de clasificación es pequeña. Además, si elige quedarse con un SVM, puede intentar sobremuestrear la clase minoritaria. Esencialmente, querrás incluir más ejemplos de la clase minoritaria o crear casos sintéticos para la clase minoritaria

Este documento: http: //www.it.iitb.ac.in/~kamlesh/Page/Reports/highlySkewed.pdf

Tiene algunas discusiones y ejemplos de estas técnicas implementadas en Weka, pero también es posible implicarlas en R.

Dan
fuente
Gracias por los útiles comentarios. Déjame probar tus sugerencias.
Anand
1

Además de lo que ya se ha mencionado, está arreglando su mejor modelo para usar un núcleo lineal. Debe predecir el uso del mejor modelo que se ajustó, incluido el mismo núcleo que se usó / encontró en su etapa de ajuste (que supongo que es RBF ya que está ajustando gamma).

benbo
fuente