一、什么是支持向量机
支持向量机(support vector machines)是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。它既能解决线性可分又能解决线性不可能,既能解决分类问题又能完成回归问题。
当训练样本线性可分时使用硬间隔最大化(Hard Margin SVM)或者近似线性可分时使用软件最大化(Soft Margin SVM)。当训练样本线性不可分时使用核函数和软间隔最大化。
在实际问题中往往都存在着决策边界不唯一的情况,这就是不适定问题。给定训练样本集 D={(x1,y1),(x2,y2),…,(xm,ym)},yi∈{-1,1} 分类算法的基本思想就是基于训练集在样本空间中找到一个划分超平面,但是能将训练样本分开的划分超平面可能有很多,所以,应该努力地去找哪一个?
而svm找到的这条直线希望距离最近的红色的点和蓝色的点,距离决策边界尽可能的远,这样就能保证模型的泛化能力。svm尝试寻找一个最优的决策边界,距离两个类别最近的样本最远,图中3个点到决策边界距离相同。这三个点就叫做支持向量(support vector)。而平行于决策边界的两条直线之间的距离就是 margin,svm就是要最大化 margin ,这样就把这个问题转化称为最优化问题。
二、深入了解SVM
2.1 线性可分到线性不可分
2.1.1 从原始问题到对偶问题的求解
虽然上文1.3节给出了目标函数,却没有讲怎么来求解。现在就让我们来处理这个问题。回忆一下之前得到的目标函数(subject to导出的则是约束条件):
由于求
的最大值相当于求
的最小值,所以上述问题等价于(w由分母变成分子,从而也有原来的max问题变为min问题,很明显,两者问题等价):
- 转化到这个形式后,我们的问题成为了一个凸优化问题,或者更具体的说,因为现在的目标函数是二次的,约束条件是线性的,所以它是一个凸二次规划问题。这个问题可以用任何现成的 QP (Quadratic Programming) 的优化包进行求解,归结为一句话即是:在一定的约束条件下,目标最优,损失最小;
- 但虽然这个问题确实是一个标准的 QP 问题,但是它也有它的特殊结构,通过 Lagrange Duality 变换到对偶变量 (dual variable) 的优化问题之后,可以找到一种更加有效的方法来进行求解,而且通常情况下这种方法比直接使用通用的 QP 优化包进行优化要高效得多。
也就说,除了用解决QP问题的常规方法之外,还可以通过求解对偶问题得到最优解,这就是线性可分条件下支持向量机的对偶算法,这样做的优点在于:一者对偶问题往往更容易求解;二者可以自然的引入核函数,进而推广到非线性分类问题。
至于上述提到,关于什么是Lagrange duality?简单地来说,通过给每一个约束条件加上一个 Lagrange multiplier(拉格朗日乘子),即引入拉格朗日乘子,如此我们便可以通过拉格朗日函数将约束条件融和到目标函数里去(也就是说把条件融合到一个函数里头,现在只用一个函数表达式便能清楚的表达出我们的问题,n为样本个数):
然后我们令
容易验证,当某个约束条件不满足时,例如,那么我们显然有
(只要令
即可)。而当所有约束条件都满足时,则有
,亦即我们最初要最小化的量。因此,在要求约束条件得到满足的情况下最小化
,实际上等价于直接最小化
。
因为如果约束条件没有得到满足,会等于无穷大,自然不会是我们所要求的最小值。具体写出来,我们现在的目标函数变成了:
这里用表示这个问题的最优值,这个问题和我们最初的问题是等价的。不过,现在我们来把最小和最大的位置交换一下(稍后,你将看到,当下面式子满足了一定的条件之后,这个式子d 便是上式P 的对偶形式表示):
当然,交换以后的问题不再等价于原问题,这个新问题的最优值用来表示。并且,我们有
≤
,这在直观上也不难理解,最大值中最小的一个总也比最小值中最大的一个要大吧! 总之,第二个问题的最优值
在这里提供了一个第一个问题的最优值
的一个下界,在满足某些条件的情况下,这两者相等,这个时候我们就可以通过求解第二个问题来间接地求解第一个问题。
也就是说,下面我们将先求L 对w、b的极小,再求L 对的极大。而且,之所以从minmax的原始问题
,转化为maxmin的对偶问题
,一者因为
是
的近似解,二者,转化为对偶问题后,更容易求解。
2.1.2 KKT条件
与此同时,上段说“在满足某些条件的情况下”,这所谓的“满足某些条件”就是要满足KKT条件。那KKT条件的表现形式是什么呢?据维基百科:KKT 条件的介绍,一般地,一个最优化数学模型能够表示成下列标准形式:
- KKT条件的意义:它是一个非线性规划(Nonlinear Programming)问题能有最优化解法的必要和充分条件。
那到底什么是所谓Karush-Kuhn-Tucker条件呢?KKT条件就是指上面最优化数学模型的标准形式中的最小点 x* 必须满足下面的条件:
经过论证,我们这里的问题是满足 KKT 条件的(首先已经满足Slater condition,再者f和gi也都是可微的,即L对w和b都可导),因此现在我们便转化为求解第二个问题。也就是说,现在,咱们的原问题通过满足一定的条件,已经转化成了对偶问题。而求解这个对偶学习问题,分为3个步骤,首先要让L(w,b,a) 关于 和 最小化,然后求对α的极大,最后利用SMO算法求解对偶因子。
2.1.3 求解对偶问题的步骤
(1)首先固定,要让 关于 和 最小化,我们分别对w,b求偏导数,即令 和 等于零。
以上结果代回上述的
得到:
提醒:有读者可能会问上述推导过程如何而来?说实话,其具体推导过程是比较复杂的,如下图所示:
最后,得到:
(2)求的极大值,这块交由SMO算法处理,具体可以参考相关论文资料。
不得不提醒下读者:经过上面第一个步骤的求w和b,得到的拉格朗日函数式子已经没有了变量w,b,只有,而反过来,求得的
将能导出w,b的解,最终得出分离超平面和分类决策函数。为何呢?因为如果求出了
,根据
,即可求出w。然后通过
,即可求出b 。
三、基础代码实现
基于sklearn的代码实现
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
def create_data():
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
data = np.array(df.iloc[:100, [0, 1, -1]])
for i in range(len(data)):
if data[i,-1] == 0:
data[i,-1] = -1
return data[:,:2], data[:,-1]
X, y = create_data()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
plt.scatter(X[:50,0],X[:50,1], label='0')
plt.scatter(X[50:,0],X[50:,1], label='1')
plt.show()
model = SVC()
model.fit(X_train, y_train)
SVC(C=1.0, break_ties=False, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
print('train accuracy: ' + str(model.score(X_train, y_train)))
print('test accuracy: ' + str(model.score(X_test, y_test)))
四、运行效果
五、反思总结
- 数据预处理是模型训练前的重要步骤,能够有效提高模型的性能和稳定性。
- 通过交叉验证和网格搜索等方法可以有效找到适合数据集的参数设置。同时,要注意避免过拟合和欠拟合的问题。
- 根据数据集的特性和问题的需求选择合适的核函数是SVM应用的关键。在实际应用中,可以通过实验对比不同核函数的性能来选择最合适的核函数。
- 在评估模型性能时,除了准确率等指标外,还要考虑其他指标如精确率、召回率、F1分数等,以全面评估模型的性能。