Использование sklearn ансамбля голосования с частичной подгонкой

Может кто-нибудь подскажите, пожалуйста, как использовать ансамбли в склеарне с использованием частичной подгонки. Я не хочу переучивать свою модель. В качестве альтернативы, мы можем передать предварительно обученные модели для ансамбля? Я видел, что классификатор голосования, например, не поддерживает обучение с использованием частичного подбора.

4 ответа

В библиотеке Mlxtend есть реализация VotingEnsemble, которая позволяет передавать предварительно установленные модели. Например, если у вас есть три предварительно обученные модели clf1, clf2, clf3. Следующий код будет работать.

from mlxtend.classifier import EnsembleVoteClassifier
import copy
eclf = EnsembleVoteClassifier(clfs=[clf1, clf2, clf3], weights=[1,1,1], refit=False)

Если установлено значение false, аргумент refit в EnsembleVoteClassifier гарантирует, что классификаторы не будут refit.

В общем, если вы ищете более продвинутые технические функции, которые не предоставляет Sci-Kit, обратите внимание на mlxtend в качестве первого ориентира.

Временное решение:

VotingClassifier проверяет, что estimators_ установлен, чтобы понять, подходит ли он, и использует оценки в списке estimators_ для прогнозирования. Если у вас есть предварительно обученные классификаторы, вы можете поместить их в estimators_, как показано ниже.

Тем не менее, он также использует LabelEnconder, поэтому он предполагает, что метки похожи на 0,1,2,... и вам также нужно установить le_ и classes_ (см. Ниже).

from sklearn.ensemble import VotingClassifier
from sklearn.preprocessing import LabelEncoder

clf_list = [clf1, clf2, clf3]

eclf = VotingClassifier(estimators = [('1' ,clf1), ('2', clf2), ('3', clf3)], voting='soft')

eclf.estimators_ = clf_list
eclf.le_ = LabelEncoder().fit(y)
eclf.classes_ = seclf.le_.classes_

# Now it will work without calling fit
eclf.predict(X,y)

К сожалению, в настоящее время это невозможно в scikiit VotingClassifier.

Но вы можете использовать http://sebastianraschka.com/Articles/2014_ensemble_classifier.html (из которого реализован VotingClassifer), чтобы попытаться реализовать собственный классификатор голосования, который может использовать предварительно подогнанные модели.

Также мы можем посмотреть исходный код здесь и изменить его для нашего использования:

from sklearn.preprocessing import LabelEncoder
import numpy as np

le_ = LabelEncoder()

# When you do partial_fit, the first fit of any classifier requires 
all available labels (output classes), 
you should supply all same labels here in y.
le_.fit(y)

# Fill below list with fitted or partial fitted estimators
clf_list = [clf1, clf2, clf3, ... ]

# Fill weights -> array-like, shape = [n_classifiers] or None
weights = [clf1_wgt, clf2_wgt, ... ]
weights = None

#For hard voting:
pred = np.asarray([clf.predict(X) for clf in clf_list]).T
pred = np.apply_along_axis(lambda x:
                           np.argmax(np.bincount(x, weights=weights)),
                           axis=1,
                           arr=pred.astype('int'))

#For soft voting:
pred = np.asarray([clf.predict_proba(X) for clf in clf_list])
pred = np.average(pred, axis=0, weights=weights)
pred = np.argmax(pred, axis=1)

#Finally, reverse transform the labels for correct output:
pred = le_.inverse_transform(np.argmax(pred, axis=1))

Осуществить голосование не сложно. Вот моя реализация:

import numpy as np 

class VotingClassifier(object):
    """ Implements a voting classifier for pre-trained classifiers"""

    def __init__(self, estimators):
        self.estimators = estimators

    def predict(self, X):
        # get values
        Y = np.zeros([X.shape[0], len(self.estimators)], dtype=int)
        for i, clf in enumerate(self.estimators):
            Y[:, i] = clf.predict(X)
        # apply voting 
        y = np.zeros(X.shape[0])
        for i in range(X.shape[0]):
            y[i] = np.argmax(np.bincount(Y[i,:]))
        return y

Библиотека Mlxtend имеет реализацию, вам все еще нужно вызвать fit функция для EnsembleVoteClassifier. Кажется fit Функция на самом деле не изменяет никаких параметров, а проверяет возможные значения меток. В приведенном ниже примере вы должны указать массив, содержащий все возможные значения, отображаемые в исходном y(в данном случае 1,2) для eclf2.fit Это не имеет значения для X.

import numpy as np
from mlxtend.classifier import EnsembleVoteClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
import copy
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
y = np.array([1, 1, 1, 2, 2, 2])

for clf in (clf1, clf2, clf3):
    clf.fit(X, y)    
eclf2 = EnsembleVoteClassifier(clfs=[clf1, clf2, clf3],voting="soft",refit=False)
eclf2.fit(None,np.array([1,2]))
print(eclf2.predict(X))
Другие вопросы по тегам