Использование 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))