很多人在开始学习机器学习的时候都看不上线性回归,觉得这种算法太老太笨,不够fancy,草草学一下就去看随机森林、GBDT、SVM甚至神经网络这些模型去了。但是后来才发现线性回归依然是工业界使用最广泛的模型。而且线性回归细节特别多,技术面时被问到的概率也很大,希望大家能学好线性回归这块机器学习,也可能是一个offer的敲门砖。
学习中,顺着线性回归,可以引申出多项式回归、岭回归、lasso回归,此外还串联了逻辑回归、softmax回归、感知机。通过线性回归,还能巩固和实践机器学习基础,比如损失函数、评价指标、过拟合、正则化等概念。最后,线性回归与后续要学到的神经网络、贝叶斯、SVM、PCA等算法都有一定的关系。
本文将会出现不少数学公式,需要用到线性代数和微积分的一些基本概念。要理解这些方程式,你需要知道什么是向量和矩阵,如何转置向量和矩阵,什么是点积、逆矩阵、偏导数。对于极度讨厌数学的读者,还是需要学习这一章,但是可以跳过那些数学公式,希望文字足以让你了解大多数的概念。
线性模型
线性模型的表达式很简单:
线性回归
MSE物理意义怎么解释?均方误差有非常好的几何意义,它对应了常用的欧几里得距离或简称“欧氏距离”(Euclidean distance)。基于均方误差最小化来进行模型求解的方法称为“最小二乘法”(least square method)。在线性回归中,最小二乘法就是试图找到一条直线,使所有样本到直线上的欧氏距离之和最小。
最小二乘法:使得所选择的回归模型应该使所有观察值的残差平方和达到最小
- 非满秩矩阵:例如3个变量,但是只有2个方程,故无法求得唯一的解。
- 矩阵的逆:类似于数字的倒数(5对应1/5)目的是实现矩阵的除法。
解决方法: 引入正则化(regularization)将矩阵补成满秩
代码实战:
# 随机生成一些用于实验的线性数据
import numpy as np
np.random.seed(42)
m = 100 # number of instances
X = 2 * np.random.rand(m, 1) # column vector
y = 4 + 3 * X + np.random.randn(m, 1) # column vector
画个图来看看生成的数据。
import matplotlib.pyplot as plt
plt.figure(figsize=(6, 4))
plt.plot(X, y, "b.")
plt.xlabel("$x_1$")
plt.ylabel("$y$", rotation=0)
plt.axis([0, 2, 0, 15])
plt.grid()
plt.show()
# add x0 = 1 to each instance
X_b = np.c_[np.ones((100, 1)), X]
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
X_new = np.array([[0], [2]])
# add x0 = 1 to each instance
X_new_b = np.c_[np.ones((2, 1)), X_new]
y_predict = X_new_b.dot(theta_best)
绘制模型的预测结果。
plt.plot(X_new, y_predict, "r-")
plt.plot(X, y, "b.")
plt.axis([0, 2, 0, 15])
plt.show()
另外也可以直接调用最小二乘函数scipy.linalg.lstsq()进行计算:
theta_best_svd, residuals, rank, s = np.linalg.lstsq(X_b, y, rcond=1e-6)
theta_best_svd的计算结果为array([[4.21509616],[2.77011339]])。
方法二:数值解法
梯度下降,随机初始化和,通过逼近(沿着梯度下降的方向)的方式来求解(找到一个收敛的参数值)。
损失函数回顾:
梯度下降的过程可以通过程序来完成,动手练习,可以加深对于梯度下降方法的理解。
梯度下降有什么缺点?
- 最小点的时候收敛速度变慢,并且对初始点的选择极为敏感。
- 梯度下降有时会陷入局部最优解的问题中,即下山的路上有好多小坑,运气不好掉进坑里,但是由于底部梯度(导数)也为0,故以为找到了山的最底部。
- 步长选择的过大或者过小,都会影响模型的计算精度及计算效率。
解决方法: 随机梯度下降、批量梯度下降、动量梯度下降
代码实战:
eta = 0.1 # learning rate
n_iterations = 1000
m = 100
theta = np.random.randn(2,1) # random initialization
for iteration in range(n_iterations):
gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
theta = theta - eta * gradients
计算的theta结果为array([[4.21509616],[2.77011339]]),是不是很简单?还可以更简单!
使用Scikit-Learn自带的随机梯度下降SGDRegressor类,该类默认优化平方误差成本函数。以下代码最多可运行1000个轮次,或者直到一个轮次期间损失下降小于0.001为止(max_iter=1000,tol=1e-3)。它使用默认eta0=0.1。
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=1000, tol=1e-3, penalty=None, eta0=0.1)
sgd_reg.fit(X, y.ravel())
解析法(最小二乘)还是数值法(梯度下降),如何选择?
4. 梯度下降法: 一种数值方法(也可以叫优化方法),需要多次迭代来收敛到全局最小值。
损失函数虽然是碗状的,但如果不同特征的尺寸差别巨大,那它可能是一个非常细长的碗。如图所示的梯度下降,左边的训练集上特征1和特征2具有相同的数值规模,而右边的训练集上,特征1的值则比特征2要小得多(注:因为特征1的值较小,所以θ1需要更大的变化来影响成本函数,这就是为什么碗形会沿着θ1轴拉长)whaosoft aiot http://143ai.com 最后说下,统计学和机器学习中,可能存在一些术语差异&混用,如下表,但它们说的是一个意思: