2015-11-27 13 views
5

Używam naukowego scikit z uwarstwionym CV, aby porównać niektóre klasyfikatory. Obliczam: dokładność, przypomnienie, auc.Losowy las jest overfitting

Użyłem do optymalizacji parametrów GridSearchCV z 5 CV.

RandomForestClassifier(warm_start= True, min_samples_leaf= 1, n_estimators= 800, min_samples_split= 5,max_features= 'log2', max_depth= 400, class_weight=None) 

to najlepsze_paramy z GridSearchCV.

Mój problem, myślę, że naprawdę nadwyrężam. Na przykład:

Losowy las z odchyleniem standardowym (+/-)

  • precyzja: 0,99 (+/- 0,06)
  • czułość: 0,94 (+/- 0,06)
  • specyficzności : 0,94 (+/- 0,06)
  • B_accuracy: 0,94 (+/- 0,06)
  • AUC: 0,94 (+/- 0,11)

regresja logistyczna z odchyleniem standardowym (+/-)

  • Dokładność: 0,88 (+/- 0,06)
  • czułość: 0,79 (+/- 0,06)
  • specyficzność: 0,68 (+/- 0,06)
  • B_accuracy: 0,73 (+/- 0,06)
  • AUC: 0,73 (+/- 0,041)

A pozostałe również wyglądają jak regresja logistyczna (więc nie wyglądają na przestarzałe).

Moje CV jest kod:

for i,j in enumerate(data): 
    X.append(data[i][0]) 
    y.append(float(data[i][1])) 
x=np.array(X) 
y=np.array(y) 

def SD(values): 

    mean=sum(values)/len(values) 
    a=[] 
    for i in range(len(values)): 
     a.append((values[i]-mean)**2) 
    erg=sum(a)/len(values) 
    SD=math.sqrt(erg) 
    return SD,mean 

    for name, clf in zip(titles,classifiers): 
    # go through all classifiers, compute 10 folds 
    # the next for loop should be 1 tab indent more, coudlnt realy format it here, sorry 
    pre,sen,spe,ba,area=[],[],[],[],[] 
    for train_index, test_index in skf: 
     #print train_index, test_index 
     #get the index from all train_index and test_index 
     #change them to list due to some errors 
     train=train_index.tolist() 
     test=test_index.tolist() 
     X_train=[] 
     X_test=[] 
     y_train=[] 
     y_test=[] 
     for i in train: 
      X_train.append(x[i]) 

     for i in test: 
      X_test.append(x[i]) 

     for i in train: 
      y_train.append(y[i]) 

     for i in test: 
      y_test.append(y[i]) 


     #clf=clf.fit(X_train,y_train) 
     #predicted=clf.predict_proba(X_test) 
     #... other code, calculating metrics and so on... 
    print name 
    print("precision: %0.2f \t(+/- %0.2f)" % (SD(pre)[1], SD(pre)[0])) 
    print("sensitivity: %0.2f \t(+/- %0.2f)" % (SD(sen)[1], SD(pre)[0])) 
    print("specificity: %0.2f \t(+/- %0.2f)" % (SD(spe)[1], SD(pre)[0])) 
    print("B_accuracy: %0.2f \t(+/- %0.2f)" % (SD(ba)[1], SD(pre)[0])) 
    print("AUC: %0.2f \t(+/- %0.2f)" % (SD(area)[1], SD(area)[0])) 
    print "\n" 

Jeśli używam metody scores = cross_validation.cross_val_score(clf, X, y, cv=10, scoring='accuracy'), ja nie rozumiem tego „przeuczenia” wartości. Więc może jest coś nie tak z metodą CV, której używam? Ale to tylko dla RF ...

Zrobiłem własne z powodu opóźnienia funkcji oceny specyficzności w funkcji cross_val_function.

+0

I pytanie jest ...? –

+2

Czynisz * nie * krzyżujesz walidację losowego lasu. Przeciwnie, las jest sprawdzany krzyżowo podczas budowy. –

+0

Ale jak mam porównać modele? Wiem, że jest sprawdzany krzyżowo, ale jakoś powinienem go porównać z innymi metodami, takimi jak SVM, regresja logistyczna itd. Moim zadaniem jest również: dlaczego nadrabiam? jest częścią z "dla train_index, test_index w skf:" cała pętla może być źle? bo jak wspomniałem, funkcja scorer_val daje "normalne" wartości. – auronsen

Odpowiedz

11

Herbert,

jeśli celem jest porównanie różnych algorytmów uczenia, polecam używać zagnieżdżonych krzyżowej walidacji. (Odnoszę się do algorytmu uczenia się jako różnych algorytmów, takich jak regresja logiczna, drzewa decyzyjne i inne modele dyskryminacyjne, które poznają hipotezę lub model - ostateczny klasyfikator - z danych treningowych).

"Regularna" weryfikacja krzyżowa jest dobra, jeśli chcesz dostroić hiperparametry pojedynczego algorytmu. Jednak, gdy tylko rozpoczniesz optymalizację hiperparametru z tymi samymi parametrami/fałdami walidacji krzyżowej, twoje oszacowanie wydajności będzie prawdopodobnie zbyt optymistyczne. Powód, dla którego wielokrotnie sprawdzasz poprawność krzyżową, twoje dane testowe w pewnym stopniu staną się "danymi treningowymi".

Ludzie zadał mi to pytanie dość często, rzeczywiście, i wezmę kilka fragmentów z sekcji FAQ napisałem tutaj: http://sebastianraschka.com/faq/docs/evaluate-a-model.html

W zagnieżdżonego krzyżowej walidacji mamy zewnętrzną k-fold cross pętla walidacji, aby podzielić dane na trening i fałdy testowe, a wewnętrzna pętla jest używana do wyboru modelu poprzez k-krotne sprawdzanie krzyżowe na fałdzie treningowym. Po wybraniu modelu fałd testowy jest wykorzystywany do oceny wydajności modelu. Po zidentyfikowaniu naszego "ulubionego" algorytmu możemy śledzić "zwykłe" podejście k-krotnego sprawdzania krzyżowego (na kompletnym zestawie treningowym), aby znaleźć jego "optymalne" hiperparametry i ocenić je na niezależnym zestawie testowym. Rozważmy model regresji logistycznej, aby było to bardziej zrozumiałe: za pomocą zagnieżdżonej walidacji krzyżowej będziesz szkolił m różne modele regresji logistycznej, 1 dla każdej z m zewnętrznych fałd, a wewnętrzne fałdy są używane do optymalizacji hiperparametrów każdego modelu (np. przy użyciu funkcji gridsearch w połączeniu z k-krotnym sprawdzeniem poprawności krzyżowej.Jeśli model jest stabilny, wszystkie te modele m powinny mieć te same wartości hyperparametryczne, a Ty raportujesz średnią wydajność tego modelu w oparciu o zewnętrzne fałdy testowe. następny algorytm, np SVM itp

enter image description here

mogę tylko gorąco polecam ten doskonały papier, który omawia tę kwestię bardziej szczegółowo:

PS: Zazwyczaj nie musisz/chcesz dostroić hiperparametrów losowej Forest (tak intensywnie). Ideą Random Forests (formą workowania) jest w rzeczywistości nie przycinanie drzew decyzyjnych - faktycznie, jednym z powodów, dla których Breiman wymyślił algorytm Losowego Lasu, było poradzenie sobie z problemem przycinania/przebudowy indywidualnych drzew decyzyjnych. Tak więc jedynym parametrem, na który naprawdę trzeba się "martwić", jest liczba drzew (a może liczba losowych funkcji na drzewo). Jednak zazwyczaj najlepiej jest pobrać próbki bootstrapów o rozmiarze n (gdzie n jest oryginalną liczbą funkcji w zestawie treningowym) i elementach squareroot (m) (gdzie m jest wymiarowością Twojego zestawu treningowego).

Mam nadzieję, że było to pomocne!

Edit:

Niektóre przykładowy kod do wykonywania zagnieżdżony CV poprzez scikit-learn:

pipe_svc = Pipeline([('scl', StandardScaler()), 
        ('clf', SVC(random_state=1))]) 

param_range = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0] 

param_grid = [{'clf__C': param_range, 
       'clf__kernel': ['linear']}, 
      {'clf__C': param_range, 
       'clf__gamma': param_range, 
       'clf__kernel': ['rbf']}] 


# Nested Cross-validation (here: 5 x 2 cross validation) 
# ===================================== 
gs = GridSearchCV(estimator=pipe_svc, 
          param_grid=param_grid, 
          scoring='accuracy', 
          cv=5) 
scores = cross_val_score(gs, X_train, y_train, scoring='accuracy', cv=2) 
print('CV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores))) 
+0

grid = GridSearchCV (algo, paramsE, cv = 5, scoring = 'accuracy'). fit (x_data, y_data), a następnie: scores = cross_validation.cross_val_score (grid, x_data, y_data), czy CV jest zagnieżdżone, czy nie? z tego mogę uzyskać grid.best_score_ i najlepsze parametry/estymator? – auronsen

+0

@auronsen Niezupełnie. To nie byłoby "zagnieżdżone CV", ponieważ pasowałbyś do estymatora przeszukiwania siatki na zbiorze treningowym, a nie do pod-treningu zewnętrznej pętli. Dodałem przykład na dole poprzedniej odpowiedzi; mam nadzieję, że pomaga! – Sebastian