数据分析——局部加权线性回归
局部加权线性回归(Locally Weighted Linear Regression,LWLR),针对于线性回归存在的欠 拟合现象,可以引入一些偏差得到局部加权线性回归对算法进行优化。
在该算法中,给待测 点附近的每个点赋予一定的权重,进而在所建立的子集上进行给予最小均方差来进行普通的 回归,分析可得回归系数 w 可表示为: w = (xTWx)-1xTWy,其中 W 为每个数据点赋予的权重,那么怎样求权重呢,核函数可以 看成是求解点与点之间的相似度,在此可以采用核函数,相应的根据预测点与附近点之间的 相似程度赋予一定的权重,在此选用最常用的高斯核,则权重可以表示为: w(i,i) = exp(|x(i) - x| / -2k2) 其中 K 为宽度参数,至于此参数的取值,目前仍没有一个确切的标准,只有一个范围的 描述,所以在算法的应用中,可以采用不同的取值分别调试,进而选取最好的结果。
python 编程实现
结合上述的分析,采用 python 编程实现,代码如下:
代码语言:javascript复制def lwlr(testPoint,xArr,yArr,k):
xMat = mat(xArr)
yMat = mat(yArr).T
m = shape(xMat)[0]
weights = mat(eye((m))) for i in range(m): weights[i,i] = exp((testPoint - xMat[i,:])*(testPoint - xMat[i,:]).T / (-2.0*k**2))
xTx = xMat.T * (weights * xMat)
if linalg.det(xTx) == 0:
print "输入有误"
return
ws = xTx.I * xMat.T * weights * yMat
return testPoint * ws #为数据点中的每个数据调用
lwlr def lwlrTest(testArr,xArr,yArr,k):
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
return yHat 结合上述分析,我们可以选取不同的 k 值分别求得结果,进而采用 Matplotlib 绘图直观 的表示,在此,分别选取 k = 1,0.01,0.002,代码如下: #test x,y = loadData("ex0.txt") a = lwlr(x[0],x,y,0.002) b = lwlrTest(x,x,y,0.002)
#采用 matplotlib 绘制图像
xMat = mat(x) srtInd = xMat[:,1].argsort(0)#按升序排序,返回下标
xSort = xMat[srtInd][:,0,:]#将 xMat 按照升序排列
fig = plt.figure() ax = fig.add_subplot(111) ax.plot(xSort[:,1],b[srtInd]) ax.scatter(xMat[:,1].flatten().A[0],mat(y).T.flatten().A[0],s = 2,c = 'red') plt.show()
最终结果分别如下,依次为 k = 1,0.01,0.002 对应的结果:
可以看出,当 k = 1 时,结果和线性回归使用最小二乘法的结果相似,而 k=0.001 时噪 声太多,属于过拟合的情况,相比之下,k = 0.01 得到的结果更理想。虽然 LWLR 得到了较为 理想的结果,但是此种方法的缺点是在对每个点进行预测时都必须遍历整个数据集,这样无 疑是增加了工作量,并且该方法中的的宽度参数的取值对于结果的影响也是蛮大的。同时,当数据的特征比样本点还多当然是用线性回归和之前的方法是不能实现的,当特征比样本点 还多时,表明输入的矩阵 X 不是一个满秩矩阵,在计算(XTX)-1 时会出错。