【367】通过 python 实现 SVM 硬边界 算法
参考: 支持向量机整理
SVM 硬边界的结果如下:
min12m∑i=1m∑j=1αiαjyiyj→xi→xj−m∑i=1αis.t.αi≥0i=1...mm∑i=1αiyi=0
一. 数据准备
测试数据如下所示, 前两个为 -1, 后面三个为 1, 如下图可以看到分割线即为:
y=x+1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import numpy as np import matplotlib.pyplot as plt X = np.array([[ 1 , 3 ], [ 0 , 2 ], [ 0 , 0 ], [ 2 , 0 ], [ 2 , 2 ]]) x = np.linspace( - 2 , 3 , 100 ) y = np.array([ - 1 , - 1 , 1 , 1 , 1 ]) plt.figure() plt.scatter(X[: 2 , 0 ],X[: 2 , 1 ]) plt.scatter(X[ 2 :, 0 ],X[ 2 :, 1 ]) plt.plot(x, x + 1 ) plt.show() |
二. 获取 QP 的参数并计算α
将下面的结果带入到二次规划问题中分别求得 P/p/G/h/A/b 的值.
这个过程不是很容易, 虽然数据量这么少, 我反反复复弄了好几遍最终才做对.
min12m∑i=1m∑j=1αiαjyiyj→xi→xj−m∑i=1αis.t.αi≥0i=1...mm∑i=1αiyi=0
按照下面的形式进行获取参数.
min12xTPx+qTxs.t.Gx≤hAx=b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # 需要将 X 中的数据彼此相乘, 得到一个 5*5 的矩阵 # 同时需要注意 y 的符号会影响 P = matrix([[ 10.0 , 6.0 , 0.0 , - 2.0 , - 8.0 ], [ 6.0 , 4.0 , 0.0 , 0.0 , - 4.0 ], [ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ], [ - 2.0 , 0.0 , 0.0 , 4.0 , 4.0 ], [ - 8.0 , - 4.0 , 0.0 , 4.0 , 8.0 ]]) # 为了得到一个常数, q 为 5*1 的矩阵, 转置后正好可以用 q = matrix( - 1.0 , ( 5 , 1 )) # 首先将 ≥ 调整为 ≤, 然后按照向量的形式表示 # 结果 h 为 5*1 的矩阵 # 因此 G 为 5*5 的矩阵(α 是 5*1 矩阵) G = matrix([[ - 1.0 , 0.0 , 0.0 , 0.0 , 0.0 ], [ 0.0 , - 1.0 , 0.0 , 0.0 , 0.0 ], [ 0.0 , 0.0 , - 1.0 , 0.0 , 0.0 ], [ 0.0 , 0.0 , 0.0 , - 1.0 , 0.0 ], [ 0.0 , 0.0 , 0.0 , 0.0 , - 1.0 ]]) h = matrix( 0.0 , ( 5 , 1 )) # 结果为常数的形式, 因此 A 是一个 1*5 矩阵 A = matrix([ 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 ]).T b = matrix( 0.0 , ( 1 , 1 )) |
将上面的内容带入到二次规划的函数中进行求解.
1 2 3 | sol = solvers.qp(P,q,G,h,A,b) alpha = sol[ 'x' ] print (alpha) |
pcost dcost gap pres dres 0: -1.4151e+00 -3.0463e+00 1e+01 3e+00 2e+00 1: -3.4780e-01 -2.4147e+00 2e+00 7e-16 8e-16 2: -9.2882e-01 -1.0856e+00 2e-01 3e-16 5e-16 3: -9.9882e-01 -1.0010e+00 2e-03 2e-16 3e-16 4: -9.9999e-01 -1.0000e+00 2e-05 1e-16 3e-16 5: -1.0000e+00 -1.0000e+00 2e-07 2e-16 2e-16 Optimal solution found. [ 4.31e-01] [ 5.69e-01] [ 2.84e-01] [ 5.88e-08] [ 7.16e-01]
三. 根据α来计算w
目前已经求出了所有的α, 根据下面的公式将所有的样本点数据带入求得→w. 根据α的结果可以判断哪些是支持向量, 包括 index = 0, 1, 2, 4 都满足.
→w=m∑i=1αiyi→xi
1 2 3 4 5 6 7 8 9 10 | X0 = X[:, 0 ].flatten() X1 = X[:, 1 ].flatten() w1 = (w * y * X0). sum () w2 = (w * y * X1). sum () W = np.array([w1,w2]) print ( "w1=" , w1) print ( "w2=" , w2) |
w1= 1.0000000446896518 w2= -1.000000054585139
四. 根据w来求b
→w已经求出了, 这时候只要带入任何一个支持向量里面即可, 公式如下:
yi(→wT→xi+b)=1
化简后得到:
b=yi−→wT→xi
由上面计算可知, 第一个点在支持向量上面, 因此可以计算获得b值.
b=y1−→wT→x1
1 2 3 4 5 6 | W = np.mat(W) xx = np.mat(X[ 1 ,:].T) xx = xx.T b = int ( - 1 - W * xx) print ( "b=" , b) |
b= 1
所以最终的结果就是:
x1−x2+1=0
将x1换成x, 将x2换成y, 则得到:
y=x+1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)