感知机
来源:互联网 发布:缩鼻翼手术多少钱知乎 编辑:程序博客网 时间:2024/05/01 09:49
感知机是二分类线性分类模型, 其输入为实例的特征向量, 输出为实例的类别, 取+1和-1二值。
感知机公式:
感知机的几何解释是,线性方程w*x+b=0 将特征空间划分为正负两个部分:
损失函数
如果训练集是可分的,感知机的学习目的是求得一个能将训练集正实例点和负实例点完全分开的分离超平面。为了找到这样一个平面(或超平面),即确定感知机模型参数w和b,我们采用的是损失函数,同时并将损失函数极小化。
对于损失函数的选择,我们采用的是误分类点到超平面的距离,也就是点到直线的距离:, 其中||w||是L2范数。
对于误分类点(xi,yi)来说:,误分类点到超平面的距离为:,假设所有误分类点集合为M, 那么,所有误分类点到超平面的总距离为:, 由于||w||对超平面的构成不起决定性作用,我们可以等比例的缩放w, b得到相同的超平面,于是我们可以使||w||为1,那么感知机的损失函数就为:。其实 y*(w*x + b)称为函数间隔, 可以相对地表示点x距离超平面的远近。
可以看出,损失函数L(w,b)是非负的。如果没有误分类点,则损失函数的值为0,而且误分类点越少,误分类点距离超平面就越近,损失函数值就越小。同时,损失函数L(w,b)是连续可导函数
学习算法
感知机学习算法是对以下最优化问题的算法:
使用梯度下降法进行优化,损失函数的梯度为:
算法伪代码:
输入:T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N,学习速率为η)输出:w, b;感知机模型f(x)=sign(w·x+b)(1) 初始化w0,b0,权值可以初始化为0或一个很小的随机数(2) 在训练数据集中选取(x_i, y_i)(3) 如果yi(w xi+b)≤0 w = w + ηy_ix_i b = b + ηy_i(4) 转至(2),直至训练集中没有误分类点
Python实现
正样本点:x1=(3,3)T,x2=(4,3)T
负样本点:x1=(1,1)T
求感知机模型f(x)=sign(w⋅x+b)
import copyfrom matplotlib import pyplot as pltfrom matplotlib import animationtraining_set = [[(3, 3), 1], [(4, 3), 1], [(1, 1), -1]]w = [0, 0]b = 0history = []def update(item): """ update parameters using stochastic gradient descent :param item: an item which is classified into wrong class :return: nothing """ global w, b, history w[0] += 1 * item[1] * item[0][0] w[1] += 1 * item[1] * item[0][1] b += 1 * item[1] print w, b history.append([copy.copy(w), b]) # you can uncomment this line to check the process of stochastic gradient descentdef cal(item): """ calculate the functional distance between 'item' an the dicision surface. output yi(w*xi+b). :param item: :return: """ res = 0 for i in range(len(item[0])): res += item[0][i] * w[i] res += b res *= item[1] return resdef check(): """ check if the hyperplane can classify the examples correctly :return: true if it can """ flag = False for item in training_set: if cal(item) <= 0: flag = True update(item) # draw a graph to show the process if not flag: print "RESULT: w: " + str(w) + " b: " + str(b) return flagif __name__ == "__main__": for i in range(1000): if not check(): break # first set up the figure, the axis, and the plot element we want to animate fig = plt.figure() ax = plt.axes(xlim=(0, 2), ylim=(-2, 2)) line, = ax.plot([], [], 'g', lw=2) label = ax.text([], [], '') # initialization function: plot the background of each frame def init(): line.set_data([], []) x, y, x_, y_ = [], [], [], [] for p in training_set: if p[1] > 0: x.append(p[0][0]) y.append(p[0][1]) else: x_.append(p[0][0]) y_.append(p[0][1]) plt.plot(x, y, 'bo', x_, y_, 'rx') plt.axis([-6, 6, -6, 6]) plt.grid(True) plt.xlabel('x') plt.ylabel('y') plt.title('Perceptron Algorithm') return line, label # animation function. this is called sequentially def animate(i): global history, ax, line, label w = history[i][0] b = history[i][1] if w[1] == 0: return line, label x1 = -7 y1 = -(b + w[0] * x1) / w[1] x2 = 7 y2 = -(b + w[0] * x2) / w[1] line.set_data([x1, x2], [y1, y2]) x1 = 0 y1 = -(b + w[0] * x1) / w[1] label.set_text(history[i]) label.set_position([x1, y1]) return line, label # call the animator. blit=true means only re-draw the parts that have changed. print history anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(history), interval=1000, repeat=True, blit=True) plt.show() anim.save('perceptron.gif', fps=2, writer='imagemagick')
可视化:
该算法是收敛的,具体证明过程可参考:《统计学习方法》P31
请其对偶形式本质上是一样的,在此不再多述,想了解的可以参考:《统计学习方法》P33
参考:
[1] 统计学习方法, 李航 著
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- 感知机
- css 属性选择器学习+css3 混合模式+css background
- day1
- nginx+lua+redis防刷,lua代码
- opencv3/C++霍夫圆/直线检测
- Android_黑马视频学习_day04
- 感知机
- echarts -- 使用 formatter 修改鼠标悬浮事件信息
- 浅析前端工程化
- 2017年个人总结-程序员的中年焦虑症
- disruptor源码解读
- 站在巨人的肩膀上
- c++11库 <thread>的基本使用
- 推荐系统之用户行为分析
- Android图片加载框架,Glide