2015-05-21 11 views
9

Ho una matrice con 20 colonne. L'ultima colonna sono etichette 0/1.Differenza tra l'uso di train_test_split e cross_val_score in sklearn.cross_validation

Il collegamento ai dati è here.

Sto cercando di eseguire una foresta casuale sul set di dati, utilizzando la convalida incrociata. Io uso due metodi per farlo:

  1. utilizzando sklearn.cross_validation.cross_val_score
  2. utilizzando sklearn.cross_validation.train_test_split

sto ottenendo risultati diversi quando faccio quello che penso è praticamente la stessa cosa esatta. Per esemplificare, eseguo una doppia convalida incrociata utilizzando i due metodi sopra, come nel codice qui sotto.

import csv 
import numpy as np 
import pandas as pd 
from sklearn import ensemble 
from sklearn.metrics import roc_auc_score 
from sklearn.cross_validation import train_test_split 
from sklearn.cross_validation import cross_val_score 

#read in the data 
data = pd.read_csv('data_so.csv', header=None) 
X = data.iloc[:,0:18] 
y = data.iloc[:,19] 

depth = 5 
maxFeat = 3 

result = cross_val_score(ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False), X, y, scoring='roc_auc', cv=2) 

result 
# result is now something like array([ 0.66773295, 0.58824739]) 

xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.50) 

RFModel = ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False) 
RFModel.fit(xtrain,ytrain) 
prediction = RFModel.predict_proba(xtest) 
auc = roc_auc_score(ytest, prediction[:,1:2]) 
print auc #something like 0.83 

RFModel.fit(xtest,ytest) 
prediction = RFModel.predict_proba(xtrain) 
auc = roc_auc_score(ytrain, prediction[:,1:2]) 
print auc #also something like 0.83 

La mia domanda è:

Perché ricevo risultati diversi, vale a dire, perché è l'AUC (la metrica che sto usando) più elevato quando uso train_test_split?

Nota: Nota: Quando uso più pieghe (diciamo 10 volte), nei miei risultati sembra esserci una sorta di motivo, con il primo calcolo che mi dà sempre l'AUC più alto.

Nel caso della convalida incrociata doppia nell'esempio sopra, la prima AUC è sempre superiore alla seconda; è sempre qualcosa come 0.70 e 0.58.

Grazie per il vostro aiuto!

+0

i dati sono inizialmente randomizzati? Se ricordo bene, uno o entrambi i due metodi predefiniti per dividere i dati senza randomizzazione. Questo potrebbe spiegare il "modello" a cui fai riferimento, anche se probabilmente non spiegherebbe i risultati complessivi più poveri con il primo metodo (potrebbe però) – KCzar

+0

No, i dati non sono inizialmente randomizzati. Sembra essere una buona spiegazione del motivo per cui i risultati mostrano lo stesso modello in cross_val_score. Immagino che l'unica parte casuale di cross_val_score nel mio caso sia il fatto che il randomForestClassifier abbia qualche casualità nell'algoritmo per scegliere le caratteristiche nei suoi alberi.A parte questo, se si limitano a ridurre i dati in n fold in base all'ordine iniziale, allora forse questo è il problema. Lo controllerò tra qualche ora, quando mi sveglio tutto, è il cuore della notte qui! – evianpring

+0

così, sì, questo lavorato: p = np.random.permutation (len (y)) Risultato = cross_val_score (ensemble.RandomForestClassifier (n_estimators = 1000, max_depth = 5, max_features = 3, oob_score = False), X [p], y [p], scoring = 'roc_auc', cv = 2) – evianpring

risposta

12

Quando si utilizza cross_val_score, sarete spesso desidera utilizzare un KFolds o StratifiedKFolds iteratore:

http://scikit-learn.org/0.10/modules/cross_validation.html#computing-cross-validated-metrics

http://scikit-learn.org/0.10/modules/generated/sklearn.cross_validation.KFold.html#sklearn.cross_validation.KFold

Per impostazione predefinita, cross_val_score non casuale dei dati, che può produrre risultati dispari così se i dati non sono casuali per cominciare.

L'iteratore KFolds ha un parametro di stato casuale:

http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.KFold.html

Così fa train_test_split, che non randomizzare per impostazione predefinita:

http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.train_test_split.html

modelli come quello che hai descritto sono di solito un risultato di una mancanza di casualità nel treno/set di test.

+0

Ho una domanda su ** train_test_split **. Nel codice sopra 'xtrain, xtest, ytrain, ytest = train_test_split (X, y, test_size = 0.50)', come fa l'algoritmo a sapere quale valore deve essere inserito in 'xtrain',' xtest' ecc.? Come fa a sapere che 'xtrain' deve contenere il risultato di _training le variabili indipendenti_ del set di dati, e in modo simile su' xtest'. Non credo che sia il fatto che la variabile contenga "treno" o "test" al suo interno. È? Grazie per l'aiuto. –