机器学习:线性回归I 最小二乘法

原文在此

线性回归是最基础和常见的算法,属于监督学习的一种,是讲述算法开始的地方。我们在中学、大学学过很多次,虽然我已完全不记得。线性回归作为基础,虽然simple但不意味着easy,对其掌握很重要的。

虽然看上去平平无奇,不过其内涵之丰富让人惊叹,很多复杂的算法中都能看到线性回归的影子,可以自然的过渡到逻辑回归、多层感知机、再到深度学习等复杂的方法。

本篇主要结构如下:

  • 快照snapshot:sklearn实例

  • 最小二乘法

快照snapshot

首先看看我们要解决的问题。来自kaggle的house price数据集,有1460个样本的训练集,我们节选两列作为例子。

给定n个实例,每个实例含有m个特征和1个目标变量。目标变量为连续值时,意味着采用回归的方法;目标变量为离散值时,则采用分类的方法。这里的例子中,GrLivArea和LotArea两列是已知的特征,SalePrice列则是目标变量。目标变量与两个特征的关系如下图,可见特征与目标间基本符合“线性”的假设。

线性回归假设每个特征和目标变量的关系为线性关系,目标可用各个特征的加权求和求得。用如下公式表达:

其中,x是一个实例,含有m个特征故形状为(1,m);y是因变量;w是每个特征对应的权重,形状为(m,1);b是偏差,形状为1。

我们可以把n个实例的公式,写成矩阵形式:

其中,X变为n个实例的集合,是一个(n,m)形状的矩阵。Y为n个实例的目标,是形状为(n,1)的矩阵。

线性回归的求解过程是,已知X和Y,设置一个目标,求解最优目标时的对应的w和b。这里的目标既是:损失函数取最小值。这样问题转化为一个数学优化问题来求解,主要求解方法有基于误差的最小二乘法,和基于频率派观点的最大似然法,基于贝叶斯派观点的最大后验法。

为了了解基本过程,我们先在sklearn里实现一下。

# load the data
train = pd.read_csv("./data/house-prices-advanced-regression-techniques/train.csv")
train = train.loc[:,['GrLivArea','LotArea','SalePrice']]
# preprocess the data, and train test split
feature_cols = ['GrLivArea','LotArea']
train['SalePrice']=np.log1p(train['SalePrice'])
X_train, X_test, y_train, y_test = train_test_split(train.loc[:,feature_cols],train.loc[:,'SalePrice'], test_size=0.33, random_state=42)
# train and eval
lr = LinearRegression()
lr.fit(X_train, y_train)
print(lr.coef_, lr.intercept_)
y_pred = lr.predict(X_test)
print ("RMSE:",np.sqrt(metrics.mean_squared_error(y_test, y_pred)))

我们得到了两个特征对应的权重是4.89e-04和2.83-06,对应的截距b是11.25。这意味着
SalePrice=4.89e-4* GrLivArea + 2.83e-6* LotArea + 11.25

这样,我们就实现了一个线性回归的过程,知道了它大概的含义。当然,就算在excel里,也很容易的做出拟合来。

最小二乘法

最小二乘法,看着也是平平无奇,但他的发明者却是真大佬:高斯和勒让德。勒让德在1805年的著作《计算慧星轨道的新方法》中首先发表最小二乘法。高斯在4年后也发表了最小二乘法,并宣称已用了很多年了,而且还用它精确预测了谷神星的位置。如果是别人这么说,可能是沽名钓誉,但如果是高斯这么说,我是相信的。看来,最小二乘法也是响当当的高端知识。

最小二乘法的理念是承认观测误差的存在,认为误差是围绕真值上下波动的,当平方误差最小时即为真值。具体应用时,算法的关键是要学习到线性方程中中的未知权重w和b,当经验风险最小化时的权重认为是最优的。为了简化,我们经常在推导中忽略b,因为b可以认为存在一个常数列x=1对应的权重w的一个分量,不必单独另求。

m个实例的经验数据,其经验损失函数为:

虽然预测的时候我们是带入x,求解y,是关于特征x的函数。但训练的时候,我们把损失函数Loss看成是关于w的函数,把问题转化为求关于w的最优化问题。即Loss取最小值时,认为w和b是最佳值。最小值问题当然可以用微积分,导数为0时取得的值为极值,如果是凸函数,此时的极值为最小值。L对w的导数为:

其中,矩阵求导过程中用到的几个规律:

可求得w的解析解为:

这里需要存在逆矩阵的情况下才存在解析解,即需要其是一个满秩矩阵。如果是奇异矩阵,如特征的个数超过样本的个数或一些特征本身是线性相关的,则无法得到其解析解。

# 解析
X_train_extended=np.c_[X_train.values,np.ones(len(X_train))]
w=np.linalg.pinv(X_train_extended).dot(y_train)

梯度下降

矩阵求逆的运算量较大,且数据量较大甚至无法放进内存时,我们就需要一种高效数值解法:连深度学习都说好的梯度下降法。数值解法通过不断的迭代,以时间换空间,逐步求的最优解。

直观理解就是,在曲面上的一点,其变化最大的方向、最陡的方向是沿着梯度的方向。我们把loss看作一个w的函数,为了让loss不断减小,移动w的方向就是沿着其梯度的方向。

这里的 就是调参中最重要参数了学习率。每一步都沿着梯度负方向前进一点。梯度下降可以求得全局最优解的条件是凸优化。

批量梯度下降

批量梯度下降则是为了应对更大量数据的,总共有n个样本。可以一次进去一小批,更新一下参数,再进去更新一小批,更新一下参数。这里n个样本循环轮数称为epochs,每次进去的一下批的个数为batch_size,所以权重w一共更新的次数为 n/batch_size*epochs,称为总的步数steps。

如果每次只进去一个样本进行更新权重,则称为随机梯度下降,此时batch_size大小为1。

这些参数即使到了深度学习也是需要了解的基本概念,因此这里介绍了一下。而从梯度下降对调参的重要启示是:初始化很重要,学习率很重要,梯度下降决定了各个特征需要norm标准化。

通过最小二乘法,我们看到求解一个算法的基本步骤。那就是定义一个损失函数/目标函数,一般的目标函数都是为了让模型的预测尽量贴近数据中已有的标签。然后采用优化方法,不断调整模型重的参数,使目标函数取得最小值,此时的模型参数即为我们找到的模型。这个过程,就可以称之为“学习”。

我是YueTan,欢迎关注。

下篇预告: 机器学习- 线性回归II从零开始实现

参考资料:

机器学习

PRML

ESL

猜你喜欢

转载自blog.csdn.net/weixin_38812492/article/details/108226722