Мой StackingCVClassifier имеет более низкую точность, чем базовые классификаторы, но очень хорошо работает на тестовом наборе - PullRequest
0 голосов
/ 10 января 2019

Я создал простой стековый классификатор с mlxtend и пробую разные базовые классификаторы, и я столкнулся с интересной ситуацией. Из всех моих исследований мне кажется, что классификаторы стеков всегда работают лучше, чем их базовые классификаторы.

В моем случае, когда я перекрестно проверяю классификатор стеков на тренировочном наборе, я получаю более низкий балл, чем некоторые из базовых оценок. Кроме того, я часто получаю средний балл CV моего классификатора суммирования, равный наименьшему из среднего балла CV базовых оценщиков.

Разве это не странно? Что еще более странно, когда я выполняю GridSearchCV на своем классификаторе стеков, выбираю лучшие параметры и переобучаюсь для всего набора поездов, и, наконец, вычисляю точность на тестовом наборе, я на самом деле получаю довольно хороший результат.

Я знаю, что этот метод подвержен утечкам, и существуют различные методы для CV классификатора стеков, но они кажутся чрезвычайно медленными, и из моего исследования приведенный выше подход кажется подходящим (об этой потенциальной утечке, это руководство по стекированию Kaggle). В посте даже говорится: «На практике все игнорируют эту теоретическую дыру (и, честно говоря, я думаю, что большинство людей даже не подозревают, что она существует!» http://blog.kaggle.com/2016/12/27/a-kagglers-guide-to-model-stacking-in-practice/ См. параграф настройки параметров)

from mlxtend.classifier import StackingCVClassifier
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import BernoulliNB
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.metrics import accuracy_score

RANDOM_SEED = 12

#Imported df in separate code snippet
y = df['y']
X = df.drop(columns=['y'])

scaler = preprocessing.StandardScaler().fit(X)
X_transformed = scaler.transform(X)


X_train, X_test, y_train, y_test = train_test_split(X_transformed,y, random_state = 4)

def gridSearch_clf(clf, param_grid, X_train, y_train):
    gs = GridSearchCV(clf, param_grid).fit(X_train, y_train)
    print("Best Parameters")
    print(gs.best_params_)
    return gs.best_estimator_

def gs_report(y_test, X_test, best_estimator):
    print(classification_report(y_test, best_estimator.predict(X_test)))
    print("Overall Accuracy Score: ")
    print(accuracy_score(y_test, best_estimator.predict(X_test)))

lr = LogisticRegression()

np.random.seed(RANDOM_SEED)
sclf = StackingCVClassifier(classifiers=[best_clf1, best_clf2, best_clf3], 
                            meta_classifier=lr)

clfs = [best_clf1, best_clf2, best_clf3, sclf]
clf_names = [i.__class__.__name__ for i in clfs]

print_cv(clfs, clf_names)

Accuracy: 0.68 (+/- 0.30) [Decision Tree Classifier]
Accuracy: 0.55 (+/- 0.26) [K Neighbors Classifier]
Accuracy: 0.67 (+/- 0.32) [Bernoulli Naive Bayes]
Accuracy: 0.55 (+/- 0.26) [StackingClassifier]

## StackingClassifier Accuracy = KNN Classifier Accuracy

param_grid = {'meta-logisticregression__C':np.logspace(-2, 3, num=6, base=10)}

best_sclf = gridSearch_clf(sclf, param_grid, X_train, y_train)
gs_report(y_test,X_test, best_sclf)

Best Parameters
{'meta-logisticregression__C': 0.1}
             precision    recall  f1-score   support

          0       0.91      0.99      0.95      9131
          1       0.68      0.22      0.33      1166

avg / total       0.88      0.90      0.88     10297

Overall Accuracy Score: 
0.9000679809653297
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...