在分类问题中,相同的 SVM 配置,相同的输入数据使用 Matlab 和 SVM 的 scikit-learn 实现给出不同的输出

数据挖掘 分类 支持向量机 scikit-学习 matlab
2021-10-11 11:25:25

我有一个二维特征空间中有 60 个数据点的分类问题。数据最初分为2类。早些时候我使用的是 Matlab 的 Statistics Toolbox,所以它给了我相当好的结果。它给出了 1 个假阴性和没有假阳性。

我使用了以下代码:

SVMstruct = svmtrain(point(1:60,:),T(1:60),'Kernel_Function','polynomial','polyorder',11,'Showplot',true);

我正在使用多项式内核,多项式阶数为 11。

使用 Matlab 中的 svmTrain 训练数据后生成的边界

但是,当我在 scikit-learn SVC 中使用相同的内核配置时,它并没有给出相同的结果,而是将它们全部分类到单个类中给出了非常不受欢迎的结果。

在 python 中使用 Scikit-learn 中的 SVC 训练数据后生成的边界

我用它作为

svc = svm.SVC(kernel='poly', degree=11, C=10)

我也使用了许多 C 值。没有大的区别。

为什么结果差别这么大?如何获得与使用 Matlab 相同的结果?对我来说,必须使用 python-scikit。

3个回答

您必须确保算法是相同的,并且内核函数确实是相同的。如果您查看scikit learn 中内核的这个 python 文档页面,您将看到 poly kernel 的描述。

请注意,您有一个 gamma 和一个学位。Gamma 默认为“自动”,在 1/n_samples 处评估。对于同一个内核,您有“coef0”(参数的好名字),它在 poly 中用作自由术语。我不知道matlab如何将此值作为默认值,但我发现文献中poly kernel的常用公式是poly(x1,x2)=(<x1,x2>+1)d. 所以没有伽玛,自由项是1. 我认为matlab使用它。(无论如何,我发现 scikit 中的“改进”学习气味不太好)。

同样在此SVC 文档页面中,他们声明有一个称为收缩的参数。我真的不知道它的效果,但它的自动,这意味着启用。可能是个问题。

稍后编辑

我在 matlab中找到了 svm 的这个文档页面,它以我所说的方式描述了内核(没有学位,免费术语1)。它还声明默认使用“SMO”,确保在 python 中也使用“SMO”。

另一方面,您必须了解,这些算法是通过优化方法解决的,这些优化方法通常是迭代的,为了节省一些内存,或者循环它们的实现可能在小细节上有所不同,这几乎会产生不同的结果。然而,我同意结果应该是相似的。

SVC 参数:

是什么促使您使用多项式内核?在某些情况下这可能有意义,但它肯定不是我的首选。径向基函数可能更适合,这就是为什么它是 SKLearn 的默认值。退后一分钟,从大局出发。给定您显示的点,您的人类大脑是否想使用 11 阶多项式创建决策面?看起来您的第二张图像中有几个白点岛,可以很容易地用两个Gaussian functionsaka包裹起来radial basis functions

只有默认参数的 SVC 有什么作用?我见过很多需要高达 10 或 100 的正则化参数的情况,但您还没有谈到您过去使用的交叉验证程序C=10,所以我想知道你是怎么到那里的。

我建议使用默认参数运行 SVC 并查看返回的内容。然后可以尝试调整 gamma(这实际上是决策表面与其周围点之间的缓冲区)和 C(这是控制过度拟合的正则化项,即高方差)。

希望这可以帮助!

我对两种实施方式的差异一无所知,但找到了如何找到问题的决策边界。

在第一步中,我将数据缩放到 [0,100] 的范围,而之前的输入是 [0,1]。(仍然不知道为什么缩放会产生差异)

然后使用低伽马和高C值的RBF内核。

svc = svm.SVC(内核='rbf', gamma=.004, C=1000)。

这给了我以下结果。

使用上述内核创建的分离边界