什么是回归?以公式为例,计算男生能找到女朋友的概率:$$P=0.4\astproperty+0.3\astappearance+0.3\astheight$$这意味着概率必须结合三个因素来判断:属性、外貌、身高,其中属性也是最重要的因素。这个公式可以称为回归方程,其中0.4和0.3也称为回归系数。一般来说,回归系数是未知的。通过输入数据得到回归系数的过程就是回归。得到回归系数后,可以通过公式得到最终的预测值。这里给出的例子属于线性回归,还有一种更复杂的回归形式——非线性回归。本文仅介绍线性回归的相关知识。LinearRegression回归系数推导线性回归(LR)可??以分为简单线性回归和多元线性回归,也就是我们平时接触的线性方程组和多元线性方程组。两者之间的主要区别在于未知项目的数量。为了便于理解,这里主要以线性回归为例。一元线性方程的公式大家应该很熟悉了:$$y=wx+b$$如果输入数据存放在矩阵X中,回归系数全部存放在向量$\omega$中,那么矩阵可以得到形式表达式:$$y=X^T\omega$$现在的问题是如何找到$\omega$,我们已经知道如何衡量一个分类器的性能,回归模型的性能是通常用“均方误差”来衡量,我们可以用这个公式求出误差最小时的$\omega$,这里的误差指的是预测值和真实值之间的差值。均方误差的表示如下:$$E=\sum_{i=0}^m(y_i-x_i^T\omega)^2$$可以转化为矩阵形式:$$E=(y-X\omega)^T(y-X\omega)$$由$\omega$推导得到如下公式,令其等于0:$$2X^T(X\omega-y)=0$$且最后求解$\omega$omega$如下:$$\omega^\ast=(X^TX)^{-1}X^Ty$$可以看到这里涉及到矩阵求逆,所以这个公式只适用在可逆矩阵中,也就是说,只有当$X^TX$是满秩矩阵时,上式才成立。矩阵中非零行的个数定义为矩阵的秩,记为R(A)。对于矩阵$A_{n\timesn}$,若R(A)=n,则称A为满秩矩阵。线性拟合现在有一个像上面这样的数据集,按照上面提到的方法计算出最佳拟合直线的回归系数,就可以得到这个数据集的回归曲线。这部分代码如下:defstandRegres(xMat,yMat):#根据公式计算回归系数xTx=xMat.T*xMatifnp.linalg.det(xTx)==0.0:print("The矩阵是奇异矩阵,不能求逆")returnws=xTx.I*(xMat.T*yMat)returnwsdefplotRegression():xMat,yMat=loadDataSet('regression_data.txt')ws=standRegres(xMat,yMat)#计算回归系数xCopy=xMat.copy()#复制一个xMat矩阵xCopy.sort(0)#排序xCopy方便绘图yHat=xCopy*ws#计算对应的y值fig=plt.figure()ax=fig.add_subplot(111)ax.plot(xCopy[:,1],yHat,c='red')#绘制回归曲线plt.scatter(xMat.A[:,1],yMat.A,c='b',s=10)#绘制数据集sampleplt.show()这里省略了加载数据集函数。第一个函数standRegres用于计算回归系数。首先将x和y作为矩阵传入,然后计算$X^TX$。接下来的操作可能比较陌生,因为上面已经说过只有可逆矩阵才能求逆。这里,linalg.det()方法可以计算矩阵的行列式。当行列式非零时,计算回归系数ws并返回。第二个函数是绘图函数,根据第一个函数计算出的回归系数绘制回归曲线,最后画出图像如下:几乎任何数据集都可以用上面的方法建立模型,那么多好或者这些模型不好是怎么判断的?“相关系数”可以计算出预测值序列和真实值序列的匹配程度,而Numpy中的corrcoef方法可以计算出两个序列之间的相关性。图中主对角线上的1代表你和自己完全匹配,副对角线代表预测值和实际值的相关性。局部加权线性回归拟合的回归曲线难免有些粗糙,会出现一些欠拟合现象,比如波浪到直线的距离还是有点远,难以达到最佳预测效果,局部加权线性回归(LWLR)通过在估计中引入一些偏差来减少预测的均方误差。该方法的基本思想是给待预测点附近的每个点分配一定的权重,并将这些权重存储在一个新的矩阵W中,表达式如下:$$\omega^\ast=(X^TWX)^{-1}X^TWy$$加权模型也考虑到样本点之间的距离越近,越有可能符合同一个线性模型,所以对于当前预测的样本点$x^{(i)}$,距离越近的样本点$x$会被赋予更大的权重,这种机制可以使用高斯核来实现:$$\omega(i,i)=exp\left(\frac{x^{(i)}-x}{-2k^2}\right)$$这样就构造了一个只包含对角线元素的权重矩阵W。上面的公式只包含一个需要调整的参数k,它决定了给附近的点赋予多少权重。实际上,当k的值越大,参与训练的样本点就越多;相反,k值越小,只有少数局部点参与训练。如果对应的k值太大,可能会出现欠拟合,如果k值太小,可能会出现过拟合。因此,k值的选择决定了模型的好坏。具体代码如下:defLWLR(testMat,xMat,yMat,k=1.0):m=xMat.shape[0]n=testMat.shape[0]weights=np.mat(np.eye(m))#创建一个Unit对角矩阵yHat=np.zeros(n)#创建一个存储预测值的矩阵foriinrange(n):forjinrange(m):#遍历,根据公式求权重diffMat=testMat[i]-xMat[j]weights[j,j]=np.exp(diffMat*diffMat.T/(-2.0*k**2))xTx=xMat.T*(weights*xMat)如果np.linalg.det(xTx)==0.0:print("矩阵是奇异矩阵,不能求逆")returnws=xTx.I*(xMat.T*(weights*yMat))yHat[i]=testMat[i]*ws#求预测值returnyHat这里首先初始化一个权重矩阵weights,形式为主对角线上为1,其他位置为0。然后遍历数据集,计算每个样本点对应的权重值。当样本点与待预测点的距离越来越远时,权值会衰减,k控制衰减的速度。这里需要注意的是,testMat正是xMat本身,因为实际上每个样本的权重都是在数据集中的样本点之间计算的。起名testMat只是为了方便,最后可以得出对应的k值。回归曲线如下:可以看出,当k=1.0时,与普通回归曲线没有区别;当k=0.01时,回归线拟合较好;当k=0.002时,回归曲线开始出现棱角,证明曲线的一部分受其附近样本点的影响较大,从而导致过拟合现象。随着拟合越来越准确,模型也付出了相应的代价,即计算量增加,因为在预测每个点的同时要用到整个数据集。下面将介绍一种可以解决这个问题的方法。.岭回归在现实生活中,$X^TX$往往不是满秩矩阵。例如,数据集中可能有很多特征,其数量甚至超过了样本数量,导致X的列数多于行数。这时候$X^TX$显然对排名不满意了。为了解决这个问题,引入了岭回归的概念。岭回归的思想很简单,就是引入一个矩阵$\lambdaI$,把这个单位矩阵加到$X^TX$上,$X^TX$就可以转化为可逆矩阵,并且然后$X^TX+\lambdaI$逆,此时回归系数表达式可以写为:$$\omega^\ast=(X^TX+\lambdaI)^{-1}X^Ty$$这里$I$是单位矩阵,即主对角线上的元素为1,其余元素为0。$\lambda$称为惩罚项,其作用是减少不重要的参数。这种技术称为还原。显然,缩减后可以获得更好的预测结果。在使用岭回归和缩减技术之前,需要对特征进行标准化。我们在KNN中也使用了这部分。其目的是使每个特征具有相同的重要性。这部分代码如下:yMean=np.mean(yMat,axis=0)#找到真实的y平均值yMat=yMat-yMean#真实的y值减去平均值xMeans=np.mean(xMat,axis=0)#找到x平均值xVar=np.var(xMat,axis=0)#求方差xMat=(xMat-xMeans)/xVar#其余标准化代码与局部加权回归类似,不再赘述。为了方便起见,我们使用的数据集还是上面提到的。这里是最好使用特征多于样本的数据集,但我们只展示得出的结论,如下:这张图绘制了回归系数与$log(\lambda)$之间的关系,当$\lambda$很小,得到的系数和原来的线性回归是一致的;当$\lambda$达到一定值时,系数全部降为0;所以中间部分的某个值会达到最好的预测结果。这里有一条蓝线永远为0,因为我们一开始就设置了一个特征全为1,所以$\lambda$对这个特征没有影响。如果要找到最好的参数值,需要进行交叉验证,即多次调整参数找到最优,同时根据每个特征对应的系数大小,也可以判断影响这个特征对预测结果的影响。除岭回归外,归约方法还包括套索、LAR、PCA回归和子集选择。这些方法可以提高预测精度。有兴趣的小伙伴可以自行了解一下。综上所述,普通线性回归虽然可以拟合回归曲线,但过于粗糙,存在欠拟合现象。通过局部加权回归可以得到更好的预测结果,但关键是调整参数k。如果k太小,可能会出现过拟合的现象。对于现实任务中总会出现的不可逆矩阵,归约技术中的岭回归可以很好的解决这个问题。它的主要思想是通过消除冗余特征来减少预测误差。公众号【奶糖猫】回复“线性回归”获取源码供参考,感谢阅读
