2013-11-04 14 views
15

Non riesco a trovare un modo per eseguire la convalida incrociata su un modello di foresta casuale di regressione che sto cercando di produrre.Come eseguire la convalida casuale della foresta/croce in R

Quindi ho un set di dati contenente 1664 variabili esplicative (diverse proprietà chimiche), con una variabile di risposta (tempo di ritenzione). Sto cercando di produrre un modello di foresta casuale di regressione per poter prevedere le proprietà chimiche di qualcosa dato il suo tempo di ritenzione.

ID RT (seconds) 1_MW 2_AMW 3_Sv 4_Se 
4281 38 145.29 5.01 14.76 28.37 
4952 40 132.19 6.29 11 21.28 
4823 41 176.21 7.34 12.9 24.92 
3840 41 174.24 6.7 13.99 26.48 
3665 42 240.34 9.24 15.2 27.08 
3591 42 161.23 6.2 13.71 26.27 
3659 42 146.22 6.09 12.6 24.16 

Questo è un esempio del tavolo che ho. Voglio fondamentalmente tracciare RT contro 1_MW, ecc (fino a 1664 variabili), così posso trovare quali di queste variabili sono importanti e quali no.

faccio: -

r = randomForest(RT..seconds.~., data = cadets, importance =TRUE, do.trace = 100) 
varImpPlot(r) 

che mi dice che le variabili sono di importanza e cosa no, che è grande. Tuttavia, voglio essere in grado di partizionare il mio set di dati in modo da poter eseguire la convalida incrociata su di esso. Ho trovato un tutorial online che spiegava come farlo, ma per un modello di classificazione piuttosto che per la regressione.

ho capito che fate: -

k = 10 
n = floor(nrow(cadets)/k) 
i = 1 
s1 = ((i-1) * n+1) 
s2 = (i * n) 
subset = s1:s2 

per definire quanti croce pieghe che si vuole fare, e la dimensione di ogni piega, e per impostare il valore di partenza e la fine del sottoinsieme. Tuttavia, non so cosa fare qui dopo. Mi è stato detto di collegarmi ma sinceramente non ho idea di come farlo. Né so come poi tracciare il set di validazione e il set di test sullo stesso grafico per rappresentare il livello di accuratezza/errore.

Se potessi aiutarmi con questo sarei davvero grato, grazie!

+0

Se siete ancora interessati a CV in R v'è almeno un paio: [accento circonflesso] (http://cran.r-project.org/web/packages/caret/caret.pdf) e [cvTools ] (http://cran.r-project.org/web/packages/cvTools/cvTools.pdf) – topchef

risposta

0

Questo è in realtà più veloce e abbastanza facile da eseguire in Python utilizzando la libreria scikit-learn (http://scikit-learn.org/stable/modules/cross_validation.html). Puoi eseguire la convalida K-fold, la K-fold stratificata (che garantisce che le classi siano equamente distribuite in ciascuna delle pieghe), lasciarne una e altre.

È anche molto facile generare la curva ROC, le funzionalità importance e altre metriche di valutazione.

Ecco un rapido esempio:

y = data[1:, 0].astype(np.float) 
X = data[1:, 1:].astype(np.float) 
cv = StratifiedKFold(y, n_folds = 5) 

precision = [] 
accuracy = [] 
sensitivity = [] 
matthews = [] 
r2   = [] 
f1   = [] 
auroc  = [] 
cm   = [[0, 0], [0, 0]] 

for i, (train, test) in enumerate(cv): 
    probas_  = rf.fit(X[train], y[train]).predict_proba(X[test]) 
    classes  = rf.fit(X[train], y[train]).predict(X[test]) 
    r2   = np.append(r2, (r2_score(y[test], probas_[:, 1]))) 
    precision = np.append(precision, (precision_score(y[test], classes))) 
    auroc  = np.append(auroc, (roc_auc_score(y[test], classes))) 
    accuracy = np.append(accuracy, (accuracy_score(y[test], classes))) 
    sensitivity = np.append(sensitivity, (recall_score(y[test], classes))) 
    f1   = np.append(f1, (f1_score(y[test], classes))) 
    matthews = np.append(matthews, (matthews_corrcoef(y[test], classes))) 
    cma   = np.add(cma, (confusion_matrix(y[test], classes))) 

cma   = np.array(cma) 
r2   = np.array(r2) 
precision = np.array(precision) 
accuracy = np.array(accuracy) 
sensitivity = np.array(sensitivity) 
f1   = np.array(f1) 
auroc  = np.array(auroc) 
matthews = np.array(matthews) 

print("KF Accuracy: %0.2f (+/- %0.2f)" % (accuracy.mean(), accuracy.std() * 2)) 
print("KF Precision: %0.2f (+/- %0.2f)" % (precision.mean(), precision.std() * 2)) 
print("KF Sensitivity: %0.2f (+/- %0.2f)" % (sensitivity.mean(), sensitivity.std() * 2)) 
print("KF R^2: %0.2f (+/- %0.2f)" % (r2.mean(), r2.std() * 2)) 
print("KF F1: %0.2f (+/- %0.2f)" % (f1.mean(), f1.std() * 2)) 
print("KF AUROC: %0.2f (+/- %0.2f)" % (auroc.mean(), auroc.std() * 2)) 
print("KF Matthews: %0.2f (+/- %0.2f)" % (matthews.mean(), matthews.std() * 2)) 
print("Confusion Matrix", cma) 
+5

Come potrebbe essere questa la risposta accettata, l'utente ha chiesto una risposta usando R, hai risposto usando Python .... –

28

Dal source:

stimare l'errore (OOB) out-of-bag

Nelle foreste casuali, non v'è alcuna necessità di convalida incrociata o un test separato impostato su ottenere una stima obiettiva dell'errore del set di test. Si stimata internamente, durante la corsa ...

In particolare, predict.randomForest restituisce la previsione out-of-bag se newdata non è dato.

10

Come topchef pointed out, la convalida incrociata non è necessaria come una guardia contro l'eccesso di raccordo. Questa è una caratteristica interessante dell'algoritmo della foresta casuale.

Sembra che il tuo obiettivo sia la selezione delle funzionalità, la convalida incrociata è ancora utile per questo scopo. Dai un'occhiata alla funzione rfcv() all'interno del pacchetto randomForest. La documentazione specifica l'input di un vettore di dati & vector, quindi inizierò creando quelli con i tuoi dati.

set.seed(42) 
x <- cadets 
x$RT..seconds. <- NULL 
y <- cadets$RT..seconds. 

rf.cv <- rfcv(x, y, cv.fold=10) 

with(rf.cv, plot(n.var, error.cv)) 
+2

questa funzione esegue davvero la convalida incrociata? Non mostra l'errore in relazione alla quantità di variabili utilizzate? – marbel