机器学习第一道菜(二):玩转最小二乘法
- 一、线性函数表达式
- 二、最小二乘法:数据拟合大师
- 2.1 概念及其历史背景
- 2.2 拟合优势
- 2.3 数学表达式
- 2.3.1 一般公式
- 2.3.2 目标函数
- 2.4 用python快速搞定最小二乘法
- 2.4.1 numpy
- 2.4.2 linear_model
- 2.4.3 python代码
之前在 《机器学习第一道菜(一):线性回归的理论模型》一文中,我们建立了线性回归的理论模型,本文就用“最小二乘法”来求解这个模型。
一、线性函数表达式
1.1 函数表达式 y y y
在《机器学习第一道菜(一):线性回归的理论模型》一文中,我们最终得到的表达式为:
y = θ 0 + θ 1 x y=\theta_0 + \theta_1x y=θ0+θ1x
别被这个式子吓到,它只不过是我们熟知的一次函数 y = k x + b y=kx+b y=kx+b的另一种写法(把k换成 θ 1 \theta_1 θ1,b换成 θ 0 \theta_0 θ0)。
搞这个函数是为了找到一条最佳直线,拟合我们文中“千金买笑”(简单理解为:送礼越贵,妹子越笑)问题的离散数据点。
对付这些散乱的数据点的入门级武器就是“最小二乘法”,它能找到数据背后的规律。
1.2 函数表达式 f θ ( x ) f_\theta(x) fθ(x)
为了让最小二乘法这道菜做得更地道,我们需要再次转换一下上面的表达式,改成这个鸟样:
f θ ( x ) = θ 0 + θ 1 x f_\theta(x)=\theta_0 + \theta_1x fθ(x)=θ0+θ1x
咱们要做的就是确定这个函数,也就是求出 θ \theta θ的值。
这么写也很好理解。咱们上学时就经常把y写成 f ( x ) f(x) f(x),这样就更清楚地表示这个函数是关于x的函数。还有一点,如果继续使用y,后面可能会造成混乱。 f ( x ) f(x) f(x)加上下标 θ \theta θ是为了标明这个函数含有我们要求的参数 θ \theta θ。
1.3 最小误差
现在再明确一下问题:
已知:礼物金额及对应的微笑次数数据,这些数据被称为训练数据。
求: θ \theta θ的值,即 θ 0 \theta_0 θ0、 θ 1 \theta_1 θ1,也就是一次函数的截距和斜率。
这个问题可以转换为下面的问题:
找到 θ \theta θ,使训练数据中的x(礼物金额)代入函数后,求出来的 f θ ( x ) f_\theta(x) fθ(x)(微笑次数)与训练数据中的微笑次数的差最小。
随便拿上面散点图中的几个数据为例:
礼物金额 x x x | 微笑次数 y y y |
---|---|
1245 | 9 |
1324 | 14 |
1843 | 12 |
2342 | 22 |
3189 | 28 |
由于最开始不知道给 θ \theta θ取多大的值合适,那就先随便给个随机值,比如设 θ 0 = 1 \theta_0=1 θ0=1、 θ 1 = 2 \theta_1=2 θ1=2,则表达式变为:
f θ ( x ) = 1 + 2 x f_\theta(x)=1+ 2x fθ(x)=1+2x
将上表中的x代入函数,求出 f θ ( x ) f_\theta(x) fθ(x):
礼物金额 x x x | 微笑次数 y y y | θ 0 = 1 \theta_0=1 θ0=1、 θ 1 = 2 \theta_1=2 θ1=2 时的 f θ ( x ) f_\theta(x) fθ(x) |
---|---|---|
1245 | 9 | 2491 |
1324 | 14 | 2649 |
1843 | 12 | 3687 |
2342 | 22 | 4685 |
3189 | 28 | 6379 |
接下来我们要做的就是通过不断调整 θ \theta θ,使计算值 f θ ( x ) f_\theta(x) fθ(x)与实际值 y y y的差值最小。
理想的情况就是二者的差值为0,即:
y − f θ ( x ) = 0 y-f_\theta(x)=0 y−fθ(x)=0
y和fθ(x)之间的误差为0,可能对于个别数据可以实现,但要所有点的误差都是0是不可能的。
实际上,个别点误差最小是没有意义的,我们应该着眼于所有点,使所有点的误差之和尽可能地小。用公式表示为:
min ∑ i = 1 n ∣ y i − f θ ( x i ) ∣ \min \sum_{i=1}^{n}|y_i - f_\theta(x_i)| mini=1∑n∣yi−fθ(xi)∣
∑是求和符号,读作“西格玛”。上面的公式表示对每个训练数据的误差求和。
然而,这个式子求解起来很不方便,主要有两个原因:
(1)可加性。因为求绝对值需要考虑误差为负的情况,这虽然不存在什么困难,但会降低效率。
(2)可微性。这是最主要的原因。求解误差最小值,需要用到微分。绝对值函数图像不连续,有的点不可微分,而且还必须分情况讨论,很麻烦。
下面介绍一个求解类似误差和最小问题的通用方法:最小二乘法。相比如前面的最小绝对值法,最小二乘法的优势是使用平方类函数,图像连续、可微分,计算微分也非常简单。
二、最小二乘法:数据拟合大师
2.1 概念及其历史背景
最小二乘法(Least Squares Method)是一种数据拟合方法。
从名字可以看出它有两个特点:
- 最小(Least ):它求的是最小值。
- 二乘(Squares):square的意思是平方。二乘就是两个同样的数相乘,就是求平方。
最小二乘法的核心思想是:找到一个最佳的函数曲线(通常是一条直线或曲线),使得所有数据点到这条曲线的垂直距离(也就是误差)的平方和最小。简单来说,就是找到一个最“平均”的拟合方式,让所有数据点都尽可能地靠近这条曲线。
这种方法最早可以追溯到18世纪末期,由德国数学家高斯(Carl Friedrich Gauss)和法国数学家勒让德(Adrien-Marie Legendre)分别独立提出,并逐渐成为现代统计学、机器学习等领域不可或缺的一部分。
2.2 拟合优势
最小二乘法相比其他拟合方法有以下几大优势:
- 计算简便:只需要求解线性方程组即可获得结果,非常适合计算机自动化处理;
- 稳定性强:即使输入数据存在轻微波动或噪声干扰,也能保证输出结果相对稳定;
- 应用广泛:不仅限于线性关系建模,还可以扩展应用于非线性回归分析等多个场景。
2.3 数学表达式
2.3.1 一般公式
假设我们有一组实际数据 ( x i , y i ) (x_i, y_i) (xi,yi),其中 i = 1 , 2 , … , n i=1,2,\ldots,n i=1,2,…,n表示数据(或者称样本)编号。我们的目标是找到一条直线(或其他形式的曲线),使得这条线上每个点与实际值之间的垂直距离尽可能小。用公式表示就是:
min a , b ∑ i = 1 n ( y i − ( a x i + b ) ) 2 \min_{a,b} \sum_{i=1}^{n}(y_i - (ax_i + b))^2 a,bmini=1∑n(yi−(axi+b))2
这里, a a a代表斜率, b b b则是截距, a x i + b ax_i + b axi+b为所求一次函数。
这是最小二乘法公式的一般形式。
为了方便计算,可以进一步简化为矩阵形式:
e T e = ( Y − X β ) T ( Y − X β ) \mathbf{e}^T\mathbf{e} = (\mathbf{Y}-X\mathbf{\beta})^T(\mathbf{Y}-X\mathbf{\beta}) eTe=(Y−Xβ)T(Y−Xβ)
其中, Y \mathbf{Y} Y是一个包含所有 y i y_i yi的列向量, X X X是由 x i x_i xi组成的系数矩阵,而 β \mathbf{\beta} β则包含了待估计的参数 a a a和 b b b。通过求导并令导数等于零,最终可以得到最优解 β ^ = ( X T X ) − 1 X T Y \hat{\beta}=(X^TX)^{-1}X^T\mathbf{Y} β^=(XTX)−1XTY。
这个矩阵形式说是为了简化计算,但感觉是复杂了理解。老金反正正是没看明白。
2.3.2 目标函数
介绍完最小二乘法公式的一般形式,再回到咱们今天要说的机器学习中的线性回归问题。
前面说了,用 min ∑ i = 1 n ∣ y i − f θ ( x i ) ∣ \min \sum_{i=1}^{n}|y_i - f_\theta(x_i)| min∑i=1n∣yi−fθ(xi)∣这种绝对值的形式求最小误差和不好求解。改用最小二乘法后,变成误差的平方形式,可直接消去绝对值。
在线性回归问题中,一般采用下面的奇葩写法:
E ( θ ) = 1 2 ∑ i = 1 n ( y ( i ) − f θ ( x ( i ) ) ) 2 E(\theta)=\frac{1}{2}\sum_{i=1}^{n}(y^{(i)} -f_\theta(x^{(i)}))^2 E(θ)=21i=1∑n(y(i)−fθ(x(i)))2
注意:
① E ( θ ) E(\theta) E(θ)是一个函数,这说明 E E E是关于 θ \theta θ的函数,就是说参数 θ \theta θ才是他的自变量, x x x不是。
② E ( θ ) E(\theta) E(θ)的 E E E是误差的英语单词Error的首字母。
③ x ( i ) x^{(i)} x(i)和 y ( i ) y^{(i)} y(i)中的i不是i次幂的意思,而是指第i个训练数据。也就是说,它们就相当于 x i x_i xi、 y i y_i yi。
④常数 1 2 \frac{1}{2} 21是硬凑出来的,加不加并不影响结果(只要是正的常数都不影响),加上它纯出于美观考虑。这是为了后面的微分,因为微分的时候指数2会下来变成乘以2,正好跟1/2抵消,微分后的式子前面就没有了常数2,看起来会很有美感。
这玩艺被称为“目标函数”,也被称为损失函数(loss function)、成本函数或误差函数。
说到底,它就是一个用来衡量预测值与真实值之间差距的函数。
机器学习的目标就是找到一组模型参数(也就是 θ \theta θ的值),使得目标函数 E ( θ ) E(\theta) E(θ)的值最小。
这样的问题称为最优化问题,或者叫目标规划。
我们可以把1.3节中最后一张表中的微笑次数 y y y,及当 θ 0 = 1 \theta_0=1 θ0=1、 θ 1 = 2 \theta_1=2 θ1=2 时的 f θ ( x ) f_\theta(x) fθ(x)代入这个目标函数:
E ( θ ) = 1 2 ∑ i = 1 n ( y ( i ) − f θ ( x ( i ) ) ) 2 = 1 2 × ( ( 9 − 2491 ) 2 + ( 14 − 2649 ) 2 + ( 12 − 3687 ) 2 + ( 22 − 4685 ) 2 + ( 28 − 6379 ) 2 ) = 1 2 × ( 6160324 + 6943225 + 13505625 + 21743569 + 40335201 ) = 44343972 \begin{align*} E(\theta)&=\frac{1}{2}\sum_{i=1}^{n}(y^{(i)} -f_\theta(x^{(i)}))^2 \\ &= \frac{1}{2}\times((9-2491)^2+(14-2649)^2+(12-3687)^2+ (22-4685)^2 +(28-6379)^2) \\ &= \frac{1}{2}\times(6160324+6943225+13505625+21743569+40335201) \\ &= 44343972 \end{align*} E(θ)=21i=1∑n(y(i)−fθ(x(i)))2=21×((9−2491)2+(14−2649)2+(12−3687)2+(22−4685)2+(28−6379)2)=21×(6160324+6943225+13505625+21743569+40335201)=44343972
这个误差确实有点大哈,而且这才只有5组数据,要是有5万组呢?
我们要做的就是不断修改参数 θ \theta θ,使这个值变得越来越小,这就是最小二乘法。
2.4 用python快速搞定最小二乘法
最小二乘法基本形式咱们搞明白了,但要求出目标函数最小时的 θ \theta θ,还有一定难度。
等不了了,先上个工具把结果直接求出来再说。
用python求解这个问题非常简单,只需要几行代码,简直可以说妈妈再也不用担心我的学习。
求解之前,先要下载两个库。
2.4.1 numpy
NumPy(Numerical Python)是一个用于科学计算的Python库,它提供了一种高效处理大型多维数组和矩阵的方式,是Python进行科学计算的一个基础包。
官方网站:http://www.numpy.org/
安装方法:
①在Windows左下方的输入框中键入cmd,回车
②在弹出的黑窗口(命令提示符)中输入:
pip install numpy
即可完成安装
2.4.2 linear_model
linear_model可以快速实现最小二乘法线性回归。它是sklearn(即scikit-learn)库的一部分,提供了一系列用于拟合线性模型的方法和工具。
官方网站:https://scikit-learn.org/
安装方法:同上,只是输入:pip install scikit-learn
2.4.3 python代码
import numpy as np
from sklearn.linear_model import LinearRegression
# 输入数据集
days = np.array([1245, 1324, 1843, 2342, 3189]).reshape((-1, 1))
temperatures = np.array([9, 14, 12, 22, 28,])
# 创建并训练线性回归模型
model = LinearRegression()
model.fit(days, temperatures)
# 输出拟合结果
print("斜率:", model.coef_[0])
print("截距:", model.intercept_)
输出:
斜率: 0.009157584356140707
截距: -1.2107722506214103
把它们代进去,求出的函数为:
y = 0.009157584356140707 x − 1.2107722506214103 y=0.009157584356140707x-1.2107722506214103 y=0.009157584356140707x−1.2107722506214103
按这个函数求出5组数据的微笑次数如下:
礼物金额 x x x | 实际微笑次数 y y y | 利用函数求出的微笑次数 |
---|---|---|
1245 | 9 | 10 |
1324 | 14 | 11 |
1843 | 12 | 16 |
2342 | 22 | 20 |
3189 | 28 | 28 |
怎么样,看着效果还不错吧。这只是5组数据,如果数据更多,它的拟合效果就越好。
咱们可以把数据都代入函数,算下此时目标函数的值:
E ( θ ) = 1 2 ∑ i = 1 n ( y ( i ) − f θ ( x ( i ) ) ) 2 = 1 2 × ( ( 9 − 10 ) 2 + ( 14 − 11 ) 2 + ( 12 − 16 ) 2 + ( 22 − 20 ) 2 + ( 28 − 28 ) 2 ) = 1 2 × ( 1 + 9 + 16 + 4 + 0 ) = 15 \begin{align*} E(\theta)&=\frac{1}{2}\sum_{i=1}^{n}(y^{(i)} -f_\theta(x^{(i)}))^2 \\ &= \frac{1}{2}\times((9-10)^2+(14-11)^2+(12-16)^2+ (22-20)^2 +(28-28)^2) \\ &= \frac{1}{2}\times(1+9+16+4+0) \\ &= 15 \end{align*} E(θ)=21i=1∑n(y(i)−fθ(x(i)))2=21×((9−10)2+(14−11)2+(12−16)2+(22−20)2+(28−28)2)=21×(1+9+16+4+0)=15
是不是非常小了?