线性回归问题

来源:互联网 发布:c#网络编程视频 编辑:程序博客网 时间:2024/04/29 14:33

首先,我们要明确什么是回归,回归和分类的区别是什么?

分类和回归的区别在于输出变量的类型。 定量输出称为回归,或者说是连续变量预测; 定性输出称为分类,或者说是离散变量预测。 举个例子: 预测明天的气温是多少度,这是一个回归任务; 预测明天是阴、晴还是雨,就是一个分类任务。

线性回归?

如果每个样本只有一个属性,以下图为例,y是待估计的值,x是一个属性。

以上图为例,我们需要根据已有的样本(也就是上图中的点)估计合适的参数a和b

现在我们来重新说明下我们的目的,我们是要找到这样的一个函数h(x),这个函数有theta0,theta1,....,thetan这么多个参数,使得这个函数能尽量的拟合已有的样本。

,其中我们在每个样本的第一列加了一个x0=1,使得theta0作为截距,也就是说,我们要找一个超平面来尽可能地拟合样本。

那现在问题的关键转化成我们如何参数theta。

我们将M个N维矩阵组成样本X,其中X的每一行对应一个样本,共M个样本,X的每一列对应一个属性(也就是样本的一个维度),共N维样本。y是M*1的向量,每一行代表第i个样本在待估计的属性上的值。

这时候有两种做法。

目标函数:

其中,是第i个样本,是第i个样本的第j个属性。

现在,我们开始想象该目标函数的合理性(最严谨的做法是假设误差项服从高斯分布,可以找本机器学习的书看看),我们使每一个样本都尽量接近需要预测的那个属性的值,最终使所有样本的误差平方项和最小,如果能使这个函数达到最小值,预测结果是相对比较合理的。也就是说,我们需要找到使这个函数达到最小值对应的theta,就达到目的了。

增加平方正则项(L2正则化)的目标函数:


使用带有正则项的目标函数,可以防止过拟合。这里只简单说明原因(如若想知道更多,可以参考李航的统计学习方法的一个例子),如果没有增加正则项,则容易过分地去拟合样本,学习到了样本中的噪音数据。而增加正则项,就会抑制这种现象。因为如果过分拟合样本,就会导致theta的值总体偏大,导致整个目标函数比较大。


(1)解析式法


另一个理解角度是,我们要找到使这个式子成立的解,但是最直接的想法是对X求逆。首先,X一般不是方阵,一般样本量是远大于样本的维度。其次,就算刚好相等,也不一定可逆。这时候矩阵论的广义逆就派上用场了,广义逆的本质还是利用目标函数求出来的。具体做法可以找一本矩阵论的书瞧瞧,这边只给出公式。


针对带有正则项的目标函数,可以可以模拟以上的过程,同样可以得到以下的解。


首先是个半正定矩阵,原因是,也就是是个半正定矩阵,即特征值都大于等于0,

不可逆,或为了防止过拟合增加landan扰动(landan大于0),则,此时可以的特征值大于等于landan,也就大于0,必然可逆。

此处记录下L1正则化(目标函数后面添加的是绝对值项而不是平方项)与L2正则化的区别,L1正则化的结果更容易有出现参数为0,也就是说该值对应的属性与结果无关。

而L2正则化则更容易出现一些值较小的项。

(2)梯度下降法

梯度下降法并不是使用解析式法来求目标函数的最小值,而是使用梯度(上升最快的方向,不懂自己去查查资料,可以使用多元的高斯展开式理解)慢慢下降,直到极小值。相比解析式法,这是更常用的方法,因为很多时候解析式不一定能求解出来,而梯度则是很容易求解。

梯度方向:


按照这种情况,产生批量梯度下降



但是这样其实效率很低,因为每下降一次都需要使用到所有样本。

由此产生改进算法,随机梯度下降,每拿到一个样本,就下降一次。


如果想要自己实现线性回归,可以参考机器学习实战这本书,python代码写得还是非常优秀的。

附上使用scikit-learn的线性回归代码,这个真的特别简单,直接去scikit-learn的官网照着例子敲。

使用的例子是新闻的案例,可以自己网上去找,还是很多的。

from sklearn import linear_modelimport pandas as pdfrom sklearn.model_selection import train_test_splitimport numpy as npif __name__ == '__main__': houseData = pd.read_csv('8.Advertising.csv') x = houseData[['TV','Radio','Newspaper']] y = houseData['Sales'] x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=1) alpha = np.logspace(-3,1,10) reg = linear_model.RidgeCV(alphas = alpha) model = reg.fit(x_train,y_train) y_hat = reg.predict(x_test) mse = np.average((y_hat - y_test) ** 2) rmse = np.sqrt(mse) print model print reg.coef_ print reg.intercept_ #print y_hat #print y_test print mse print reg.alpha_ #print x #print y
1 0
原创粉丝点击