机器学习(二):感知机+svm习题 感知机手工推导参数更新 svm手推求解二维坐标超平面直线方程
作业1:
输入: 训练数据集 \(T = {(x1; y1); (x2; y2),..., (xN; yN)}\) 其中,\(x \in R^n\), \(y \in Y = \{+1, -1\}\), \(i=1,2...,N\),学习率\(η = 0.1\).
输出: \(w\),\(b\) ; 感知机模型\(f(x) = sign(w · x + b)\)
给出下列训练数据的感知机参数学习过程:
\(x_1\) | \(x_2\) | \(y\) |
---|---|---|
-3.0 | 3.0 | 1 |
-5.0 | 2.0 | 1 |
2.0 | 4.0 | -1 |
3.0 | 2.0 | -1 |
解:
step1: 令初值 \(w_o=[0,0]^T,b_0=0\)
step2: 选取第一个点 \((x_1,y_1)=([-3,3]^T,1)\)
step3: 计算 \(y_i(w_i\cdot x_i+b)=1\times (0+0)=0\le 0\) 那么进行迭代
\(w \leftarrow w+\eta y_{i} x_{i}\) 即 \(w_1=[0,0]^T+0.1\times 1\times [-3,3]^T=[-0.3,0.3]^T\)
\(b \leftarrow b+\eta y_{i}\) 即 \(b_1=0+0.1\times 1=0.1\)
step4: 【回到第二步验证第三步分类结果并迭代直到没有误分类】
感知机算法是收敛的,不会无限更新参数
再次计算可知对于第一个点\(y_1(w_1 \cdot [x_{11},x_{12}]^T+b)=1 \times (-0.3 \times -3+0.3 \times 3+0.1)=1.9>0\)
对于第二个点:\(1\times (1.5+0.6+0.1)=2.2>0\)
对于第三个点:\(-1\times (-0.6+1.2+0.1)=-0.7<0\)
进行迭代\(w_2=[-0.3-0.1\times2,0.3-0.1\times 4]^T=[-0.5,-0.1]^T\)
\(b_2=0.1+0.1=0.2\)
对于第一个点:\(y_1(w_1\cdot x_1+b_1)=1.2>0\)
对于第二个点:\(y_2(w_2\cdot x_2+b_2)=2.3>0\)
对于第三个点:\(y_3(w_3\cdot x_3+b_3)=1.4>0\)
对于第四个点:\(y_4(w_4\cdot x_4+b_4)=1.7>0\)
没有误分类,迭代结束.
作业2:
根据数据样本点,按照SVM算法计算分类超平面方程
\(x_1\) | \(x_2\) | \(y\) |
---|---|---|
-3.0 | 3.0 | 1 |
-5.0 | 2.0 | 1 |
2.0 | 4.0 | -1 |
3.0 | 2.0 | -1 |
解:
step1:将散点图绘制在坐标轴上,观察并找出支持向量,对应的支持向量(点)是(-3,3)和(2,4)

step2:把向量w伸缩1,这样就不用单独更新b了(w将b吸收了)
有\(s_1=\begin{bmatrix} -3\\ 3\\1\end{bmatrix}\),\(s_2=\begin{bmatrix} 2\\ 4\\1\end{bmatrix}\)
同时\(s_1\)标注为+1,有\(w_0^Tx+b=1\),即\(<w,s_1>=1\)
<a,b>表示内积,点乘;a<>b表示矩阵乘法
然后根据推论:最小化拉格朗日函数\(L(w,b,a)\)要求其极值点,满足L的w偏导为0
带入点积运算得到(已知\(y_1=1,y_2=-1\)):
结果:
解得\(a_1=\frac{2}{25},a_2=\frac{13}{175}\)
那么\(w=\sum_{i=1}^{m} a_{i} y_{i} s_{i}=\begin{bmatrix} -0.39\\ -0.06\\0.006\end{bmatrix}\)
那么\(w_0=[-0.39,-0.06]^T\),\(b=0.006\)
带入\(y=w_0^Tx+b\)计算得到

根据支持向量计算结果无误.
附录:
感知机算法实现代码:
import numpy as np
def perceptron(X, Y, max_iter=1000, alpha=1.0):
"""
X: m x n matrix, m samples with n features
Y: m x 1 matrix, true labels of m samples
max_iter: int, maximum training iterations
alpha: float, learning rate
"""
# 初始化权重向量和偏置
w = np.zeros((X.shape[1], 1))#x行1列的0矩阵
b = 0.0
# 迭代更新权重和偏置
for iter in range(max_iter):
w_last=w
b_last=b
for i in range(X.shape[0]):
y_pred = np.sign(np.dot(X[i], w) + b)
print("当前参数w={},b={},对于第{}个点".format(w.T,b,i+1))
print(int(Y[i]*y_pred),Y[i]*(np.dot(X[i], w) + b))
if y_pred != Y[i]:
w = w + alpha * Y[i] * X[i].reshape(-1, 1)
b = b + alpha * Y[i]
break
if (np.array_equal(w, w_last)==False and b!=b_last):
w_last= w
b_last = b
elif (np.array_equal(w, w_last) and b==b_last):
break
return w, b
def main():
X = np.array(
[
[-3, 3],
[-5, 2],
[2 , 4],
[3 , 2]
]
)
Y=np.array([1,1,-1,-1])
perceptron(X, Y, max_iter=100, alpha=0.1)
if __name__ == '__main__':
main()
绘制散点图的代码:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
# 坐标点数据
X = np.array([[-3, 3], [-5, 2], [2, 4], [3, 2]])
y = np.array([1, 1, -1, -1])
# 定义SVM分类器
clf = svm.SVC(kernel='linear')
clf.fit(X, y)
# 定义SVM超平面
w = clf.coef_[0]
b = clf.intercept_
x1 = np.arange(-6, 6)
x2 = -(w[0] * x1 + b) / w[1]
# 创建一个散点图
fig, ax = plt.subplots()
# 设置坐标轴范围和中心点
x_min, x_max = -6, 6
y_min, y_max = -6, 6
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
# 绘制四个点
ax.scatter(X[0, 0], X[0, 1], color='r')
ax.scatter(X[1, 0], X[1, 1], color='r')
ax.scatter(X[2, 0], X[2, 1], color='b')
ax.scatter(X[3, 0], X[3, 1], color='b')
# 绘制SVM超平面
ax.plot(x1, x2, c='r',label='svm')
# 在散点周围添加坐标注释
ax.annotate(f'({X[0, 0]}, {X[0, 1]})', xy=(X[0, 0], X[0, 1]), xytext=(5, 5), textcoords='offset points')
ax.annotate(f'({X[1, 0]}, {X[1, 1]})', xy=(X[1, 0], X[1, 1]), xytext=(5, 5), textcoords='offset points')
ax.annotate(f'({X[2, 0]}, {X[2, 1]})', xy=(X[2, 0], X[2, 1]), xytext=(5, 5), textcoords='offset points')
ax.annotate(f'({X[3, 0]}, {X[3, 1]})', xy=(X[3, 0], X[3, 1]), xytext=(5, 5), textcoords='offset points')
# 增加图例 显示图像
plt.legend(loc='best')
plt.show()