Verbesserung der SVM-Klassifikation von Diabetes

10

Ich benutze SVM, um Diabetes vorherzusagen. Ich verwende den BRFSS- Datensatz für diesen Zweck. Der Datensatz hat die Abmessungen und ist verzerrt. Der Prozentsatz von s in der Zielvariablen beträgt während die s die verbleibenden .11 % 89 %432607×136Y11%N89%

Ich verwende nur 15aus 136unabhängigen Variablen aus dem Datensatz. Einer der Gründe für die Reduzierung des Datensatzes bestand darin, mehr Trainingsmuster zu haben, wenn Zeilen mit NAs weggelassen wurden.

Diese 15Variablen wurden ausgewählt, nachdem statistische Methoden wie Zufallsbäume, logistische Regression ausgeführt und herausgefunden wurden, welche Variablen aus den resultierenden Modellen signifikant sind. Nach dem Ausführen der logistischen Regression haben wir beispielsweise p-valuedie wichtigsten Variablen sortiert.

Ist meine Methode zur Variablenauswahl korrekt? Anregungen zu ist sehr willkommen.

Das Folgende ist meine RImplementierung.

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

Ich lief mit (Training = und Test = ) Proben, da es in meinem Laptop schneller ist. Die Verwirrungsmatrix für die Testdaten ( Proben), die ich bekomme, ist ziemlich schlecht.700 300 3001000700300300

    true
pred   N   Y
   N 262  38
   Y   0   0

Ich muss meine Vorhersage für die YKlasse verbessern . Tatsächlich muss ich so genau wie möglich sein, Yauch wenn ich schlecht abschneide N. Vorschläge zur Verbesserung der Genauigkeit der Klassifizierung sind sehr willkommen.

Anand
quelle
Ich denke, Ihre SVM funktioniert überhaupt nicht, aber ich weiß nicht warum! Es kann auch besser sein, Ihre Daten zu normalisieren ...
user4581
Ja, es sagt grundsätzlich Yjede Eingabe voraus . Dies bedeutet, dass es in der korrekt ist .  90%
Anand
Das Normalisieren der Daten ist der beste Anfang. Beginnen Sie damit. Sie können auch versuchen, auch nichtlineare Kernel zu suchen, um ein besseres Ergebnis zu erzielen. (Es hängt von Ihrer Grenzvorhersage ab, möglicherweise sollte eine Normalisierung ausreichen)
404Dreamer_ML
Sie können auch versuchen, kernlabanstatt e1071- es normalisiert sich automatisch und verfügt über einige Heuristiken, die das Bootstrap des ersten Modells erleichtern.

Antworten:

9

Ich habe 4 Vorschläge:

  1. Wie wählen Sie die Variablen aus, die in Ihr Modell aufgenommen werden sollen? Möglicherweise fehlen Ihnen einige der Schlüsselindikatoren aus dem größeren Datensatz.
  2. Fast alle von Ihnen verwendeten Indikatoren (wie Geschlecht, Raucher usw.) sollten als Faktoren behandelt werden. Die Behandlung dieser Variablen als numerisch ist falsch und trägt wahrscheinlich zum Fehler in Ihrem Modell bei.
  3. Warum verwenden Sie eine SVM? Haben Sie einfachere Methoden wie die lineare Diskriminanzanalyse oder sogar die lineare Regression ausprobiert? Möglicherweise führt ein einfacher Ansatz für einen größeren Datensatz zu einem besseren Ergebnis.
  4. Probieren Sie das Caret- Paket. Es hilft Ihnen bei der Kreuzvalidierung der Modellgenauigkeit, ist parallelisiert, sodass Sie schneller arbeiten können, und erleichtert die Untersuchung verschiedener Modelltypen.

Hier ist ein Beispielcode für 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)

Dieses LDA-Modell schlägt Ihre SVM, und ich habe Ihre Faktoren nicht einmal behoben. Ich bin sicher, wenn Sie Sex, Raucher usw. als Faktoren umkodieren, werden Sie bessere Ergebnisse erzielen.

Zach
quelle
Ich erhalte den folgenden Fehler task 1 failed - "could not find function "predictionFunction"". Ich weiß, dass dies kein Forum ist, aber wenn Sie Kommentare haben, lassen Sie es mich bitte wissen.
Anand
1
@Anand: Öffnen Sie eine neue R-Sitzung als Administrator (oder führen Sie sudo R unter Mac / Linux aus). Ausführen update.packages.Wenn dies abgeschlossen ist, schließen Sie R und öffnen Sie eine normale Sitzung (ohne Administratorrechte) erneut. Führen Sie Ihren Code mit Ausnahme der Abschnitte "SVM" und "Verwirrungsmatrix" aus. Dann führen Sie meinen Code aus. Wenn Sie immer noch einen Fehler erhalten, geben Sie bitte die Zeile mit dem Fehler zusammen mit dem genauen Fehler an.
Zach
1
@Anand: Stellen Sie außerdem sicher, dass Sie die neueste Version von R (2.14) ausführen und die neueste Version von Caret verwenden. Sie können Caret aktualisieren, indem Sie es install.packages('caret')erneut ausführen .
Zach
@ Anand: Großartig! Sie können verschiedene Methoden für die trainFunktion nbeingeben , z. B. (naive Bayes), glm(logistische Regression) svmLinearund svmRadial. Es wird lange dauern, bis die SVMs passen.
Zach
3

Wenn Sie einen linearen Kernel verwenden, ist die Auswahl von Features möglicherweise eine schlechte Idee, und durch die Regularisierung kann eine Überanpassung effektiver verhindert werden als durch die Auswahl von Features. Beachten Sie, dass die Leistungsgrenzen, die die SVM ungefähr implementiert, unabhängig von der Dimension des Feature-Space sind, der eines der Verkaufsargumente der SVM war.

Dikran Beuteltier
quelle
2

Ich hatte dieses Problem vor kurzem und fand ein paar Dinge, die helfen. Probieren Sie zunächst ein Naive Bayes-Modell (Paket klaR) aus, das manchmal bessere Ergebnisse liefert, wenn die Minderheitsklasse in einem Klassifizierungsproblem winzig ist. Wenn Sie sich für eine SVM entscheiden, möchten Sie möglicherweise versuchen, die Minderheitsklasse zu überabtasten. Im Wesentlichen möchten Sie weitere Beispiele für die Minderheitsklasse einfügen oder Fälle für die Minderheitsklasse synthetisch erstellen

Dieses Papier: http: //www.it.iitb.ac.in/~kamlesh/Page/Reports/highlySkewed.pdf

Hat einige Diskussionen und Beispiele dieser Techniken in Weka implementiert, aber es ist auch möglich, sie selbst in R zu implementieren.

Dan
quelle
Danke für die hilfreichen Kommentare. Lassen Sie mich Ihre Vorschläge ausprobieren.
Anand
1

Zusätzlich zu dem, was bereits erwähnt wurde, korrigieren Sie Ihr bestes Modell für die Verwendung eines linearen Kernels. Sie sollten vorhersagen, dass Sie das beste Modell verwenden, das optimiert wurde, einschließlich des gleichen Kernels, der in Ihrer Optimierungsphase verwendet / gefunden wurde (von dem ich annehme, dass es RBF ist, da Sie Gamma optimieren).

benbo
quelle