非线性SVM分类

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

非线性SVM分类

线性SVM分类器在很多情况下,他有着很不错的表现,但是也有很多复杂的图像他可能不能够线性分离。 本文将会介绍两种方法去处理非线性的问题,先看下图1:

图1 线性不可分离

图1中的数据只有一个特征 x 1 x_{1} ,导致显示的图像中两类不同的实例都混在一起了,这样导致我们不能够继续使用线性分类。但是如果我们可以像之间使用多项式回归一样,可以通过讲一个特征增加阶数后形成一个新的图像。

在本例中,我们可以新增一个 ( x 2 = x 1 ) 2 (x_2 = x_1)^{2} ,重新看一下新的图像之间是不是会有什么变化:

图2 线性可分离

添加了新的特征后,图像似乎被很明显的分成了两部分,现在就是一个很完美的线性可分离的状态。

在Scikit-Learn中有个方法make_moons(),在官网的介绍是A simple toy dataset to visualize clustering and classification algorithms.它可以生成一些简单的数据集,用于可视化聚类算法和分类算法。我们就简单的生成一下,如下图:

图3 简单的数据集

使用make_moons(),可以很明显的看出两类好像两个半圆合在一起,这个正是他的特点(详细内容在官方文档上有介绍)。那我们是不是可以用增加一个3阶的函数,然后去匹配一下看看效果如何:

图4 新增3阶多项式特征的线性SVM分类器

上面的分类器是通过LinearSVC()方法实现的,同时使用了PolynomialFeatures(degree=3)新增一个3阶多项式特征。

在LinearSVC()的方法中,有一个超参数loss:在这里可以选择hinge这使用了 l 1 l_{1} 范数,squared_hinge则可以选择 l 2 l_{2} 范数。

方法一:多项式内核

上面为LinearSVC(),添加了多项式特征似乎能解决一部分的分线性问题,但是我们不要忘记PolynomialFeatures()在生成高阶多项式特征时会产生的问题:他会因为要产生过多的多项式特征,而导致模型训练过慢。

因此在解决这个问题上,我们可以通过修改SVM的核。我们修改SVM(kernel="poly")后,它能够和产生了许多高阶多项式特征的效果一样,但是在实际上并没有新增任何的特征。

SVM(kernel="poly",degree=3,coef0=1,C=5):通过这个就能够得到一个3阶多项式分类器

  • kernel 就是SVM的内核,如果要线性的可以使用"linear"
  • degree 多项式的阶数
  • C 惩罚参数
  • coef0 根据他的数值大小去控制模型受高阶多项式还是低阶多项式影响。数值大,就受高阶多项式的影响多点。

方法二:相似特征和RBF

除了可以通过上面增加多项式特征方法,我们还可以使用相似特征的方法来解决分线性问题。比如常用的高斯径向基函数(RBF),他的公式如下:

ϕ γ ( x , l ) = e ( γ x l 2 ) \phi_\gamma(x,l) = e^{(-\gamma\left\| x-l \right\|^{2})}

这边我们需要自己修改一个超参数gamma( γ \gamma ):当模型过拟合,就降低他的值,如果欠拟合,就增加。这个和正则化作用有些类似。

使用也很方便,修改一下SVM的核就行,如SVM(kernel="rbf",gamma=1,C=1)

图6 不同gamma和惩罚值的RBF核SVM分类器

从上图看出随着gamma的增加,每个实例的范围也在减少,如果太大就会增加模型的过拟合。C越小,模型也会过拟合。

猜你喜欢

转载自juejin.im/post/7106151435746443294