局部加权线性回归

来源:互联网 发布:淘宝直播端口 编辑:程序博客网 时间:2024/05/01 10:52

  线性回归的一个问题是可能出现欠拟合现象。显而易见,模型欠拟合就不能取得好的预测效果,如下图,线性拟合并不能挖掘出数据的一些潜在规律。

这里写图片描述

  一个常见的解决方法是局部加权回归。该算法的思想是给待预测点附近的每一个点赋予一定的权重(离待预测点越近权重越大,越远权重越小,即以待预测点附近点的一个子集来进行普通的线性回归)

  普通线性回归与局部加权线性回归的区别在于,普通线性回归是选择合适的参数θ最小化i(y(i)θTx(i));而局部加权回归则是要最小化iw(i)(y(i)θTx(i))w即为权重函数,需要满足前面提到的条件,最常用的函数形式为高斯型:

w(i)=exp((x(i)x)22k2)

该算法解出的回归系数形式为:

w=(XTWX)1XTWY

  在采用上述高斯型权重函数前提下,W是一个对角矩阵。函数中K是一个需要用户指定的参数,它决定了对附近的点赋予多大的权重。

示例:

import numpy as npimport matplotlib.pyplot as pltdef loadData(fileName):    numFeat = len(open(fileName).readline().split('\t')) - 1    x = []    y = []    ifs = open(fileName)    for line in ifs.readlines():        lineArr = []        curLine = line.strip().split('\t')        for i in range(numFeat):            lineArr.append(float(curLine[i]))        x.append(lineArr)        y.append(float(curLine[-1]))    return x,yx,y = loadData('ex0.txt')K = [1.0, 0.01, 0.003]subplot = [311, 312, 313]fig = plt.figure(figsize=(10,15),dpi=80)for index in range(len(K)):    m = len(x)    yHat = np.zeros(m)    for i in range(m):        curExp = x[i]        xMat = np.mat(x)        yMat = np.mat(y).T        weights = np.mat(np.eye(m))        for j in range(m):            diffMat = curExp - xMat[j,:]            k = K[index]            weights[j,j] = np.exp(diffMat * diffMat.T/(-2*k*k))        ws = (xMat.T * weights * xMat).I * xMat.T * weights * yMat        yHat[i] = curExp * ws    print yHat[0]    plt.subplot(subplot[index])    plt.scatter(xMat[:,1].flatten().A[0],yMat[:,0].flatten().A[0],s=2,c='red')    sortIndex = xMat[:,1].argsort(0)    xSort = xMat[sortIndex][:,0,:]    plt.plot(xSort[:,1].flatten().A[0],yHat[sortIndex])plt.show()

当采用不同的K时,对拟合产生的影响如下图所示:

这里写图片描述

  k=1.0时权重很大,即将所有数据点权重视为相同,此时就与普通的线性回归一致。k=0.01时得到了很好的效果,挖掘出了数据的潜在规律。k=0.003时又引入了过多的噪声,拟合的效果过于贴近。也就是说,k=1时欠拟合了,而k=0.003时又过拟合了。

  局部加权回归也存在一个问题,即增加了计算量,因为它对每个点做预测时都必须使用整个数据集。

0 0