一、用线性回归找到最佳拟合直线
回归的目的是预测数值型的目标值,即依据输入写出一个目标值的计算公式。
这个公式就是所谓的回归方程,此处的HorsePower是我们要求的目标值,0.0015和-0.99就是回归方程的回归系数,annualSalary和hourListingToPublicRadio是计算目标值所需要输入的值。
求这些回归系数的过程就是回归。
给定输入X矩阵,回归系数存放在向量W中,求解回归方程,现在已知数据为X和Y,只有回归系数W矩阵未知,所以现在求解回归方程的问题转化为求解系数矩阵W的问题,求解W可通过最小化误差平方和来解决,因为简单的误差累加会使得正差值和负差值相互抵消,所以采用平方误差。
所以回归系数向量W的估计为
注:公式中包含有矩阵的逆计算,因此这个计算方程必须满足矩阵乘积可逆的条件,所以必须在程序中对这一条件进行判断。
标准回归函数和数据导入的函数:
import numpy as np
#数据加载函数
def loadDataSet(filename):
dataArr = []
labesArr = []
#数据集中除了最后一行是目标值外,其他的列都是输入特征值
featNum = len(open(filename).readline().strip().split('\t')) - 1
fp = open(filename)
#遍历文件内容,初始化数据集和目标集
for line in fp.readlines():
#把每行数据中的空格去掉,并且以制表符分割为数组,此时数组中既包含输入特征,也包括要预测的样本目标值
#需要将它们分别加入数据集数组和目标值数组中
curLine = line.strip().split('\t')
lineArr = []
for i in range(featNum):
lineArr.append(float(curLine[i]))
dataArr.append(lineArr)
labesArr.append(float(curLine[-1]))
return dataArr,labesArr
#标准回归函数回归系数求解函数
def standRegres(xArr,yArr):
#将两个数据集转换为矩阵形式
xMat = np.mat(xArr)
#将目标集数组转换为列向量矩阵,保证矩阵运算可以进行
yMat = np.mat(yArr).T
#计算数据矩阵的平方
xtx = xMat.T * xMat
#利用行列式值计算公式计算矩阵行列式值,以得知该矩阵是否可逆
#如果不可逆,立即返回;否则继续计算回归系数向量
if np.linalg.det(xtx) == 0:
print("该矩阵的行列式值为零,其矩阵不可逆")
return
ws = xtx.I * (xMat.T * yMat)
return ws
绘制最佳拟合直线与绘制散点图函数:
#图像绘制函数
def plotFigure_stand(dataArr,labesArr,ws):
import matplotlib.pyplot as plt
#创建绘图对象
fig = plt.figure()
#固定画笔位置
ax = fig.add_subplot(111)
#绘制散点图
# 对训练集进行预测
xMat = np.mat(dataArr)
yMat = np.mat(labesArr)
# 需要对x排序,保证绘图正确
xCopy = np.copy(xMat)
xCopy.sort(0)
yHat = xCopy * ws
ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0])
#绘制计算出的最佳拟合直线
#绘制直线,数据集第一列作为x轴的值,预测值作为y轴的值
ax.plot(xCopy[:,1],yHat)
plt.show()
计算两个两个序列的相关系数,用来衡量寻找到的最佳拟合直线的拟合效果:
#计算预测值和真实值两个序列的相关系数
def calCoef(dataArr,labesArr,ws):
xMat = np.mat(dataArr)
yMat = np.mat(labesArr)
yHat = xMat * ws
#利用函数计算两个行向量的相关系数
corrNum = np.corrcoef(yHat.T, yMat)
return corrNum
二、局部加权线性回归
线性回归可能会出现欠拟合现象,因为它求的是具有最小均方误差的无偏估计,所以有时候需要引入一些偏差来降低预测的均方误差。其中一个方法就是局部加权线性回归(LWLR)。在该算法中,我们给待预测点附近的点赋予一定的权重,在这个附近点自己中基于最小均方差来进行普通回归。
该算法求解W的公式如下:
LWLR使用高斯核函数对附近点赋权重:
注:此处的权重矩阵是一个对称矩阵,这样才能保证在矩阵运算中给每个附近样本附上权重。临近点距离预测点越近,其样本权重越大;距离越远,权重越小。
局部加权线性回归函数:
#局部加权线性回归预测函数(对于单个测试样本点),k为用户自定义参数,是计算权重的高斯核函数的参数,影响每个样本的权重
def lwlr(testPoint, xArr, yArr, k = 1.0):
xMat = np.mat(xArr)
yMat = np.mat(yArr).T
#获得测试样本附近的样本点个数
m = np.shape(xMat)[0]
#创建临近点权重的对角矩阵,初始化元素为1
weightsMat = np.mat(np.eye((m)))
#遍历整个数据集,根据高斯核函数更新样本点权重,距离测试点越近的样本点的权重越大