LinearSVC sklearn (scikit-learn) 中 C 的行为

Posted

技术标签:

【中文标题】LinearSVC sklearn (scikit-learn) 中 C 的行为【英文标题】:Behavior of C in LinearSVC sklearn (scikit-learn) 【发布时间】:2020-09-25 16:45:46 【问题描述】:

首先我创建一些玩具数据:

n_samples=20
X=np.concatenate((np.random.normal(loc=2, scale=1.0, size=n_samples),np.random.normal(loc=20.0, scale=1.0, size=n_samples),[10])).reshape(-1,1)
y=np.concatenate((np.repeat(0,n_samples),np.repeat(1,n_samples+1)))
plt.scatter(X,y)

在图表下方可视化数据:

然后我用LinearSVC训练一个模型

from sklearn.svm import LinearSVC
svm_lin = LinearSVC(C=1)
svm_lin.fit(X,y)

我对@9​​87654334@ 的理解是:

如果C 很大,则不能容忍错误分类,因为惩罚会很大。 如果C 很小,则可以容忍错误分类以使边距(软边距)更大。

对于C=1,我有下图(橙色线表示给定x 值的预测),我们可以看到决策边界在7 左右,所以C=1 足够大,不会出现任何错误分类。

X_test_svml=np.linspace(-1, 30, 300).reshape(-1,1)
plt.scatter(X,y)
plt.scatter(X_test_svml,svm_lin.predict(X_test_svml),marker="_")
plt.axhline(.5, color='.5')

C=0.001 为例,我希望决策边界位于右侧,例如 11 左右,但我得到了:

我尝试使用另一个具有SVC 功能的模块:

from sklearn.svm import SVC
svc_lin = SVC(kernel = 'linear', random_state = 0,C=0.01)
svc_lin.fit(X,y)

我成功得到了想要的输出:

通过我的 R 代码,我得到了一些更容易理解的东西。 (我使用了e1071包中的svm函数)

【问题讨论】:

【参考方案1】:

LinearSVCSVC(kernel=linear) 不是同一个东西。

区别在于:

SVC 和 LinearSVC 应该优化相同的问题,但实际上所有 liblinear 估计器都会对截距进行惩罚,而 libsvm 则不会 (IIRC)。 这会导致不同的数学优化问题,从而导致不同的结果。 还可能存在其他细微差别,例如缩放和默认损失函数(编辑:确保在 LinearSVC 中设置 loss='hinge')。 接下来,在多类分类中,liblinear 默认执行 one-vs-rest,而 libsvm 执行 one-vs-one。

另请参阅:https://***.com/a/33844092/5025009

【讨论】:

在official documentation of scikit learn 中,似乎数学公式并不表示截距会受到惩罚。还是我误会了?

以上是关于LinearSVC sklearn (scikit-learn) 中 C 的行为的主要内容,如果未能解决你的问题,请参考以下文章

sklearn中的SVM

sklearn:评估 LinearSVC AUC

scikit中LinearSVC缩减后如何获取选中的特征

scikit-learn 中的 SVC 和 LinearSVC 在啥参数下是等效的?

sklearn:LinearSVC 和 OneSVM 的 AUC 分数

如何在 Scikit-Learn 中获取 GridSearchCV() 的 OneVsRestClassifier(LinearSVC()) 的估算器键参考?