Loading web-font TeX/Math/Italic

alex_bn_lee

导航

< 2025年3月 >
23 24 25 26 27 28 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 27 28 29
30 31 1 2 3 4 5

统计

【367】通过 python 实现 SVM 硬边界 算法

参考: 支持向量机整理

SVM 硬边界的结果如下:

min12mi=1mj=1αiαjyiyjxixjmi=1αis.t.αi0i=1...mmi=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 的值.

这个过程不是很容易, 虽然数据量这么少, 我反反复复弄了好几遍最终才做对.

min12mi=1mj=1αiαjyiyjxixjmi=1αis.t.αi0i=1...mmi=1αiyi=0

按照下面的形式进行获取参数.

min12xTPx+qTxs.t.GxhAx=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=mi=1αiyixi

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(wTxi+b)=1

化简后得到:

b=yiwTxi

由上面计算可知, 第一个点在支持向量上面, 因此可以计算获得b值.

b=y1wTx1

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

所以最终的结果就是:

x1x2+1=0

x1换成x, 将x2换成y, 则得到:

y=x+1

posted on   McDelfino  阅读(475)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示