李航统计学习方法——算法1感知机学习
介绍之前先讲两个概念
转载请注明出处:http://www.cnblogs.com/bethansy/p/7235133.html
一、回归
1.定义: 回归属于监督学习,用于预测输入变量和输出变量之间的关系。 回归模型表示从输入到输出变量之间的映射的函数,回归问题的学习等于函数拟合:选择一条函数曲线使其很好滴拟合已知数据且很好地预测未知数据。
2.回归分类: 回归问题按照输入变量的个数,分为一元回归和多元回归,按照输入变量和输出变量之间的关系类型即模型的类型,分为线性回归和非线性回归。
3. 损失函数 回归最常用的损失函数是平方损失函数,在此情况下,回归问题可以由最著名的最小二乘法求解
4. 应用 回归可用于商务领域,作为市场趋势预测、产品质量管理、客户满意度调查、投资风险分析还有股价预测。例如已知某公司过去不同时间点的市场上股票价格,以及在各个时间点影响该股票价格的信息(营业额、利润),目标是从过去的数据学习一个模型,使他可以基于当前的信息预测该公司下一个时间点的股票价格。
二、分类
1.定义 分类是监督学习的核心问题,在监督学习中,当输出变量Y取有限个离散值时,预测问题便成为分类问题。
2.分类器(classifier) 监督学习从数据中学习一个分类模型或分类决策函数,称为分类器。分类器对新的输入进行输出预测, 成为分类(classification)
3.准确率 评价分类器性能的指标一般是分类准确率,其定义是:对于给定的测试数据集,分类器正确分类的样本数与总样本数之比。对于二类分类问题常用的评价指标是精确率和召回率
一、感知机概念
输入数据T={(x1,y1),(x2,y2),...,(xN,yN)}, 其中yi={1,-1}
感知机是根据输入实例的特征向量x对其进行二类分类的线性分类模型,函数形式如下:
f(x)=sign(wx+b) ----公式1
其中sign(x)=1,当x>=0;sign(x)=-1,当x<0
感知机的几何解释:线性方程 wx+b=0 对应特征空间中的一个超平面S,这个超平面将特征空间划分为两部分,位于两部分的点(特征向量)分别为正、负两类。
二、学习策略
损失函数: 感知机的学习策略是极小化损失函数,损失函数是使得误分类点距离超平面距离之和最小。
点到超平面距离:其中任一点x0距离超平面S的距离:(wx0+b)/||w||---公式2,此处易和任一点到直线ax+by+c上的距离混淆。
点p(x0,y0)到直线的距离d=|ax0+by0+c|/(a2+b2)1/2---公式3,点到超平面距离公式是一个通用公式,对于二维直线,公式2的展开式应该是(w1x1+w2x2+b)/||(w1,w2)||,此时就和公式3一致了
对于误分类数据来说,-yi(wxi+b)>0,那么那么所有误分类点到超平面S的总距离可写成:
minL(w,b)= -sigam(yi(wxi+b)) 其中xi属于M ,M是误分类点集合
梯度下降原则:wt=wt-1+xy
bt=bt-1+y
其中w0和b0为初始值,在算法进行前就给出,一般都取0,不停修改w和b值,直到所有点都分类正确为止。其中x有多少维度,那么w就有多少维度
三、感知机学习算法
原始算法中,首先任意选取一个超平面,然后用梯度下降法不断极小化目标函数,在这个过程中一次随机选取一个误分类点使其梯度下降
(1)选取初始值w0,b0
(2)在训练集中选取数据(xi,yi)
(3)如果yi(wxi+b)<=0
w=w+a*yixi
b=b+a*yi
其中a是学习速率,在0到1之间
(4)转至2,直至训练集中没有误分类点
四、感知机学习算法的收敛性
当训练数据集可分(正实例点集构成的凸壳与负实例点集所构成的凸壳互不相交),感知机学习算法是收敛的。 没看懂算法证明
五、注意
感知机学习算法存在多解,依赖初始值的选择,也依赖迭代过程中误分类点选择顺序
这个博主打算将李航博士书中的算法都实现一遍
这篇博文很好地讲了感知机原理,并附有代码
自己写的代码
# coding=utf-8 import random import numpy as np import pandas as pd # import time def train(trainset, trainLabel): b = 0 feature_length = 2 study_step = 1 nochange_count = 0 nochange_upper_limit = 10000 # 此处w必须要和训练数据x的形式对应,x是1乘3维,那么w也必须是1*3的行向量 w = np.zeros((1, feature_length)) trainsize = len(trainset) while True: count = 0 nochange_count += 1 if nochange_count > nochange_upper_limit: break for i in range(trainsize): result = trainLabel[i]*(w * trainset[i] + b) if result.any() <= 0: w += study_step * trainLabel[i] * trainset[i] b += study_step * trainLabel[i] count += 1 if count == 0: break return w, b if __name__ == '__main__': # raw_data = pd.read_csv('yy\\ONE-Preceptron\\data\\train.csv') raw_data = pd.read_csv('D:\\Python27\\yy\\ONE-Preceptron\\data\\train.csv') label = pd.read_csv('D:\\Python27\\yy\\ONE-Preceptron\\data\\label.csv') # 除去raw_data表头的内容 data = raw_data.values label = label.values # 选取数据的2/3作为训练集,1/3作为测试集 trainset = data[[0, 1, 2], :] trainLabel = label[[0, 1, 2], :] test = data[[1, 2], :] testLabel = label[[1, 2], :] w, b = train(trainset, trainLabel) # print 'Start predicting' # test_predict = Predict(test, w, b) # time_4 = time.time() # print 'predicting cost ', time_4 - time_3, ' second', '\n' # score = accuracy_score(test_labels, test_predict) # print "The accruacy socre is ", score
上面的代码运行一直有问题,问题出在第一个if 判断语句,如果result数据中有小于等于0的数(result<=0)那么就执行w和b、count的赋值语句,否则就跳过这三行代码继而执行if count==0语句,但是运行时会报错ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(),应该是说result不止一个数据,不能直接用,然后我就求了一次和,result=sum(result) 再写if result<=0同样报相同的错误,此时说明求和过后的result仍旧不是一个数,再求了一次和,变成下面这个代码后就可以正常运行了,且所得结果也正确。由于自己基础没有打牢,对于np.array([3,3])就可以直接求和,但是result数据为啥就不行,程序中的result长这样[[0. 0.]],目前并不清楚这个是个什么玩意,而且还不会手动输入多行多列的矩阵。
下面给出的代码虽然可以正确运行,但是并不完善,只能用来训练数据得到感知机模型的参数w和b,还不能够预测,后期再补
# coding=utf-8 import random import numpy as np import pandas as pd # import time def train(trainset, trainLabel): b = 0 feature_length = 2 study_step = 1 nochange_count = 0 nochange_upper_limit = 10000 # 此处w必须要和训练数据x的形式对应,x是1乘3维,那么w也必须是1*3的行向量 w = np.zeros((1, feature_length)) trainsize = len(trainset) while True: count = 0 nochange_count += 1 if nochange_count > nochange_upper_limit: break for i in range(trainsize): result = trainLabel[i]*(w * trainset[i] + b) a = sum(result) a = sum(a) if a <= 0: w += study_step * trainLabel[i] * trainset[i] b += study_step * trainLabel[i] count += 1 if count == 0: break return w, b if __name__ == '__main__': # raw_data = pd.read_csv('yy\\ONE-Preceptron\\data\\train.csv') raw_data = pd.read_csv('D:\\Python27\\yy\\ONE-Preceptron\\data\\train.csv') label = pd.read_csv('D:\\Python27\\yy\\ONE-Preceptron\\data\\label.csv') # 除去raw_data表头的内容 data = raw_data.values label = label.values # 选取数据的2/3作为训练集,1/3作为测试集 trainset = data[[0, 1, 2], :] trainLabel = label[[0, 1, 2], :] test = data[[1, 2], :] testLabel = label[[1, 2], :] w, b = train(trainset, trainLabel) print w print b # print 'Start predicting' # test_predict = Predict(test, w, b) # time_4 = time.time() # print 'predicting cost ', time_4 - time_3, ' second', '\n' # score = accuracy_score(test_labels, test_predict) # print "The accruacy socre is ", score