14

有人可以告诉如何使用部分拟合在 sklearn 中使用合奏。我不想重新训练我的模型。或者,我们可以通过预先训练的模型进行集成吗?例如,我已经看到投票分类器不支持使用部分拟合进行训练。

4

5 回答 5

15

Mlxtend 库有一个 VotingEnsemble 的实现,它允许您传入预先拟合的模型。例如,如果您有三个预训练模型 clf1、clf2、clf3。以下代码将起作用。

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

 

当设置为 false 时,EnsembleVoteClassifier 中的fit_base_estimators参数可确保分类器不会重新拟合。

一般来说,当寻找 sci-kit learn 不提供的更高级的技术特性时,请首先参考 mlxtend。

于 2017-11-26T09:22:10.553 回答
9

解决方法:

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)
于 2019-02-09T20:43:59.557 回答
8

不幸的是,目前这在 scikit 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))
于 2017-03-21T11:05:59.310 回答
4

实施投票并不难。这是我的实现:

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
于 2018-05-11T15:09:48.520 回答
2

Mlxtend 库有一个实现工程,您仍然需要调用fitEnsembleVoteClassifier 的函数。似乎该fit函数并没有真正修改任何参数,而是检查可能的标签值。在下面的示例中,您必须给出一个数组,其中包含原始 y 中出现的所有可能值(在本例中为 1,2)到eclf2.fitX 无关紧要。

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))
于 2018-07-12T16:16:45.117 回答