VotingClassifier с конвейерами в качестве оценщиков - PullRequest
2 голосов
/ 24 января 2020

Я хочу построить ансамбль sklearn VotingClassifier из нескольких разных моделей (Дерево решений, SV C и Сеть Keras). Все они нуждаются в различной обработке данных, поэтому я создал конвейер для каждого из них.

# Define pipelines

# DTC pipeline
featuriser = Featuriser()
dtc = DecisionTreeClassifier()
dtc_pipe = Pipeline([('featuriser',featuriser),('dtc',dtc)])

# SVC pipeline
scaler = TimeSeriesScalerMeanVariance(kind='constant')
flattener = Flattener()
svc = SVC(C = 100, gamma = 0.001, kernel='rbf')
svc_pipe = Pipeline([('scaler', scaler),('flattener', flattener), ('svc', svc)])

# Keras pipeline
cnn = KerasClassifier(build_fn=get_model())
cnn_pipe = Pipeline([('scaler',scaler),('cnn',cnn)])

# Make an ensemble
ensemble = VotingClassifier(estimators=[('dtc', dtc_pipe), 
                                        ('svc', svc_pipe),
                                        ('cnn', cnn_pipe)], 
                            voting='hard')

Классы Featuriser, TimeSeriesScalerMeanVariance и Flattener представляют собой некоторые изготовленные на заказ трансформаторы, которые все используют методы fit, transform и fit_transform.

Когда Я пытаюсь ensemble.fit(X, y) соответствовать всему ансамблю. Я получаю сообщение об ошибке:

ValueError: Список оценки должен быть классификатором.

Что я могу понять, как Отдельные оценки - это не классификаторы, а конвейеры. Есть ли способ заставить его работать?

1 Ответ

1 голос
/ 26 января 2020

Проблема с KerasClassifier. Он не предоставляет _estimator_type, который был проверен в _validate_estimator.

. Это не проблема использования конвейера. Pipeline предоставляет эту информацию как свойство. См. здесь .

Следовательно, быстрое исправление устанавливает _estimator_type='classifier'.

Воспроизводимый пример:

# Define pipelines
from sklearn.pipeline import Pipeline
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import MinMaxScaler, Normalizer
from sklearn.ensemble import VotingClassifier
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.datasets import make_classification
from keras.layers import Dense
from keras.models import Sequential

X, y = make_classification()

# DTC pipeline
featuriser = MinMaxScaler()
dtc = DecisionTreeClassifier()
dtc_pipe = Pipeline([('featuriser', featuriser), ('dtc', dtc)])

# SVC pipeline
scaler = Normalizer()
svc = SVC(C=100, gamma=0.001, kernel='rbf')
svc_pipe = Pipeline(
    [('scaler', scaler), ('svc', svc)])

# Keras pipeline
def get_model():
    # create model
    model = Sequential()
    model.add(Dense(10, input_dim=20, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model


cnn = KerasClassifier(build_fn=get_model)
cnn._estimator_type = "classifier"
cnn_pipe = Pipeline([('scaler', scaler), ('cnn', cnn)])


# Make an ensemble
ensemble = VotingClassifier(estimators=[('dtc', dtc_pipe), 
                                        ('svc', svc_pipe),
                                        ('cnn', cnn_pipe)], 
                            voting='hard')

ensemble.fit(X, y)

...