热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

统计学习方法之感知机python代码实现

感知机是二分类线性模型,其输入为实例的特征向量,输出为实例的类别,取1和-1。根据《统计学习方法》第2章,用python实

感知机是二分类线性模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1。

根据《统计学习方法》第2章,用python实现感知机。

import numpy as np
import matplotlib.pyplot as pltclass Perceptron:def __init__(self, dim):""" 初始化权重 w b 以及x特征的维度dim"""self.w &#61; np.random.random((dim,))self.b &#61; np.random.rand()self.dim &#61; dimdef f(self, x):""" w * x &#43; b"""return np.dot(self.w, x.T) &#43; self.bdef gw(self, x, y):""" w梯度 """return x * ydef gb(self, y):""" b梯度"""return ydef train_2(self, xs, ys, alpha&#61;1, max_step&#61;1000):"""学习算法的对偶形式"""n &#61; len(xs)matrix &#61; np.zeros((n,n),dtype&#61;int)for i in range(n):for j in range(n):matrix[i][j] &#61; np.dot(xs[i],xs[j])print("matrix:", matrix)a, b &#61; [0]*n, 0step &#61; 1error &#61; float("inf")while error and step < max_step:print("step: {}, error: {}".format(step, error))error &#61; 0for i,(x, y) in enumerate(zip(xs, ys)):sum_ &#61; bfor j in range(n):sum_ &#43;&#61; a[j]*ys[j]*matrix[j][i]if y*sum_ <&#61; 0:a[i] &#61; a[i] &#43; alphab &#43;&#61; alpha * yerror &#43;&#61; 1step &#43;&#61; 1self.w &#61; sum(a[i]*xs[i]*ys[i] for i in range(n))self.b &#61; bif step >&#61; max_step:print("max_step limit")else:print("successfully learn")print("w: {} b: {}".format(self.w, self.b))def train(self, xs, ys, alpha&#61;0.1, max_step&#61;1000):"""学习算法:param xs: 输入样本特征:param ys: 样本分类:param alpha: 学习率:param max_step: 最大迭代伦次:return:"""# 输入数据维度要等于指定维度(画图只能是二维)if xs.shape[1] !&#61; self.dim:raise ValueError("x sample must {} dim".format(self.dim))# 初始化图fig &#61; self.figure_init(xs, ys)error &#61; float("inf")step &#61; 1while error and step < max_step:print("step: {}, error: {}".format(step, error))error &#61; 0for x, y in zip(xs, ys):if self.f(x) * y <&#61; 0:self.w &#43;&#61; alpha * self.gw(x, y)self.b &#43;&#61; alpha * self.gb(y)self.figure_update(fig) # 更新图error &#43;&#61; 1step &#43;&#61; 1if step >&#61; max_step:print("max_step limit")else:print("successfully learn")print("w: {} b: {}".format(self.w, self.b))# 关闭交互模式plt.ioff()# 图形显示plt.show()def figure_init(self, xs, ys):fig &#61; plt.figure(figsize&#61;(8, 6), dpi&#61;80)ax &#61; fig.add_subplot(1, 1, 1)# 设定标题等plt.title("Perceptron")plt.grid(True)# 设置X轴plt.xlabel("x(1)")plt.xlim(-10, 10)# 设置Y轴plt.ylabel("x(2)")plt.ylim(-10, 10)# 画点for x_, y_ in zip(xs, ys):if y_ &#61;&#61; 1:ax.plot(x_[0], x_[1], "ro")else:ax.plot(x_[0], x_[1], "go")# 生成超平面 w1 * x1 &#43; w2 * x2 &#43; b &#61; 0&#xff0c;随机取两个x1&#xff0c;计算x2连起来x1 &#61; np.linspace(-10, 10, 2, endpoint&#61;True)x2 &#61; (- self.b - self.w[0] * x1) / self.w[1]# 画直线lines &#61; ax.plot(x1, x2, "b-", linewidth&#61;2.0, label&#61;"hyperplane")# 设置图例位置,loc可以为[upper, lower, left, right, center]ax.legend(loc&#61;"upper left", shadow&#61;True)# 暂停plt.pause(0.5)ax.lines.remove(lines[0])# 打开交互模式plt.ion()return axdef figure_update(self, ax):"""画图程序&#xff0c;每更新一次权重&#xff0c;调用一次"""# 生成超平面 w1 * x1 &#43; w2 * x2 &#43; b &#61; 0&#xff0c;随机取两个x1&#xff0c;计算x2连起来x1 &#61; np.linspace(-10, 10, 2, endpoint&#61;True)x2 &#61; (- self.b - self.w[0]*x1)/self.w[1]# 更新直线lines &#61; ax.plot(x1, x2, "b-", linewidth&#61;2.0, label&#61;"hyperplane")# 暂停plt.pause(0.5)# 删掉直线ax.lines.remove(lines[0])p &#61; Perceptron(2)
x_data &#61; np.array([[3, 3], [4, 3], [1, 1]])
y_data &#61; np.array([1, 1, -1])
p.train(x_data, y_data)
# p.train_2(x_data, y_data)

其中&#xff0c;train函数是学习算法的原始形式&#xff0c;train_2是学习算法的对偶形式。其中error代表误分类的个数&#xff0c;简单的逻辑就是&#xff0c;当误分类的个数为0或者超出最大学习轮次则停止学习。

另外&#xff0c;figrue_init 和 figure_update函数则是在训练过程的图形展示。

推荐阅读
author-avatar
2369698942_813453_754
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有