Miglioramento della classificazione SVM del diabete


10

Sto usando SVM per prevedere il diabete. Sto usando il set di dati BRFSS per questo scopo. Il set di dati ha le dimensioni di ed è inclinato. La percentuale di s nella variabile target è mentre s costituisce il restante .11 % 89 %432607×136Y11%N89%

Sto usando solo 15di 136variabili indipendenti dal set di dati. Uno dei motivi per ridurre il set di dati è stato quello di avere più campioni di addestramento quando le righe contenenti NAs sono state omesse.

Queste 15variabili sono state selezionate dopo aver eseguito metodi statistici come alberi casuali, regressione logistica e scoprire quali variabili sono significative dai modelli risultanti. Ad esempio, dopo aver eseguito la regressione logistica, abbiamo usato p-valueper ordinare le variabili più significative.

Il mio metodo di selezione delle variabili è corretto? Qualsiasi suggerimento è molto gradito.

Quella che segue è la mia Rimplementazione.

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

Ho corso con (training = e test = ) campioni poiché è più veloce nel mio laptop. La matrice di confusione per i dati del test ( campioni) che ottengo è piuttosto negativa.700 300 3001000700300300

    true
pred   N   Y
   N 262  38
   Y   0   0

Devo migliorare la mia previsione per la Yclasse. In effetti, devo essere il più preciso possibile Yanche se mi esibisco male N. Qualsiasi suggerimento per migliorare l'accuratezza della classificazione sarebbe molto apprezzato.


Immagino che il tuo SVM non funzioni affatto, ma non so perché! potrebbe anche essere meglio normalizzare i tuoi dati ...
user4581

Sì, prevede praticamente Yqualsiasi input. Ciò significa che sarà corretto delle volte.  90%
Anand,

Normalizzare i dati è la cosa migliore da iniziare. Inizia da quello. Puoi anche provare a cercare anche il kernel non lineare potrebbe mostrare un risultato migliore. (Dipende dalla tua previsione alla frontiera, potrebbe essere normalizzare dovrebbe essere sufficiente)
404Dreamer_ML

Puoi anche provare kernlabinvece e1071- esegue automaticamente la normalizzazione e ha alcune euristiche che facilitano l'avvio del primo modello.

Risposte:


9

Ho 4 suggerimenti:

  1. Come scegli le variabili da includere nel tuo modello? Forse ti mancano alcuni degli indicatori chiave del set di dati più grande.
  2. Quasi tutti gli indicatori che stai utilizzando (come sesso, fumatore, ecc.) Dovrebbero essere trattati come fattori. Trattare queste variabili come numeriche è errato e probabilmente contribuisce all'errore nel modello.
  3. Perché stai usando un SVM? Hai provato metodi più semplici, come l'analisi discriminante lineare o anche la regressione lineare? Forse un semplice approccio su un set di dati più grande produrrà un risultato migliore.
  4. Prova il pacchetto con il cursore . Ti aiuterà a convalidare in modo incrociato l'accuratezza del modello, è parallelizzato che ti consentirà di lavorare più velocemente e ti consentirà di esplorare facilmente diversi tipi di modelli.

Ecco alcuni esempi di codice per il cursore:

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)

Questo modello LDA batte il tuo SVM e non ho nemmeno corretto i tuoi fattori. Sono sicuro che se ricodifichi il sesso, il fumatore, ecc. Come fattori, otterrai risultati migliori.


Ottengo il seguente errore task 1 failed - "could not find function "predictionFunction"". So che questo non è un forum, ma se avete commenti per favore fatemelo sapere.
Anand,

1
@Anand: Apri una nuova sessione R come admin (o esegui sudo R su mac / linux). Esegui update.packages.Al termine, chiudere R e riaprire una sessione normale (non amministrativa). Esegui il codice ad eccezione delle sezioni "SVM" e "Matrice di confusione". Quindi esegui il mio codice. Se ricevi ancora un errore, pubblica la riga che ha restituito un errore, insieme all'errore esatto.
Zach,

1
@Anand: Inoltre, assicurati di avere l'ultima versione di R (2.14) e di utilizzare l'ultima versione di caret. Puoi aggiornare il cursore eseguendolo di install.packages('caret')nuovo.
Zach,

@Ananda: fantastico! È possibile inserire diversi metodi per la trainfunzione, come nb(bayes ingenui), glm(regressione logistica) svmLineare svmRadial. Gli svm impiegheranno molto tempo per adattarsi.
Zach,

3

Se si utilizza un kernel lineare, è possibile che la selezione delle funzionalità sia una cattiva idea e che la regolarizzazione possa impedire un adattamento eccessivo in modo più efficace rispetto alla selezione delle funzionalità. Si noti che le prestazioni limitano che SVM implementa approssimativamente sono indipendenti dalla dimensione dello spazio delle caratteristiche, che era uno dei punti di vendita di SVM.


2

Ho avuto questo problema di recente e ho trovato un paio di cose che aiutano. Innanzitutto, prova un modello Naive Bayes (pacchetto klaR) che a volte ti dà risultati migliori quando la classe di minoranza in un problema di classificazione è minuscola. Inoltre, se scegli di rimanere con un SVM potresti provare a sovracampionare la classe di minoranza. In sostanza, vorrai includere più esempi della classe di minoranza o creare sinteticamente casi per la classe di minoranza

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

Ha alcune discussioni ed esempi di queste tecniche implementate in Weka, ma è anche possibile implementarle in R.


Grazie per i commenti utili. Lasciami provare i tuoi suggerimenti.
Anand,

1

Oltre a quanto già accennato, stai risolvendo il tuo modello migliore per usare un kernel lineare. Dovresti predire usando il miglior modello che è stato sintonizzato, incluso lo stesso kernel che è stato usato / trovato nella tua fase di tuning (che presumo sia RBF poiché stai accordando la gamma).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.