在机器学习中,由于数据是多维度的,所以线性回归在此一般指多元线性回归。线性回归中的线性指的是,自变量和因变量之间呈线性关系,也就是自变量最高次数为1。回归指的是,自变量是连续分布的。否则就是就是分类问题。
对于求出一组数据中的回归直线,可采用最小二乘法。
最小二乘法
标量表达
最小二乘法,最早我们在初中就接触过,只不过那个时候考虑的自变量只有一个。 最小二乘法的思想很简单,先假设一条直线,如
y = b x + a y=bx+a y=bx+a
很明显求出来的此条直线是不会经过所有数据点的,但我们要保证各数据点到此条直线的距离和是最短的。对此我们可以构造出一个函数
J = 1 2 ∑ i = 1 n ( y i − y ^ i ) 2 J = \frac{1}{2} \sum_{i=1}^{n}(y_i-\hat{y}_i)^2 J=21i=1∑n(yi−y^i)2
其中,y帽代表预测值,很显然,此函数是关于a,b的函数.而我们的目的就是要求出此函数的最小值,学过高等数学的我们都知道,只需要对这a,b求偏导数,另其等于零,解出a,b即可。在初中我们就知道,解出来的a,b为:
a = y ˉ − b x ˉ b = ∑ i = 1 n x i y i − n x ˉ y ˉ ∑ i = 1 n x i 2 − n x ˉ 2 a = \bar{y}-b\bar{x} \\ b = \frac{\sum_{i=1}^{n}x_iy_i-n\bar{x}\bar{y}}{\sum_{i=1}^{n}x_i^2-n\bar{x}^2} a=yˉ−bxˉb=∑i=1nxi2−nxˉ2∑i=1nxiyi−nxˉyˉ
其中, x ˉ \bar{x} xˉ和 y ˉ \bar{y} yˉ代表样本对应变量的平均值
我们可以通过Python来验证上面的想法,代码如下,通过jupyter编写:
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
#生成随机数据
x_train = 10*np.random.rand(20,)
y_train = x_train * 4 + 3+ np.random.randn(20,)
print(x_train)
print(y_train)
[4.20317897 9.45722496 3.3495886 0.87348741 8.28675402 9.94841941
5.51671545 4.39436695 1.25734414 4.65941892 9.3974875 6.70832224
3.33828963 2.3645433 5.14405277 6.60791116 2.8787364 8.71938945
9.45601128 2.96794702]
[18.47497825 40.93485883 18.87926004 5.23501616 36.56810701 42.8693648
24.67536109 21.64865443 8.72337565 22.39404305 38.21333044 29.37466431
15.35262564 13.30489897 24.53073011 28.3152433 12.76249708 37.40211258
41.68158987 14.40621423]
#画图
plt.scatter(x_train,y_train)
plt.axis([0,10,0,45])
plt.show()
a = y ˉ − b x ˉ b = ∑ i = 1 n x i y i − n x ˉ y ˉ ∑ i = 1 n x i 2 − n x ˉ 2 a = \bar{y}-b\bar{x} \\ b = \frac{\sum_{i=1}^{n}x_iy_i-n\bar{x}\bar{y}}{\sum_{i=1}^{n}x_i^2-n\bar{x}^2} a=yˉ−bxˉb=∑i=1nxi2−nxˉ2∑i=1nxiyi−nxˉyˉ
其中, x ˉ \bar{x} xˉ和 y ˉ \bar{y} yˉ代表样本对应变量的平均值
```python
#最小二乘法拟合曲线
b = (np.dot(x_train,y_train) - len(x_train) * x_train.mean() * y_train.mean())/ \
(np.dot(x_train,x_train) - len(x_train) * x_train.mean() * x_train.mean())
print(b)
3.9697234774479964
a = y_train.mean() - b * x_train.mean()
print(a)
3.047316524615642
#绘制拟合后的直线图和原训练集图
x_new = 10*np.random.rand(20,)
y_new = x_new * b + a
plt.scatter(x_train,y_train)
plt.plot(x_new,y_new)
plt.axis([0,10,0,45])
plt.show()
向量/矩阵表达
上面那个例子,说实话,上过中学的娃,都能知道是干啥,毕竟当时学过。但我们机器学习肯定没有这么简单的,光从数据的维度而言,就不会只有一维这么简单,那么此时,我们就要用向量和矩阵来表达数据和公式了。说实话,当初看到这些的时候,什么对矩阵求导、积分,一脸闷逼,好像大学本科高等数学和线性代数也没学过啊…感兴趣的,可以看看王松桂写的<<线性模型引论>>,此书中有提道对矩阵的相关高级操作。
矩阵求导
关于矩阵求导,这里给出我自己对于标量对矩阵/向量求导的推导理解过程,其他类型可以参考这篇文章:
结果就是,求导的结果和自变量同形,其各分量值为标量对对应的自变量分量求导。
现在回到线性回归这个问题,用向量表达就是(n表示n组数据):
J = 1 2 ∑ i = 1 n ( y i − y ^ i ) 2 = 1 2 ( X θ − y ) T ( X θ − y ) 其 中 θ = ( b