在线性回归中,有时候样本点对待估计点的预测有一定影响,离待估计点越近的点对待估计点的预测影响更大,而距离远的点则影响小点,所以需要引入参数衡量样本点与待估计点的相似度,这个相似度可以作为一个权值,表示对待估计点估计的权有多大,这样就得到局部加权线性回归(Locally weighted linear regression)。
常用高斯相似度定义权值:
ω=similar(x,xi)=e−||x−xi||222σ2
代码实现:
import numpy as np
import matplotlib.pyplot as plt
# 对某一点计算估计值
def lwlr(testPoint, xArr, yArr, k = 1.0):
xMat = mat(xArr); yMat = mat(yArr)
m = shape(xMat)[0]
weights = mat(eye((m)))
for i in range(m):
diffMat = testPoint - xMat[i, :]
weights[i, i] = exp(diffMat * diffMat.T/(-2.0 * k**2)) # 计算权重对角矩阵
xTx = xMat.T * (weights * xMat) # 奇异矩阵不能计算
if linalg.det(xTx) == 0.0:
print('This Matrix is singular, cannot do inverse')
return
theta = xTx.I * (xMat.T * (weights * yMat)) # 计算回归系数
return testPoint * theta
# 对所有点计算估计值
def lwlrTest(testArr, xArr, yArr, k = 1.0):
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i], xArr, yArr, k)
return yHat
if __name__ == "__main__":
N = 100
x = np.linspace(-2, 2, N) + np.random.randn(N)
x = np.sort(x)
y = x**3 - 10*x + np.random.randn(N) #构造数据
xArr = x.reshape((N,1))
yArr = y.reshape((N,1))
yHat = lwlrTest(xArr, xArr, yArr, 0.4)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(xArr, yHat)
ax.scatter(xArr, yArr, s = 2, c = 'red')
plt.show()
当取
σ=0.4
得到下图:
总结:线性回归的参数是有限的,称为有参模型(Parametric model),参数一旦确定,就不会改变了,我们不需要在保留训练集中的训练样本。但局部线性回归因为在任一个待测点都使用逼近法,所以它的参数个数是无穷多个的,该类模型称为无参模型(Non-Parametric model),参数个数大体与样本个数相当,每进行一次预测,就需要重新学习一组,所以在做预测的时候要保留样本,所以虽然该模型的效果比较好,但当训练集的容量较大时,无参模型需要占用更多的存储空间,计算速度也较慢。