我使用 scikit learn (LinearSVC) 中的线性 SVM 来解决二元分类问题。我知道 LinearSVC 可以给我预测的标签和决策分数,但我想要概率估计(对标签的信心)。由于速度的原因,我想继续使用 LinearSVC(与具有线性内核的 sklearn.svm.SVC 相比)使用逻辑函数将决策分数转换为概率是否合理?
import sklearn.svm as suppmach
# Fit model:
svmmodel=suppmach.LinearSVC(penalty='l1',C=1)
predicted_test= svmmodel.predict(x_test)
predicted_test_scores= svmmodel.decision_function(x_test)
我想检查简单地获得概率估计是否有意义 [1 / (1 + exp(-x)) ] 其中 x 是决策分数。
或者,我可以使用其他选项 wrt 分类器来有效地执行此操作吗?
谢谢。
scikit-learn 提供 CalibratedClassifierCV 可用于解决此问题:它允许将概率输出添加到 LinearSVC 或任何其他实现 decision_function 方法的分类器:
svm = LinearSVC()
clf = CalibratedClassifierCV(svm)
clf.fit(X_train, y_train)
y_proba = clf.predict_proba(X_test)
用户指南有一个很好的部分。默认情况下,CalibratedClassifierCV+LinearSVC 将为您提供 Platt 缩放,但它还提供其他选项(等渗回归方法),并且不限于 SVM 分类器。
我查看了 sklearn.svm.* 系列中的 API。以下所有型号,例如,
有一个通用的接口提供一个
probability: boolean, optional (default=False)
模型的参数。如果此参数设置为 True,libsvm 将根据 Platt Scaling 的思想在 SVM 的输出之上训练概率转换模型。正如您所指出的,转换的形式类似于逻辑函数,但是在后处理步骤中学习了两个特定常数
A
和B
。另请参阅此stackoverflow 帖子以获取更多详细信息。
其实我也不知道为什么LinearSVC没有这个后处理。否则,您只需调用
predict_proba(X)
即可获得概率估计。
当然,如果您只是应用朴素的逻辑变换,它的性能将不如 Platt Scaling 这样的校准方法。如果你能理解 platt 缩放的下划线算法,你可能可以自己编写或贡献给 scikit-learn svm 系列。 :) 也可以随意使用以上四种支持
predict_proba
.的SVM变体
如果你想要速度,那么只需用sklearn.linear_model.LogisticRegression
替换SVM。它使用与
LinearSVC
完全相同的训练算法,但使用对数损失而不是铰链损失。
使用 [1 / (1 + exp(-x))] 会产生正式意义上的概率(0 和 1 之间的数字),但它们不会遵循任何合理的概率模型。
作为使用 SVM 进行二元分类的扩展:您还可以查看 SGDClassifier,它默认使用 SVM 执行梯度下降。为了估计二元概率,它使用修改后的 huber loss
(clip(decision_function(X), -1, 1) + 1) / 2)
一个例子看起来像:
from sklearn.linear_model import SGDClassifier
svm = SGDClassifier(loss="modified_huber")
svm.fit(X_train, y_train)
proba = svm.predict_proba(X_test)