1.简介
本文主要参考斯坦福大学机器学习视频中第一节关于回归的讲解,在复习知识点的同时最后给出了一个具体的应用的实例,具体实例可以参考《机器学习实战》一书中的第五章。
2.线性回归
在线性回归中,假设特征与结果之间满足线性关系,其中每个特征对结果的影响关系的强弱可以通过特征前面的参数进行控制
假设我们用x1,x2......xn来表示特征里面的分量,我们可以得到这样的一个特征估计函数:h(x) = θ0 + θ1x1 + θ2x2 在这里我们将θ作为特征参数,如果领X0=1,则上面的表达式可以表示为:
接下来就需要对h函数进行一个评估,确保函数的性能是最好的,也就是要确定θ的值,接下来定义函数:
3.梯度下降算法
我们知道,θ需要在J(θ)最小的情况下才可以确定,所以问题可以归结为求最小值的问题,使用梯度下降算法可以求得局部的最小值,算法的具体流程如下:
1.首先对θ赋初始值,初始值可以使随机的,一般选择0:
2.改变θ的值,是的J(θ)按照梯度下降的方向进行减小
梯度方向可以通过求偏导数实现。最终的求取结果为:
其中可以采取批梯度下降算法,或者采取随机梯度下降算法。批梯度下降算法需要每次对所有的样本进行一个扫描,随机梯度下降算法每次对一个样本进行扫描并更新特征参数θ,批梯度下降算法可以一直保持收敛,而随机梯度下降算法可能不断的杂收敛处徘徊。
4.Logistic回归
首先介绍Sigmoid()函数:
通过函数的形式可以知道当z等于0时,函数值为1/2,随着z值的不断的增大,函数值一直接近于0,随着z值的不断减小,函数值不断的接近于0,当横坐标的刻度足够大时候,Sigmod()函数更像一个阶跃函数。所以为了实现Logistics分类器,我们可以在每个特征值上面都乘以一个回归系数,然后将所有的结果值相加,将这个总和带入到sigmoid 函数中,进而得到一个范围在0-1之间的数,任何大于0.5的值都可以分为1类,任何小于0.5的值都可以化为0类。接下来的任务就是找到回归系数θ。
5.利用梯度上升法求解最佳参数
首先定义读取文本的函数,将文件中的数据导入到矩阵当中:
#从文本文件中将数据集导入到矩阵当中
def LoadData():
dataMat=[];labelMat=[] #定义列表
fr=open('testSet.txt') #代开文件
for line in fr.readlines(): #循环读取文件中的数据
arr=line.strip().split()
dataMat.append([1.0,float(arr[0]),float(arr[1])]) #将x0的值都设置为1.0
labelMat.append(int(arr[2]))
return dataMat,labelMat #返回列表
接下来定义sigmoid函数:
#定义sigmoid函数
def sigmoid(x):
return 1.0/(1+exp(-x))
定义梯度上升算法,返回最后优化所得的系数:
#定义梯度上升函数求解最大值
def gradAScent(dataMat,labelMat):
dataM=mat(dataMat) #将数据集矩阵转换为numpy的矩阵
labelM=mat(labelMat).transpose() #转换成列向量,即求矩阵的转置
m,n=shape(dataM)
alpha=0.001 #定义每次上升的步长
cycles=500 #定义循环迭代的次数
weights=ones((n,1)) #定义初始化的参数w都为1
for k in range(cycles):
h=sigmoid(dataM*weights)
error= labelM - h #真实类别和预测类别之间的差值
weights=weights+alpha*dataM.transpose()*error #更新参数的系数
return weights #返回系数
接下来由求得的系数作出决策边界图:
#作出最佳的拟合直线
def plotbest(wei):
import matplotlib.pyplot as plt
weights=wei
dataMat,labelMat=LoadData()
dataArr=array(dataMat)
n=shape(dataArr)[0]
xcord1=[]; ycord1=[]
xcord2=[];ycord2=[]
for i in range(n):
if int(labelMat[i]==1):
xcord1.append(dataArr[i,1])
ycord1.append(dataArr[i,2])
else:
xcord2.append(dataArr[i,1])
ycord2.append(dataArr[i,2])
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(xcord1,ycord1,s=30,c='red',marker='s')
ax.scatter(xcord2,ycord2,s=30,c='green')
x=arange(-3.0,3.0,0.1)
y=(-weights[0]-weights[1]*x)/weights[2]
ax.plot(x,y)
plt.xlabel('X1');plt.ylabel('X2')
plt.show()
所得的效果如下所示: