视频学习地址
https://www.imooc.com/video/17903/0
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)
# 随机产生50个 0到1之间的数组
x = np.linspace(0,1)
# print(xn)
# print(x)
# print(type(xn))
# print(type(x))
a = np.random.rand() # 随机生成一个0~1之间的数字
b = np.random.rand()
# 随机生成一条直线
# lambda作为一个表达式,定义了一个匿名函数 相当于
# def g(x):
# return a*x+b
f = lambda m:a*m+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()
结果图: