支持向量机(SVM)被誉为数据科学领域的重量级算法,是机器学习中不可或缺的工具之一。SVM以其优秀的泛化能力和对高维数据的管理而备受推崇。本文旨在梳理SVM的核心概念以及其在实际场景中的应用。
SVM的核心理念
SVM专注于为二分类问题找到最佳决策边界,即超平面,该平面能最大化两类数据之间的空隙或间隔。线性SVM假设用一个直线(或高维空间中的超平面)足以有效地分隔数据。当遇到重叠或杂乱无章散布的数据时,软间隔SVM允许某些点位于错误的边界一侧,这通过引入松弛变量与罚项系数C来实现,从而提供一个稳健的平衡方案。
算法实现
SVM通过转化优化问题为其对偶形式并使用拉格朗日乘子法来解决。这不仅简化了求解过程,还能自然地加入核技巧(Kernel trick)来处理非线性可分的数据集。
一个经典案例
为了具体说明SVM的应用,我们考虑了一个著名的数据集。
- 鸢尾花分类:鸢尾花数据集由三个品种的鸢尾花构成,每一种都有50个样本和4个特征。对于二分类任务,我们专注于将Setosa从Versicolour中区分出来。
实践应用
利用MindOpt APL,一种强大的代数建模语言和求解器,我们可以更高效地构建和解决SVM优化问题。在训练阶段,算法学习数据的模式,并找到分隔不同类别的最优决策边界。一旦模型确定,我们便可用其做出预测并评估其在未见数据上的性能。
clear model; #################################################### # # Vectorization Modeling Example # Linear SVM # #################################################### option modelname svm_02; #定义存储文件名 # ----------建模--------Start---- # svm_02.mapl # 1.读取iris的用于构建SVM模型的训练数据 param data_dir = "./data/iris_data-train.csv"; param X = read_csv( data_dir, use_col="0,1,2,3",skip=1); param y = read_csv( data_dir, use_col=4,skip=1); param dataNum = X.row; param dataDim = X.col; print "总共有{}个数据,每个数据有{}维"%dataNum,dataDim; # 2.LinearSVM问题建模 param C_rho = 0.2; print "Param C is :{}"%C_rho; print "Start modeling-------"; var w(dataDim) >= -1 <= 1; # Bounded Model Parameter var b; # var eps(dataNum) >= 0; minimize 1/2 * w' * w + C_rho * sum(eps); #'是转置,目标函数 subto constraint: eps >= 1 - (X*w +b).*y; #注意是向量化建模,因此相当于多条维度的约束 # 3.调用求解器求解 print "Start solving-------"; option solver mindopt; solve; # 4. 超平面的w取值 print "- Optimal w is:"; print w; print "- Optimal b is:"; print b; print "- eps is:"; forall { i in 0..dataNum-1 with eps[i] > 0.001} print " - eps[{}] = {} "%i,eps[i]; param obj_total_loss = 1/2 * w' * w + C_rho * sum(eps); #'是转置 print "- obj of total loss is : {}"%obj_total_loss; # 5.验证并分析结果 print ""; print "验证结果:-----"; param correctNum = sum{i in 0..dataNum-1} if((sum{j in 0..dataDim-1}w[j]*X[i, j]) +b )* y[i] > 0 then 1 else 0 end; param precision = correctNum / dataNum; print "- Precision for train data is : {:.2f}" % precision; # print ""; print "导入测试数据验证效果:-----"; param data_dir_test = "./data/iris_data-test.csv"; param X_test = read_csv( data_dir_test, use_col="0,1,2,3",skip=1); param y_test = read_csv( data_dir_test, use_col=4,skip=1); param dataNum_test = X_test.row; param dataDim_test = X_test.col; print "- 总共有{}个数据,每个数据有{}维"%dataNum_test,dataDim_test; print "|测试数据ID|实际标签|SVM预测标签是|"; print "|--|--|--|"; forall {i in 0..dataNum_test-1} print "|{}|{}|{}|"%i,y_test[i], if((sum{j in 0..dataDim_test-1}w[j]*X_test[i, j]) +b ) > 0 then 1 else -1 end;
运行上述代码结果如下:
总共有80个数据,每个数据有4维 Param C is :0.2 Start modeling------- Start solving------- Running mindoptampl wantsol=1 MindOpt Version 1.2.1 (Build date: 20240428) Copyright (c) 2020-2024 Alibaba Cloud. Start license validation (current time : 29-APR-2024 17:51:11). License validation terminated. Time : 0.007s Model summary. - Num. variables : 85 - Num. constraints : 80 - Num. nonzeros : 480 - Bound range : [1.0e+00,1.0e+00] - Quad. bound range : [1.0e+00,1.0e+00] - Objective range : [2.0e-01,2.0e-01] - Quad. obj. range : [1.0e+00,1.0e+00] - Matrix range : [1.0e-01,7.0e+00] Presolver started. Presolver terminated. Time : 0.000s Interior point method started. Iter PrimObj DualObj PrimFea DualFea GapFea Mu Time 0 +1.56581101e+01 -1.06624290e+01 2.0e-01 2.6e-01 2.5e+00 6.2e-01 0.02s 1 +8.56566249e+00 -7.16779185e-01 5.4e-04 7.6e-03 9.3e+00 6.5e-02 0.04s 2 +9.75513434e-01 +2.94267093e-01 2.7e-05 1.4e-03 6.8e-01 4.1e-03 0.05s 3 +5.98630319e-01 +4.50898225e-01 4.2e-06 1.5e-04 1.5e-01 8.9e-04 0.05s 4 +5.12227038e-01 +4.88329845e-01 1.1e-08 1.2e-03 2.5e-02 1.5e-04 0.05s 5 +5.04653750e-01 +5.01437631e-01 9.7e-10 2.0e-04 3.2e-03 1.9e-05 0.06s 6 +5.02835294e-01 +5.02808740e-01 2.7e-12 5.4e-07 2.7e-05 1.6e-07 0.06s 7 +5.02821164e-01 +5.02821090e-01 7.1e-15 1.5e-09 7.3e-08 4.4e-10 0.06s 8 +5.02821125e-01 +5.02821124e-01 1.9e-16 4.1e-12 2.0e-10 1.2e-12 0.06s Terminated. - Method : Interior point method. - Primal objective : 5.0282112458779E-01 - Dual objective : 5.0282112438583E-01 - Num. threads : 4 - Num. iterations : 8 - Solver details : Solver terminated with a primal/dual optimal status. Interior point method terminated. Time : 0.046s OPTIMAL; objective 0.50 0 simplex iterations Completed. - Optimal w is: [[-0.16610], [ 0.35465], [-0.75422], [-0.32403]] - Optimal b is: 2.038087831121987 - eps is: - eps[23] = 0.08284647160625058 - eps[24] = 0.05118542249112839 - eps[47] = 0.26241815907236044 - eps[69] = 0.04962685713002854 - obj of total loss is : 0.5028211245877855 验证结果:----- - Precision for train data is : 1.00 导入测试数据验证效果:----- - 总共有20个数据,每个数据有4维 |测试数据ID|实际标签|SVM预测标签是| |--|--|--| |0|1|1| |1|1|1| |2|1|1| |3|1|1| |4|1|1| |5|1|1| |6|1|1| |7|1|1| |8|1|1| |9|1|1| |10|-1|-1| |11|-1|-1| |12|-1|-1| |13|-1|-1| |14|-1|-1| |15|-1|-1| |16|-1|-1| |17|-1|-1| |18|-1|-1| |19|-1|-1|
结果
上面的程序运行结果如下:
其中,小数后几位是精度影响,每次会有变化,不影响结果。
总共有80个数据,每个数据有4维
Param C is :0.2
……
- Optimal w is: [[-0.16610], [ 0.35465], [-0.75422], [-0.32403]]
- Optimal b is: 2.038087831122001
- eps is:
- eps[23] = 0.08284647160625147
- eps[24] = 0.051185422491125426
- eps[47] = 0.26241815907236443
- eps[69] = 0.049626857130028075
- obj of total loss is : 0.5028211245877853
验证结果:-----
- Precision for train data is : 1.00
导入测试数据验证效果:-----
- 总共有20个数据,每个数据有4维
测试数据ID |
实际标签 |
SVM预测标签是 |
0 |
1 |
1 |
1 |
1 |
1 |
2 |
1 |
1 |
3 |
1 |
1 |
4 |
1 |
1 |
5 |
1 |
1 |
6 |
1 |
1 |
7 |
1 |
1 |
8 |
1 |
1 |
9 |
1 |
1 |
10 |
-1 |
-1 |
11 |
-1 |
-1 |
12 |
-1 |
-1 |
13 |
-1 |
-1 |
14 |
-1 |
-1 |
15 |
-1 |
-1 |
16 |
-1 |
-1 |
17 |
-1 |
-1 |
18 |
-1 |
-1 |
19 |
-1 |
-1 |
可以看到,对于这份数据,计算的超平面能很好地进行二分类,在测试集合上也有100%的正确率,证实了SVM在实际问题中的有效性。