线性回归是机器学习中最基础的预测模型之一,主要用于预测连续的数值型目标变量。
跟中学的二元一次方程类似,假设输入变量(自变量)和输出变量(因变量)之间存在线性关系。
线性回归模型试图找到一条直线,最好地描述自变量 X 和因变量 Y 之间的关系。这条直线的数学表达式为:
Y=β0+β1X+ϵ
其中,β0是截距,β1是斜率,统称为模型参数;ϵ是误差项,代表模型未能解释的部分
回归问题解法
这里我们换一种更直观的方式来表示线性回归问题
假定每个样本有 N 个特征 x1,x2,...,xN ,采集到 M 个样本的这 N 个特征的值并标注其结果 y:
x1(i),x2(i),...,xN(i),y(i)(1≤i≤M)
假定结果与这 N 个特征之间都是线性关系:
y=hθ(x)=θ0+θ1x1+...+θNxN=i=0∑Nθixi
换成矩阵形式:
hθ(x)=θTX,其中θ=θ0θ1...θNX=1x1...xN
对于每一个样本点,可以表示为:
y(i)=θTx(i)+ϵ(i)
假定误差 ϵ(i)(1≤i≤M) 是独立同分布的,服从均值为 0,方差为某定值 σ2 的高斯分布
为什么使用高斯分布?
- 中心极限定理
- 想象一下,你在做一件事情,这件事的结果受到很多小因素的影响,比如打篮球时的风向、手的角度、力量的大小等等。单独看一个因素,它可能对结果的影响不大,而且这种影响可能是随机的。但当这些小因素叠加起来时,它们共同创造最终的结果
- 中心极限定理告诉我们,当有很多这样的小随机因素影响一个结果时,无论这些因素各自是什么分布(只要它们符合一些基本条件),它们的总和都会趋向于形成一个高斯分布。这就是为什么即使我们不知道误差的具体来源,我们仍然可以假设它们整体上呈正态分布
- 统计分析的简化:
- 在构建统计模型时,希望模型简洁且有强大的预测能力。如果假设误差项遵循高斯分布,就可以使用一些非常有效的统计工具,比如最小二乘法和最大似然估计,来找到模型参数
- 假设误差是高斯分布的,意味着误差是“公平”的——没有系统偏差,所有的偏差都是随机的。这使得模型的估计更加可靠,因为它不会系统地高估或低估真实值
- 在经典线性回归分析中,常常假设误差项 ϵ(i) 是独立同分布的,且服从均值为 0,方差为 σ2 的正态分布。这个假设(高斯白噪声假设)简化了模型的分析和参数的估计,特别是使用最小二乘法或最大似然估计时
根据高斯分布的概率密度函数:
p(ϵ(i))=2πσ1exp(−2σ2(ϵ(i))2)
可以得到:
p(y(i)∣x(i);θ)=2πσ1exp(−2σ2(y(i)−θTx(i))2)
因为样本的特征和结果已知,上述函数是关于 θ 的函数,则可以得到关于 θ 的似然函数:
L(θ)=i=1∏mp(y(i)∣x(i);θ)=i=1∏m2πσ1exp(−2σ2(y(i)−θTx(i))2)
对其求对数似然:
l(θ)=logL(θ)=logi=1∏m2πσ1exp(−2σ2(y(i)−θTx(i))2)=i=1∑mlog2πσ1exp(−2σ2(y(i)−θTx(i))2)=m∗log2πσ1−σ21∗21i=1∑m(y(i)−θTx(i))2
极大似然估值是要求 l(θ) 的最大值,令:
J(θ)=21i=1∑m(y(i)−θTx(i))2=21i=1∑m(hθ(x(i))−y(i))2
为什么这里要用 hθ(x(i))=θTx(i) 等价变化?
-
概念清晰:使用 hθ(x) 使得模型的解释更加直观。可以更清楚地看到,损失函数是通过计算预测值 hθ(x(i)) 与实际值 y(i) 之间的差的平方来定义
-
扩展性:采用这种形式,可以更容易地将线性模型扩展到非线性模型,例如在 Logistic 回归或神经网络中,hθ(x) 可能包括非线性变换
求 l(θ) 的最大值等价于求J(θ) 的最小值,求J(θ) 最小值就是使用最小二乘法(J(θ) 即损失函数)
解析解
求J(θ) 的最小值就是一个求极值的问题,即求 ∂θ∂J(θ)=0 时 θ 的值
将 M 个 N 维样本组成矩阵 X
- X 的每一行对应一个样本,共 M 行
- X 的每一列对应 样本的一个维度(特征),加上一个值恒为 1 的维度(截距),共 N+1 列
将损失函数 J(θ) 转化为:
J(θ)=21i=1∑M(hθ(x(i))−y(i))2=21(Xθ−y)T(Xθ−y)=21(θTXT−yT)(Xθ−y)=21(θTXTXθ−θTXTy−yTXθ+yTy)
对上式求 θ 的偏导:
∂θ∂J(θ)=21(2XTXθ−XTy−(yTX)T)=21(2XTXθ−XTy−XTy)=XTXθ−XTy
导数规则
- 导数 ∂θ∂(θTAθ)=2Aθ ,当 A 是对称矩阵
- 导数 ∂θ∂(θTb)=∂θ∂(bTθ)=b ,当 b 是常数向量
令上式为 0,得到最终解:
∂θ∂J(θ)=0⇒XTXθ=XTy⇒θ=(XTX)−1XTy
这里 XTX 不一定可逆,可以加上 λ 扰动(λ 是一个略大于 0 的实数)
θ=(XTX+λI)−1XTy
XTX+λI 是正定的,所以一定是可逆的
为什么加入扰动一定是正定?
首先来解释一下什么是正定矩阵:如果对于所有非零向量 v,都有 vTAv>0,则这个对称矩阵 A 被称为正定矩阵。
XTX 特性:
- 对称性:XTX 是一个对称矩阵,因为 (XTX)T=XT(XT)T=XTX。
- 半正定:XTX 是半正定的,这是因为对于任何非零向量 v,vT(XTX)v=(Xv)T(Xv)=∥Xv∥2≥0。这表明 XTX 的所有特征值非负。
添加 λI之后
- 当我们在 XTX 中添加一个正数 λ 乘以单位矩阵 I,即 XTX+λI,我们实际上是在 XTX 的每个特征值上加上 λ。因为 I 的特征值都是1,所以 λI 的特征值都是 λ。
- 即使 XTX 是奇异的或者有零特征值,λI 的加入使得每个原始特征值 λi 变为 λi+λ。因为 λ>0,这确保了所有新的特征值都是正的。
保证正定和可逆性
- 正定:因为对于任意非零向量 v,都有 vT(XTX+λI)v=vTXTXv+λvTIv=∥Xv∥2+λ∥v∥2>0,所以 XTX+λI 是正定的。
- 可逆性:矩阵是正定的,则它没有零特征值,这意味着它是非奇异的,即可逆的。
加入扰动其实就是线性回归正则化的技术,特别是岭回归(Ridge Regression)的公式。这是一种处理特别是在存在多重共线性(自变量高度相关)时或为了防止过拟合而常用的技术
当 XTX 的行列式接近或等于零(即矩阵接近奇异或完全奇异),直接计算其逆会有问题,这通 常在特征数量多于样本数量或特征之间高度相关时发生。这会导致模型参数估计的不稳定性和大的方差。
为了克服这个问题,岭回归通过添加一个惩罚项 λI(其中 λ 是一个正的常数,I 是单位矩阵)到 XTX 中
-
惩罚项 λI:
- 惩罚系数 λ:这个系数控制了正则化的强度。λ 的值越大,对参数 θ 的惩罚越大,使得模型参数的值变得更小,这通常会降低模型的复杂度,有助于防止过拟合。
- 单位矩阵 I:添加到 XTX 的单位矩阵确保了正则化项只影响参数的估计值,而不改变其它统计性质。这样的修改提高了 XTX+λI 的条件数,从而使得矩阵更容易求逆,增加了数值稳定性。
-
统计意义:
- 通过引入惩罚项,岭回归有效控制了模型参数的大小,有助于处理共线性问题,降低模型在新数据上的预测误差,特别是当原始特征矩阵 X 不适合直接求逆时。
-
实际应用:
- 在实际应用中,选择合适的 λ 是关键,通常通过交叉验证等方法进行选择。
- 岭回归广泛用于包含大量预测变量的模型中,尤其是那些变量间存在复杂相关关系的情况。
梯度下降
对于损失函数 J(θ)=21∑i=1m(hθ(x(i))−y(i))2 ,可以得出其为凸函数
为什么损失函数一定为凸函数?
在线性回归模型中,常用的损失函数是平方误差损失,其形式为:
J(θ)=21i=1∑m(hθ(x(i))−y(i))2可以写成以下形式:
J(θ)=21(Xθ−y)T(Xθ−y)展开后,得到:
J(θ)=21θTXTXθ−θTXTy+const其中,const 是一个不依赖于 θ 的常数项。
-
矩阵 XTX 的性质:XTX 是设计矩阵 X 的转置乘以 X。这个矩阵是对称的,并且是半正定的。意味着对于任何非零向量 v,都有 vT(XTX)v≥0。
-
半正定矩阵和凸函数:一个函数如果是形式为 f(θ)=θTAθ+bTθ+c 的二次函数,其中 A 是半正定矩阵,则该函数是凸函数。在平方误差损失的情况下,矩阵 A 对应于 XTX。由于 XTX 是半正定的,这保证了损失函数 J(θ) 是关于 θ 的凸函数。
为什么形式为 f(θ)=θTAθ+bTθ+c 的函数在 𝐴 为半正定矩阵时,是一个凸函数?
凸函数的定义:一个函数 f:Rn→R 是凸的,则对于所有 θ1,θ2∈Rn 和所有 t∈[0,1],都满足:
f(tθ1+(1−t)θ2)≤tf(θ1)+(1−t)f(θ2)
二次函数的凸性
-
函数的梯度(一阶导数):
∇f(θ)=2Aθ+b
-
函数的海森矩阵(二阶导数):
H=∇2f(θ)=2A
海森矩阵 H 是衡量函数曲率的关键。如果海森矩阵是半正定的,那么该函数是凸函数。
半正定矩阵与凸性
-
半正定矩阵的特性:
半正定矩阵 A 的性质是:对于任何向量 v=0,都有 vTAv≥0,即函数 vTAv 的值永远是非负的。
-
海森矩阵的半正定性:
在上述二次函数中,海森矩阵 H=2A。因为 A 是半正定的,乘以正标量 2 不改变其半正定性。因此,H=2A 也是半正定的。
-
凸函数的确定:
如果海森矩阵 H 是半正定的,根据凸分析理论,函数 f(θ) 是凸函数。这是因为函数的曲率(由海森矩阵确定)在整个定义域内都是非负的,满足凸函数的定义。
对于凸函数,可以用梯度下降算法来求机制,相当于不断重复下式:
θj=θj−α⋆∂θj∂J
损失函数:J(θ)=2∗m1∑i=0m(hθ(X(i))−y(i))2=2∗m1∑i=1m(y^(i)−y(i))2
对每一个 θi(0≤i≤N) 求偏导:
⎩⎨⎧∂θ0∂J=m1((y^(1)−y(1))x0(1)+...+(y^(m)−y(m))x0(m))∂θ1∂J=m1((y^(1)−y(1))x1(1)+...+(y^(m)−y(m))x1(m))...∂θN∂J=m1((y^(1)−y(1))xN(1)+...+(y^(m)−y(m))xN(m))
其中 x0(i)≡1,换成矩阵形式:
∂θ∂J=m1XT(y^−y)
得出梯度下降公式就是:
θ′=θ−αm1XT(y^−y)
多项式扩展
在训练模型时,原始数据不都是线性关系,对于非线性关系的数据,就可以采用多项式扩展的方式来实现。
多项式扩展其实就是给原有的数据添加一些新的特征,这些新特征是原始特征的高次方或者不同特征之间的组合。通过这种方式,可以让简单的线性模型能够学习到数据中的非线性关系,从而提高模型的预测精度。
多项式扩展是一种提升模型能力的简单而有效的方法,尤其适用于处理那些原始特征与输出之间存在非线性关系的情况。通过这种方式,即使是简单的线性回归模型也能进行复杂的非线性数据拟合,但需要注意避免过拟合。
假如现在有一个实验,试图通过测量热水壶的电力消耗来预测它煮沸水的时间。如果仅使用电力消耗(瓦特数)作为特征,你可能会发现难以精确预测煮沸时间,因为实际上煮沸时间与电力消耗之间的关系可能不完全是直线(即线性)关系。
这时,多项式扩展就派上用场了。除了电力消耗,可以引入电力消耗的平方、立方等作为新的特征。这样,模型不仅考虑了电力消耗本身,还考虑了电力消耗的高次效应,可能更好地捕捉到煮沸时间的变化。
假设我们有以下简单的数据集:
电力消耗(瓦特) | 煮沸时间(分钟) |
---|
1500 | 4 |
1000 | 6 |
2000 | 3 |
如果直接用电力消耗来预测煮沸时间,可能得到不够准确的结果。但如果引入电力消耗的平方作为第二个特征,那么模型就有可能更好地理解数据:
- 原始特征:电力消耗 x
- 新特征:电力消耗的平方 x2
于是,特征就从单一的 x 扩展到了 x 和 x2。在实际应用中,可以使用机器学习中的工具来自动完成这种扩展,并用这些特征来训练我们的模型。
使用Python进行建模,可以用sklearn
库中的PolynomialFeatures
自动进行多项式扩展:
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
X = np.array([[1500], [1000], [2000]])
'''
用PolynomialFeatures来扩展特征
degree=2,扩展的阶数
interaction_only=False,是否只保留交互项
include_bias=True,是否需要偏置项
'''
poly = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)
X_poly = poly.fit_transform(X)
print(X_poly)
输出的 X_poly
将包含原始电力消耗及其平方值,可以直接用于模型训练。
过拟合与欠拟合
在机器学 习中,过拟合和欠拟合是两种常见的模型表现问题,它们反映了模型对训练数据和未见数据(如测试数据)的泛化能力。
欠拟合(Underfitting)
当一个模型在训练数据上没有很好的表现,即模型过于简单,没有捕捉到数据的基本关系时,就会发生欠拟合。这通常是因为模型不够复杂,无法学习数据中的所有信号
表现:
- 模型在训练集和测试集上的表现都不好
- 模型过于简单,例如线性模型试图捕捉非线性关系
原因:
解决方法:
- 增加更多特征
- 使用更复杂的模型
- 减少数据预处理中的简化
过拟合(Overfitting)
过拟合发生在模型在训练数据上表现得太好,以至于它学到了训练数据中的噪声而非潜在的数据分布。这种模型虽然在训练集上得分高,但是在新的或未见过的数据上表现差,因为它缺乏泛化能力
表现:
- 模型在训练集上表现出色,但在验证集或测试集上表现不佳
- 捕捉了数据中的随机噪声而非真正的输入与输出间的关系
原因:
- 模型复杂度过高
- 训练时间过长
- 训练数据量不足或包含噪声
解决方法:
- 简化模型,选择一个适当的模型复杂度
- 采用正则化技术(如L1、L2正则化)
- 使用更多的训练数据
- 采用交叉验证来调整模型参数
- 提前停止训练过程(例如,在验证误差开始增加时停止)
正则化
线性回归问题的损失函数后加上一项,称为正则化项:
J(θ0,θ1,⋯,θn)=2m1i=1∑m(hθ(X(i))−y(i))2+λΩ(θ)
通过添加正则化项来解决过拟合的问题就是正则化技术
L1正则化和L2正则化使用的优化算法是坐标下降(coordinate descent)
L1正则化
在L1正则化中,正则项通常形式如下:
Ω(θ)=j=1∑n∣θj∣
L1正则化的回归也称为Lasso(Least Absolute Shrinkage and Selection Operator,最小绝对收缩选择算子)回归
L1正则化倾向于产生稀疏的权重矩阵,即很多权重参数会变为零。这种特性使得L1正则化成为一种自然的特征选择方法,因为它可以帮助模型仅保留最重要的特征。
import pandas as pd
from sklearn.linear_model import Lasso, LassoCV
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
data = pd.read_csv('boston_housing.data', sep='\s+', header=None)
X = data.iloc[:, :-1]
Y = data.iloc[:, -1]
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=10)
poly = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)
x_train_poly = poly.fit_transform(x_train)
x_test_poly = poly.transform(x_test)
lasso = Lasso(alpha=0.1)
lasso.fit(x_train_poly, y_train)
y_test_hat = lasso.predict(x_test_poly)
y_train_hat = lasso.predict(x_train_poly)
print("Lasso Regression:")
print(f"系数: {lasso.coef_}")
print(f"