16

我正在做一个文本分类任务。现在我想ensemble.AdaBoostClassifierLinearSVCas 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使用SVCbase_estimator?

4

4 回答 4

14

正确的答案将取决于您正在寻找什么。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 缩放是什么感到好奇,请在此处查看 John Platt 的原始论文

于 2016-01-11T00:02:06.787 回答
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 的区别。

于 2015-03-21T07:11:22.973 回答
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,“在线学习的决策理论概括和提升的应用”,1995 年。
[2] Zhu,H. Zou,S. Rosset,T. Hastie,“Multi级 AdaBoost”,2009 年

于 2017-06-30T10:42:05.010 回答
0

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

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

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

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

YMMV

于 2015-04-15T11:22:11.980 回答