线性回归的python实现

基本的线性回归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
def loadDataSet(Filename):
fr=open(Filename)
numFeat=len(fr.readline().split('\t'))-1
dataMat=[]
labelMat=[]
for line in fr.readlines():
lineArr=[]
curline=line.strip().split('\t')
for i in range(numFeat):
lineArr.append(float(curline[i]))
dataMat.append(lineArr)
labelMat.append(float(curline[-1]))
return dataMat,labelMat

def standRegress(xArr,yArr):
xMat=np.mat(xArr);yMat=np.mat(yArr).T
xTx=xMat.T*xMat
if np.linalg.det(xTx)==0:
print 'the matrix is singular,can not reverse'
return
ws=xTx.I*(xMat.T*yMat)
return ws

具体理论之前都已经写过,简单的说就是将平方误差 最小化的过程。将上式向量化,用矩阵表示为 ,对求导得到 ,令其等于0,解出w

值得注意的是代码中要先验证 是否可逆

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#-*-coding:utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

import regression

xArr,yArr=regression.loadDataSet('ex0.txt')
ws=regression.standRegress(xArr,yArr)

xMat=np.mat(xArr)
yMat=np.mat(yArr)
#yHat=xMat*ws

fig=plt.figure()
ax=fig.add_subplot(111)#111指将画布分为x行,y列,在第z个子图上
ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0]) #降维,注意xMat里有个逗号

#先将点升序排序,否则出现混乱
xCopy=xMat.copy()
xCopy.sort(0)
yHat=xCopy*ws
ax.plot(xCopy[:,1],yHat)
plt.show()

image_1bmo35a8b1fbco4vcjf827lj19.png-39.8kB

局部加权的线性回归(Locally Weighed Liner Regression,LWLR)

该方法用来避免欠拟合问题,所以通过引入一些偏差来降低方差

回归系数公式

其中W是一个矩阵,用来给每个数据点赋予权重
LWLR使用核(与SVM类似)来赋予权重。
常用的是高斯核

这样就构建了一个只含对角元素的权重矩阵%并且点x与x(i)越近,w(i,i)将 会 越 大 。


述公式包含一个需要用户指定的参数、 它决定了对附近的点赋予多大的权重,这也是使用LWLR时唯一需要考虑的参数,在图8-4中可以看到参数k与权重的关系。

image_1bmo6hgv8j2v1jr81qgv14mf1rqq9.png-128.5kB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def lwlr(testPoint,xArr,yArr,k=1.0):
xMat=np.mat(xArr);yMat=np.mat(yArr).T
m=np.shape(xMat)[0]
weights=np.mat(np.eye(m))
for j in range(m):
diffMat=testPoint-xMat[j,:]
weights[j,j]=np.exp(diffMat*diffMat.T/(-2.0*k**2))
xTx=xMat.T*(weights*xMat)
if np.linalg.det(xTx)==0.0:
print "This matrix is singular,cannot do inverse"
return
ws=xTx.I*((weights*yMat))
return testPoint*ws

def lwlrTest(testArr,xArr,yArr,k=1.0):
m=np.shape(testArr)[0]
yHat=np.zeros(m)
for i in range(m):
yHat[i]=lwlr(testArr[i],xArr,yArr,k)
return yHat

该程序的作用给定空间中的任意一点,计算出对应的预测值yHat。,读入数 据 并创建所需矩阵,之后创建对角权重矩阵weightsO.权重矩阵是一个方阵,阶数等于样本点个数。也就是说,该矩阵为每个样本点初始化了一个权重。接着,算法将遍历数据集,计算每个样本点对应的权重值:随着样本点与待预测
点距离的递增,权重将以指数级衰减0 。输人参数k控制衰减的速度。与之前的函数standRegress()一样,在权重矩阵计算完毕后,就可以得到对回归系数呢的一个估计。

运行程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#-*-coding:utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

import regression

xArr,yArr=regression.loadDataSet('ex0.txt')

t=regression.lwlr(xArr[0],xArr,yArr,1.0)
xMat=np.mat(xArr)
srtInd=xMat[:,1].argsort(0)
xSort=xMat[srtInd][:,0,:]
yHat=regression.lwlrTest(xArr,xArr,yArr,0.003)

fig=plt.figure()
ax=fig.add_subplot(111)#111指将画布分为x行,y列,在第z个子图上

ax.plot(xSort[:,1],yHat[srtInd])
ax.scatter(xMat[:,1].flatten().A[0],np.mat(yArr).T.flatten().A[0],s=2,c='red') #降维,注意xMat里有个逗号
plt.show()

k=0.003

image_1bn0h4cqh1pgh1i331ci28fb1g59.png-29.8kB

k=0.01

image_1bn0h9qck9kr2lj15c91eee16gk1g.png-28.2kB

k=0.1

image_1bn0h5tcdjqc2nv12b27cgedcm.png-26.7kB

k=1

image_1bn0h6qfn2ei1unmomk1ukgqrt13.png-28.4kB