我正在做一个文本分类任务。现在,我想将ensemble.AdaBoostClassifier
与LinearSVC
一起用作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?
答案 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)
我在尝试将AdaBoostClassifier
与LogisticRegression
一起使用时遇到了类似的问题。文档提到弱分类器(或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