7

Próbowałem użyć GradientBoostingClassifier w scikit-learn i działa dobrze z domyślnymi parametrami. Jednak, kiedy próbował wymienić BaseEstimator z innego klasyfikatora, to nie działa i dał mi następujący błąd,GradientBoostingClassifier z BaseEstimator w nauce scikit?

return y - np.nan_to_num(np.exp(pred[:, k] - 
IndexError: too many indices 

Czy masz jakieś rozwiązanie tego problemu.

Ten błąd można regenerować stosując następujące fragmenty:

import numpy as np 
from sklearn import datasets 
from sklearn.ensemble import GradientBoostingClassifier 
from sklearn.linear_model import LogisticRegression 
from sklearn.utils import shuffle 

mnist = datasets.fetch_mldata('MNIST original') 
X, y = shuffle(mnist.data, mnist.target, random_state=13) 
X = X.astype(np.float32) 
offset = int(X.shape[0] * 0.01) 
X_train, y_train = X[:offset], y[:offset] 
X_test, y_test = X[offset:], y[offset:] 

### works fine when init is None 
clf_init = None 
print 'Train with clf_init = None' 
clf = GradientBoostingClassifier((loss='deviance', learning_rate=0.1, 
          n_estimators=5, subsample=0.3, 
          min_samples_split=2, 
          min_samples_leaf=1, 
          max_depth=3, 
          init=clf_init, 
          random_state=None, 
          max_features=None, 
          verbose=2, 
          learn_rate=None) 
clf.fit(X_train, y_train) 
print 'Train with clf_init = None is done :-)' 

print 'Train LogisticRegression()' 
clf_init = LogisticRegression(); 
clf_init.fit(X_train, y_train); 
print 'Train LogisticRegression() is done' 

print 'Train with clf_init = LogisticRegression()' 
clf = GradientBoostingClassifier(loss='deviance', learning_rate=0.1, 
          n_estimators=5, subsample=0.3, 
          min_samples_split=2, 
          min_samples_leaf=1, 
          max_depth=3, 
          init=clf_init, 
          random_state=None, 
          max_features=None, 
          verbose=2, 
          learn_rate=None) 
clf.fit(X_train, y_train) # <------ ERROR!!!! 
print 'Train with clf_init = LogisticRegression() is done' 

Oto HTE kompletny traceback błędu:

Traceback (most recent call last): 
File "/home/mohsena/Dropbox/programing/gbm/gb_with_init.py", line 56, in <module> 
    clf.fit(X_train, y_train) 
File "/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/gradient_boosting.py", line 862, in fit 
    return super(GradientBoostingClassifier, self).fit(X, y) 
File "/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/gradient_boosting.py", line 614, in fit random_state) 
File "/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/gradient_boosting.py", line 475, in _fit_stage 
    residual = loss.negative_gradient(y, y_pred, k=k) 
File "/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/gradient_boosting.py", line 404, in negative_gradient 
    return y - np.nan_to_num(np.exp(pred[:, k] - 
    IndexError: too many indices 

Odpowiedz

4

Jak sugeruje scikit-learn deweloperów, problem może być rozwiązany za pomocą adaptera tak:

def __init__(self, est): 
    self.est = est 
def predict(self, X): 
    return self.est.predict_proba(X)[:, 1] 
def fit(self, X, y): 
    self.est.fit(X, y) 
+0

Witam, mam do czynienia z bardzo podobnym błędem z GBC i LR: y_pred [:, k] + = value_ uczenie * tree.predict (X) .ravel() IndexError: zbyt wiele indeksów - próbował użyć twój pomysł adaptera, ale do Bez skutku, błąd pozostaje. Czy masz jakieś pomysły, jak rozwiązać ten problem? – abalogh

3

Gradient Boosting generalnie wymaga uczącego bazową być algorytm, który wykonuje przewidywanie numeryczne, a nie klasyfikacja. Zakładam, że to twój problem.

+0

Dzięki za komentarz. Jeśli spojrzysz na sklearn/ensemble/gradient_boosting.py, zobaczysz, że ma on wsparcie dla problemów klasyfikacyjnych (poszukaj remedium = loss.negative_gradient (y, y_pred, k = k)) – iampat

+0

Gradientowy wzrost jest z natury regresją algorytm. Można go dostosować do klasyfikacji z odpowiednią funkcją straty. Nie mam czasu na przeczytanie całego ich kodu, ale to nie znaczy, że nie używa on regresora do wykonania klasyfikacji. Funkcja utraty najmniejszych kwadratów używa tej samej metody. Najpierw spróbowałbym innego nieliniowego regresora, żeby sprawdzić, czy problem polega na tym, że powinieneś używać algorytmu regresji. Nigdy nie widziałem, aby ktokolwiek używał Gradientowego Wzmocnienia za pomocą algorytmu bez regresji. –

8

Ulepszona wersja „odpowiedzi S i nieznacznej modyfikacji scikit-developersiampat odpowiedzi s powinien wykonać sztuczka.

class init: 
    def __init__(self, est): 
     self.est = est 
    def predict(self, X): 
     return self.est.predict_proba(X)[:,1][:,numpy.newaxis] 
    def fit(self, X, y): 
     self.est.fit(X, y) 
4

Oto pełna i, moim zdaniem, prostsza wersja fragmentu kodu iampata.

class RandomForestClassifier_compability(RandomForestClassifier): 
     def predict(self, X): 
      return self.predict_proba(X)[:, 1][:,numpy.newaxis] 
    base_estimator = RandomForestClassifier_compability() 
    classifier = GradientBoostingClassifier(init=base_estimator)