sklearn.ensemble.AdaBoostClassifier不能将SVM作为base_estimator加入?

时间:2014-11-24 14:33:04

标签: python machine-learning scikit-learn ensemble-learning

我正在做一个文本分类任务。现在,我想将ensemble.AdaBoostClassifierLinearSVC一起用作base_estimator。但是,当我尝试运行代码时

clf = AdaBoostClassifier(svm.LinearSVC(),n_estimators=50, learning_rate=1.0,    algorithm='SAMME.R')
clf.fit(X, y)

发生错误。 TypeError: AdaBoostClassifier with algorithm='SAMME.R' requires that the weak learner supports the calculation of class probabilities with a predict_proba method

第一个问题是 svm.LinearSVC()无法计算班级概率吗?如何计算概率?

然后我更改参数algorithm并再次运行代码。

clf = AdaBoostClassifier(svm.LinearSVC(),n_estimators=50, learning_rate=1.0, algorithm='SAMME')
clf.fit(X, y)

这次TypeError: fit() got an unexpected keyword argument 'sample_weight'发生了。正如在AdaBoostClassifier中所说,Sample weights. If None, the sample weights are initialized to 1 / n_samples.即使我将一个整数分配给n_samples,也会发生错误。

第二个问题是 n_samples是什么意思?如何解决这个问题呢?

希望有人能帮助我。

根据@jme的评论,尝试后

clf = AdaBoostClassifier(svm.SVC(kernel='linear',probability=True),n_estimators=10,  learning_rate=1.0, algorithm='SAMME.R')
clf.fit(X, y)

程序无法获得结果,服务器上使用的内存保持不变。

第三个问题我如何才能AdaBoostClassifier使用SVC作为base_estimator?

4 个答案:

答案 0 :(得分:12)

正确的答案将取决于您正在寻找的确切内容。 LinearSVC无法预测类概率(AdaBoostClassifier使用的默认算法所需)并且不支持sample_weight。

您应该知道支持向量机不会在名义上预测类概率。它们是使用Platt缩放(或多类情况下Platt缩放的扩展)计算的,这是一种已知问题的技术。如果你需要更少的人工"类概率,SVM可能不是最佳选择。

话虽如此,我相信给出你的问题最令人满意的答案是格雷厄姆给出的。也就是说,

from sklearn.svm import SVC
from sklearn.ensemble import AdaBoostClassifier

clf = AdaBoostClassifier(SVC(probability=True, kernel='linear'), ...)

您还有其他选择。您可以将SGDClassifier与铰链损失函数一起使用,并将AdaBoostClassifier设置为使用SAMME算法(不需要predict_proba函数,但需要支持sample_weight):

from sklearn.linear_model import SGDClassifier

clf = AdaBoostClassifier(SGDClassifier(loss='hinge'), algorithm='SAMME', ...)

如果您想使用为AdaBoostClassifier提供的默认算法,也许最好的答案是使用对类概率具有原生支持的分类器,如Logistic回归。您可以使用scikit.linear_model.LogisticRegression或使用具有日志丢失功能的SGDClassifier来执行此操作,如Kris提供的代码中所使用。

希望如果你对Platt缩放是什么感到好奇,check out the original paper by John Platt here

答案 1 :(得分:1)

您需要使用具有predict_proba方法的学习器,因为这在LinearSVC中不可用,请尝试将内核设置为“线性”的SVC

clf = AdaBoostClassifier(svm.SVC(probability=True,kernel='linear'),n_estimators=50,       learning_rate=1.0, algorithm='SAMME')
clf.fit(X, y)

虽然我不确定这是否会产生与LinearSVC相同的结果,但是从文档中可以看出:

与参数kernel ='linear'的SVC类似,但是以liblinear而不是libsvm的形式实现,因此它在惩罚和损失函数的选择上具有更大的灵活性,并且应该更好地扩展(对于大量样本)。

还提到了关于One vs All和One vs One的不同之处。

答案 2 :(得分:1)

实际上,LinearSVC可以应用于AdaBoostClassifier而无需通过Platt缩放重新调整SVC输出,而AdaBoost.M1算法最初设计用于,分类器以{-1,1}作为输出。 AdaBoostClassifier中的默认算法选择是AdaBoost.SAMME算法[2](指定" SAMME.R"在算法关键字参数中),它是为多类分类而设计的。

但是,您的LinearSVC AdaBoost将无法提供predict_proba。另一方面,如果你想要的是保持输出中的符号而不是将SVM输出拟合成sigmoid曲线以提供概率。然后将算法从SAMME.R更改为SAMME是最简单的方法。

[1] Y. Freund, R. Schapire, “A Decision-Theoretic Generalization of on-Line Learning and an Application to Boosting”, 1995.
[2] Zhu, H. Zou, S. Rosset, T. Hastie, “Multi-class AdaBoost”, 2009

答案 3 :(得分:0)

我在尝试将AdaBoostClassifierLogisticRegression一起使用时遇到了类似的问题。文档提到弱分类器(或base_estimator)必须具有fit方法,该方法采用可选的sample_weight=...关键字参数,参见问题#18306416

如果您确实想要使用AdaBoost进行SVM或逻辑回归,可以使用sklearn的随机梯度下降分类器loss='hinge'(svm)或loss='log'(逻辑),例如

from sklearn.linear_model import SGDClassifier
from sklearn.ensemble import AdaBoostClassifier

clf = AdaBoostClassifier(SGDClassifier(loss='log'), ...)

YMMV