支持向量机(support vector machines, SVM)是一种二分类模型,所谓二分类模型是指比如有很多特征(自变量X)对另外一个标签项(因变量Y)的分类作用关系,比如当前有很多特征,包括身高、年龄、学历、收入、教育年限等共5项,因变量为‘是否吸烟’,‘是否吸烟’仅包括两项,吸烟和不吸烟。那么该5个特征项对于‘是否吸烟’的分类情况的作用关系研究,则称为‘二分类模型’,但事实上很多时候标签项(因变量Y)有很多个类别,比如某个标签项Y为‘菜系偏好’,中国菜系有很多,包括川菜、鲁菜、粤菜、闽菜、苏菜、浙菜、湘菜和徽菜共计8类,此时则需要进行‘多分类决策函数’转化,简单理解为两两类别(8个中任意选择2)分别建立SVM模型,然后进行组合使用。
机器学习算法常见算法中包括决策树、随机森林、贝叶斯等,上述均有良好的可解释性,比如决策树是将特征按分割点不停地划分出类别,随机森林是多个决策树模型,贝叶斯模型是利用贝叶斯概率原理进行计算。与上述不同,支持向量机模型是利用运筹规划约束求最优解,而此最优解是一个空间平面,此空间平面可以结合特征项,将‘吸烟’和‘不吸烟’两类完全地分开,寻找该空间平面即是支持向量机的核心算法原理。
支持向量机的计算原理复杂,但对其通俗地理解并不复杂,只需要知道其需要求解出‘空间平面’,该‘空间平面’可以把不同的标签项(因变量Y)类别特别明显的划分开即可。类似其它机器学习算法,支持向量机的构建步骤上,一般也需要先对数据进行量纲化处理、设置训练数据和测试数据比例、设置相关参数调优,最终实现在训练数据上有着良好表现,并且测试数据上也有着良好表现即可。
比如红色表示“吸烟”,黄色表示“不吸烟”,那么如何找到一个平面最大化的将两类群体分开,如上图所示,分开有很多种方式,左侧也可以分开,右侧也能分开。但明显的,右侧会“分的更开”,因而如何寻找到这样的一个空间平面,让标签项各类别最为明显的分开,此算法过程即为支持向量机。将点分开时,离平面最近的点要尽可能的远,比如右侧时A点和B点离平面最近,那么算法需要想办法让该类点尽可能地远离平面,这样就称为“分的更好”。左侧时挨着平面最近的两个点离平面太近,所以右侧的分类更好。
与此同时,理论上可以找到‘空间平面’,将点彻底完全地分开,但此种情况并没有用,因为它只是数学上彻底地分开,但对真实数据业务并没有帮助,与此同时,数学计算上如果尽可能地让点分开,那么很容易出现‘过拟合’现象,即训练数据时模型构建完美,但测试数据上的表现糟糕,因而通过可对此类情况进行惩罚,即设置‘误差项惩罚系数值’。另外,为构建出空间平面,还需要使用到非线性函数,SVM模型时称‘核函数’,其用用于将特征从低维(比如二维XY轴平面)向高维空间转换,并且对其进行一定参数设置,以寻找较优模型。
结合支持向量机的原理情况,其涉及以下参数,如下:
SVM本身只进行二分类,当有多个类别时,可以选择每两个类别之间都建立一个SVM分类器,或者每个类别与余下的所有类别各建立一个分类器。
ovr:(默认)每个类别与剩余的类别各建立一个分类器。
ovo:每两个类别都分别建立一个分类器。
模型收敛参数
模型的误差变化率小于该值的时候,结束模型构建
默认0.001。
最大迭代次数
若迭代次数达到该值时依然不收敛,则停止迭代。
最大2000次。
多分类决策函数:基础的的SVM只处理二分类问题,如果标签项(因变量Y)有多个类别,比如8大菜系共8个类别时,那么算法上有两种方式,第1种是每个类别与余下类别(作为反例)建立1个SVM然后整合(共计建立8个SVM),即ovr法(1对其余法),还有一种方式是两两配对法即ovo法,8个类别形成8*(8-1)/2=28个配对组合,即进行28次SVM然后整合,该项默认值为ovr法。
最后:模型收敛参数值和最大迭代次数这两项,其为算法内部迭代求最优解的参数值,正常情况下不用设置。
训练集比例默认选择为:0.8即80%(150*0.8=120个样本)进行训练支持向量机模型,余下20%即30个样本(测试数据)用于模型的验证。需要注意的是SVM时涉及距离计算,因而需要对特征进行量纲处理,通常量纲处理方式为正态标准化,此处理目的是让数据保持一致性量纲。当然也可使用其它的量纲方式,比如区间化,归一化等。
接着对参数设置如下:
具体上述具体指标的解读,可见决策树模型帮助手册,通常使用F1-score值进行评估即可,训练数据时f1-score值为0.96,并且测试集数据也保持着0.94高分,二者比较接近,因而意味着应该不存在‘过拟合’现象,而且模型良好。
接着进一步查看测试数据的‘混淆矩阵’,即模型预测和事实情况的交叉集合,如下图:
model = svm.SVC(C=1.0, kernel=rbf, gamma=scale, tol = 0.001, max_iter=2000, decision_function_shape=ovr)
model.fit(x_train, y_train)