线性回归是在已有数据的基础上,通过建立含有未知参数的线性模型来拟合样本点。通过已有数据确定未知参数后,就可用回归模型来预测其他输入状态下的输出值。
一般地,线性回归分为标准线性回归(Standard LR)和局部加权线性回归(Locally Weighted LR)两种。其区别在于:前者对所有的样本点共享一个权重矩阵,权重矩阵由全局MSE得出;后者每个样本点使用一个权重矩阵,权重矩阵由核函数与MSE共同决定。下面从一个实例考虑二者的区别。
考虑如图1(i)所示的数据集,用标准线性回归直观上并不恰当,似乎用曲线可以拟合得更好,这是全局共享权重矩阵的弊端。如图1(ii)所示,将某个样本点 x i x_i x
i
及其邻域内的点视为一个元集合 A A A,对 A A A进行标准线性回归以得到回归直线 ,将样本中的所有元集合对应的回归直线连接起来,就形成了对整个样本集的拟合。换言之,这是用局部最优拟合全局最优,用线性拟合非线性模型。
局部加权线性回归的核心原理在于如何计算出一个元集合并进行标准线性回归。这里引入的是高斯核函数:
k ( x i , x j ) = e − ( x i − x j ) 2 2 σ 2 k(x_i,x_j)=e^{-\frac{(x_i-x_j)^2}{2\sigma^2}}
k(x
i
,x
j
)=e
−
2σ
2
(x
i
−x
j
)
2
这使得离 x i x_i x
i
近的点对 x i x_i x
i
对应元集合的影响大,离 x i x_i x
i
远的点影响小。对每一个点 x i x_i x
i
都运用高斯核函数计算出一个权重矩阵 W i = d i a g ( w 1 , w 2 , . . . , w m ) W_i=diag(w_1,w_2,...,w_m) W
i
=diag(w
1
,w
2
,...,w
m
) ,此时对于每一个样本点都有一个标准线性回归方程,其代价函数为:
于是对于每个预测值而言都有:
在代码实现层面,下面贴出计算参数的核心代码:
def lwlr_weights(x_Test,xMat,yMat,Gama): #计算权重矩阵并返回theta n = np.shape(xMat)[1] weights = np.eye(n) temp = np.multiply(np.diagonal((xMat-x_Test).T*(xMat-x_Test)).T,weights) weights = np.multiply(np.diagonal(np.exp(-Gama*temp)).T,weights) xWx = xMat*weights*xMat.T if (np.linalg.det(xWx)==0): return "\terror" else: theta = xWx.I*xMat*weights*yMat.T return theta
其中temp与weights的计算通过numpy库中矩阵点乘、提取对角元素等操作避免了显式的for循环。向量化是机器学习中非常重要的节约资源的手段,经验证,本实验200个数据采用矩阵运算只需0.7ms左右完成,而使用for循环则需要3.8ms左右,且此倍率将随着样本扩大而增加。
如图2所示为回归分析的结果,取Gama=1,900,50000进行实验。Gama越大说明高斯核的作用越强,前述元集合越小,拟合程度越高。但过拟合和欠拟合均不具备机器学习提高泛化能力的初衷,因此在一般模型设计时还会对其正则化。