视频地址 https://www.imooc.com/video/17903
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.figsize'] = {8.0, 6.0} # 生成图的大小
# 产生新画布
fig = plt.figure();
figa = plt.gca()
N = 100
# 随机产生N个 2维的0-1之间的数组 如 [[0.2 0.4],[0.333 0.43233]]
xn = np.random.rand(N, 2)
print(xn)
# 随机产生50个 0到1之间的数组
x = np.linspace(0, 1)
a = np.random.rand() # 随机生成一个0~1之间的数字
b = np.random.rand()
# 随机生成一条直线
f = lambda x: a * x + b
plt.plot(x, f(x), 'r')
# 线性分割前面产生的点
yn = np.zeros([N, 1]) # 生成N个1维的0数组 (类似于定义一个空的数组)
for i in range(N):
if (f(xn[i, 0]) >= xn[i, 1]):
yn[i] = 1
plt.plot(xn[i, 0], xn[i, 1], 'bo', markersize=12) # 蓝色圆圈标记
else:
yn[i] = -1
plt.plot(xn[i, 0], xn[i, 1], 'go', markersize=12) # 绿色圆圈标记
# 感知机
# xn 数据点 N*2的向量
# yn 分类结果 N*1的向量
# MaxIter 训练次数
# 输出 超平面参数y = ax + b最好的分割平面
def perceptron(xn, yn, MaxIter=1000, a=0.01, w=np.zeros(3)):
# N表示xn有多少个变量
N = xn.shape[0]
f = lambda x: np.sign(w[0] * 1 + w[1] * x[0] + w[2] * x[1])
for _ in range(MaxIter):
i = np.random.randint(N)
if (yn[i] != f(xn[i, :])):
w[0] = w[0] + yn[i] * 1 * a
w[1] = w[1] + yn[i] * xn[i, 0] * a
w[2] = w[2] + yn[i] * xn[i, 1] * a
# print(w)
return w
w = perceptron(xn, yn)
print("last ===== ")
print(w)
print(a)
print(b)
bnew = -w[0] / w[2]
anew = -w[1] / w[2]
y = lambda x: anew * x + bnew
# 分割颜色
sep_color = (yn) / 2.0
plt.figure()
figa = plt.gca()
plt.scatter(xn[:, 0], xn[:, 1], c=sep_color.flatten(), s=50)
plt.plot(x, y(x), 'b--', label='感知机分类结果')
plt.plot(x, f(x), 'g', label='原始分类曲线')
plt.title('原始曲线与感知机近似结果比较')
plt.legend()
plt.show()
其中
w[0]是偏置的权重值,w[1]是x的权重值,w[2]是y的权重值
由 x[2]*y + w[1]*x + w[0] = 0
a = -w[0] / w[2]
b = -w[1] / w[2]
即调整后的斜率和偏置