1、方法论
局部加权线性回归(Local Weights Linear Regression)也是一种线性回归,不同的是,普通线性回归是全局线性回归,使用全部的样本计算回归系数。而局部加权线性回归,通过引入权值(核函数),在预测的时候,只使用与测试点相近的部分样本来计算回归系数。
值得一提,该方法与kNN思想类似,都是用最近的若干样本点来做。
比如这样的曲线,用简单线性回归可以得到一条与样本具有最小均方差的直线,但这条直线显然不能代表图中数据所蕴含的细节规律,为了挖掘数据潜在特性,这里引入核函数,或者说权值,每次预测前都要计算一次回归系数,只使用测试点附件的部分样本点来进行计算。核函数如下
这里分子项应该是平方(欧式距离),而不是绝对值,书中有误。其中w是一个对角方阵,方阵大小与x的样本数量相等,显然,这是一个均值为x,标准差为k的高斯函数,故与测试样本x越近的样本点,能够得到更高的权重,而远的点则权重很小。
标准差k的选择可以遵循2sigma或者3sigma原则来。
根据上面的理论,下面对线性回归的目标函数进行修改:
注意w(i)是w(i,i),计算每一个样本点时候都要计算一次w矩阵
求导并另导数为零可以得到:
2、Python实现
有了上面的公式,python实现就很容易了,直接贴代码:
# 局部加权线性回归 # 增加了核函数,使用高斯核函数,相当于只用于当前数据点相近的部分数据计算回归系数 def linear_regression_local_weights(test_point, x, y, k): m = x.shape[0] weights = np.mat(np.eye(m)) for i in range(m): s = np.sum((test_point - x[i]) * (test_point - x[i]).T) dif = np.sqrt(s) weights[i, i] = np.exp(dif / (-2.0 * k**2)) xtx = x.T * weights * x if np.linalg.det(xtx) == 0: print("the matrix is singular, cannot do inverse") return 0 w = xtx.I * x.T * weights * y # (2,2)*(2,n)*(n,1)=(2,1) return test_point * w # 局部加权线性回归,每次都要去计算weights和w,速度龟慢 # 200个数据也要7,8s def lrlw_test(): xd = np.linspace(0, 1, 200) yd = xd * 2 + 0.5 + 0.1*np.sin(xd * 50) + np.random.normal(0, 0.03, xd.shape[0]) y_org = xd * 2 + 0.5 + 0.1*np.sin(xd * 50) y = yd.reshape(xd.shape[0], 1) y = np.mat(y) x = np.c_[xd, np.ones(xd.shape[0])] # 在最后一列全部添加1,用来增加w0或者说偏置项b x = np.mat(x) y_predict = np.zeros(xd.shape[0]) t1 = time.clock() # datetime.datetime.now() for i in range(xd.shape[0]): y_predict[i] = linear_regression_local_weights(x[i], x, y, 0.08) # 0.08可以得到0.999的相关性 print(time.clock() - t1, "s") print(np.corrcoef(y_org, y_predict)) plt.scatter(xd, yd, marker=".", color="b") plt.plot(xd, y_predict, "r") plt.show()实现方法和用公式计算最小二乘差不多。只是速度太慢了,每次都要计算一次核函数权值,每次都要计算一次回归系数,500个样本点它给我跑到5,6秒钟去了。
200个样本点,最后运行效果:
1.3961943469164886 s
[[ 1. 0.99924515]
[ 0.99924515 1. ]]
小结一下:
优点:用Python实现简单,容易理解,应该可以拟合任意的连续曲线
缺点:每次都要计算权值,效率很低
参考链接:
https://blog.csdn.net/gadwgdsk/article/details/79769206
https://blog.csdn.net/z_feng12489/article/details/80213739
https://blog.csdn.net/lanchunhui/article/details/88261494