机器学习算法笔记——线性回归
机器学习算法笔记——线性回归
线性回归是机器学习中最基础的算法之一,广泛应用于预测分析和数据建模。本文将从线性模型和回归分析的基本概念出发,深入讲解线性回归的参数估计方法,包括最小二乘法、极大似然估计和梯度下降。同时,本文还将探讨线性回归的模型拓展,如对数线性回归和引入正则化的线性回归。
📖概念
字面意思就是建立线性模型进行回归分析。
线性回归可以是一维的(如一元线性回归),也可以是多维的(如多元线性回归),涉及多个自变量。通过拟合一条直线(二维空间)或一个超平面(多维空间)来进行预测。
❓什么是线性模型
线性模型的核心思想是建立自变量(特征)与因变量(预测值)之间的线性关系,即当自变量发生变化时,因变量也会按照一个固定的比率发生变化,这个比率就是模型的权重,在回归方程中也叫回归系数。
假设数据有d维的特征,它们的线性组合符合公式:
,一个d元一次函数
简写一下,用向量形式表示:
,输出f(x)是输入特征的一个仿射变换①
这里的w^T表示权重向量(行向量),x表示特征列向量(列向量),截距b是偏置项;转置T的意义是把列向量w转为行向量(类似矩阵乘法),使w^Tx结果为标量,方便与b相加。
狭义的线性模型如上所述,指的是自变量上不可能有高次项,自变量与标签之间不能存在非线性关系的模型;广义的线性模型包括岭回归、lasso回归、Elastic Net、逻辑回归、线性判别分析等。
❓什么是回归分析
为一个或多个自变量与因变量之间的关系建模的方法,预测因变量的数值。
回归经常用来表示输出与输出之间的关系。
🎲参数估计
机器学习求解参数的过程被称为参数估计。
线性回归的核心是求解最佳拟合曲线,对应到模型本身就是求解最优的w和b,使得新样本预测的误差尽可能小。什么情况下模型的参数最优呢?肯定是模型质量最优的时候,因此引入模型常用的性能度量——损失函数。
损失函数能量化实际值与预测值的差距,损失越小,模型自然越优。
线性回归本质是一个最优化问题,存在解析解②。
❎最小二乘法
回归任务中最常用的损失函数是均方误差(mean squared error),基于均方误差最小化来求解的方法称为“最小二乘法”。几何意义是,找到一条直线,使所有样本到直线上的欧式距离之和最小。
对于一元线性回归:
损失函数的计算公式为
这里E(w,b)是关于w和b的凸函数③,因此局部最优解就是全局最优解,可以在导数为0时找到。
分别对w和b求导,然后令结果为0,可以得到w和b的最优解。
对于多元线性回归:
先将偏置b合并到参数w中(合体为
),合并方法是在包含所有参数的矩阵中增加一列。把损失
最小化的公式转换为
对
求导,然后令结果为0,得到解析解
当
为满秩矩阵④或正定矩阵⑤时,线性回归模型存在唯一的解析解。
用最小二乘法进行线性回归(调用scikit-learn的LinearRegression)
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
# 随机生成一个数据集,假设y与X1有较强的线性关系,同时与X2也有一定的关系
data = {
'X1': np.random.rand(100),
'X2': np.random.rand(100),
'y': np.random.rand(100) * 2 + np.random.rand(100)
}
df = pd.DataFrame(data)
# 计算特征相关性矩阵
corr_matrix = df.corr()
print(corr_matrix)
# 基于相关性分析,选择X1作为特征进行线性回归
X = df[['X1']] # 选择特征列
y = df['y'] # 目标变量
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建并训练模型,默认使用最小二乘法计算最佳拟合系数
model = LinearRegression()
model.fit(X_train, y_train)
# 使用模型进行预测
y_pred = model.predict(X_test)
# 计算并打印模型的评估指标
print('系数: ', model.coef_)
print('截距: ', model.intercept_)
print('均方误差: ', mean_squared_error(y_test, y_pred))
# 检验线性回归分析模型的拟合程度
score = model.score(x,y)
print(score)
# 绘制拟合散点的直线
plt.scatter(x,y)
plt.plot(x, model.predict(x))
plt.xlabel('X1')
plt.ylabel('Y')
plt.show()
📈极大似然估计
理解似然函数
似然函数用于描述在不同参数下真实数据发生的概率,其值表示在给定样本数据下,参数取某一特定值的“可能性”或“似然性”。
与概率的“已知背后原因、推测结果发生概率”不同,似然反映的是:已知结果、反推原因。以抛硬币举例,似然函数表示基于“硬币抛掷6正4反”的结果,反推“硬币不是正反均匀的,每次出现正面的可能性是0.6”。单个观测结果发生的可能性为P(θ),如果各观测之间相互独立,那么多个观测数据同时发生的概率可表示为各个样本发生的概率的乘积。两次抛掷硬币之间互不影响,因此硬币正面朝上的概率可以用各次概率的乘积来表示。
假设P(硬币为正)=θ,则P(硬币为反)=1-θ。基于硬币“6正4反”的事实得到的似然函数表示为:
公式的几何曲线如下所示,可以看出:参数θ为0.6时,似然函数最大,得出“每次出现正面的可能性是0.6”的上述推论。
标题“6正4反”的似然函数曲线
推广到更为一般的场景,似然函数的一般形式可以用下面公式来表示,也就是之前提到的,各个样本发生的概率的乘积。
极大似然估计推导
极大似然估计就是寻找最优参数,让似然函数最大化,或者说,使用最优参数时观测数据发生的概率最大。
线性回归的一大假设是:误差服从均值为0的正态分布,且多个观测数据之间互不影响,相互独立。这使得模型的参数估计具有统计上的合理性。
正态分布的概率密度公式为:
既然误差服从均值为0的正态分布,那么误差的分布满足:
由于误差项是预测值与真实值之间的差异,用公式表示为:
又由于似然函数是各样本发生概率的乘积,最终似然函数可以表示为:
其中,x^{(i)}和y^{(i)}都是观测到的真实数据,是已知的,w是需要去求解的模型参数。
对L(w)取log对数以简化运算,化简得到:
忽略前面的系数,再加一个负号,转化成最小化问题,得到和最小二乘法几乎一样的损失函数,
(真实值-预测值)的平方和:
后面的参数求解过程与最小二乘一模一样,不再赘述。
📉梯度下降
线性回归的损失函数
是一个凸二次函数,这意味着它只有一个全局最小值点。对于函数值的变化,沿着梯度⑥方向的变化速度最快。因此,使用梯度下降方法可以高效地找到这个最小值点,并求得最优的模型参数。
一个简单的思路是,以均方误差作为损失函数,先确定模型参数的初始值(随机初始化),再对数据集所有样本的损失均值计算梯度,沿着负梯度方向更新参数,并不断迭代这一步骤,直至损失足够小时终止。这种遍历全量数据的方案叫做“批量梯度下降”(Batch Gradient Descent,BGD)。
批量梯度下降在更新参数时把所有样本都考虑进去,当数据量大、特征多时,每次迭代都使用全量数据并不现实,且存在很多冗余信息。出于模型性能和训练开销的考虑,一种妥协方法是,每次更新参数时,只随机抽取部分样本。极端情况下,每次迭代时随机抽取一条样本,使用单个样本来更新本次迭代的参数,这个算法被称为“随机梯度下降”(Stochastic Gradient Descent,SGD)。
折中以上两种方案,也可以随机抽取小批量样本计算梯度,这样既降低了SGD中随机性带来的噪音,又比BGD更高效。这种变体叫做“小批量随机梯度下降”(Mini-batch SGD)。
在每次迭代中,先随机抽取一个小批量样本B,计算B的梯度
,然后更新参数:
如此循环,让损失函数
逐渐变小直至等于或无限接近最小值点。这里需要手动预设两个参数:批量大小(batch size)和学习率
(learning rate)。批量大小表示每次参数更新时用于训练的样本数量|B|;学习率
用于控制下降时的步长,假设不把
设置的过大,迭代次数足够多,梯度下降法总能收敛到全局最小值。
线性回归恰好是一个在整个域只有一个最小值的学习问题,但是对像深度神经网络这样复杂的网络来说,损失平面上往往包含多个最小值,需要采用更为复杂的优化算法和技巧,如动量、学习率衰减、批量归一化等,以帮助模型逃离局部最优解,找到更好的全局最优解。
用随机梯度下降进行线性回归(调用scikit-learn的SGDRegressor),加入数据标准化操作
import numpy as np
from sklearn.linear_model import SGDRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_regression
from sklearn.metrics import mean_squared_error
# 创建模拟线性回归数据
X, y = make_regression(n_samples=100, n_features=1, noise=0.1)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数据标准化,调整到均值为0,标准差为1的标准正态分布,使梯度下降更快收敛
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 初始化SGDRegressor,默认使用均方误差作为损失函数,loss='squared_loss'
# tol=1e-3 意味着当损失函数的改进小于0.001时,SGD会停止优化。
# penalty=None 表示不使用正则化,可选'l1'、'l2','elasticnet'
# 设置learning_rate='constant'以使用固定学习率,设置学习率eta0=0.01
# 设置random_state 以确保结果可复现
# 设置批量大小batch_size=32
reg = SGDRegressor(max_iter=1000, tol=1e-3, penalty=None,
learning_rate='constant', eta0=0.01,
random_state=42, batch_size=32)
# 训练模型
reg.fit(X_train_scaled, y_train)
# 评估模型
score = reg.score(X_test_scaled, y_test)
print(f"Test R^2: {score:.2f}")
# 使用模型进行预测
y_pred = reg.predict(X_test_scaled)
# 可以在这里进行其他操作,如计算参数和MSE、绘制回归线等,代码同上一节
总结
直观上来说,最小二乘法是在寻找观测数据与回归超平面之间的误差距离最小的参数;最大似然估计是最大化观测数据发生的概率,而梯度下降通过不断地在损失函数递减的方向上更新参数来降低误差。
最小二乘法比较直观,很容易解释,通常用于线性回归等简单模型的参数估计,但不具有普遍意义,对于更多其他机器学习问题,比如二分类和多分类问题,最小二乘法就难以派上用场了。
极大似然估计则更适用于概率模型,尤其是当数据的概率分布已知或可以假设时,但对于某些非概率模型,如支持向量机(SVM)或决策树,极大似然估计的适用性会受到限制。
梯度下降的优点是广泛适用于各种模型和损失函数,尤其是深度神经网络,且可以通过调整学习率和迭代次数来控制优化过程。然而,梯度下降也可能面临一些问题,如在高维且稀疏的数据集中,梯度下降可能会面临计算量大、收敛速度慢的问题;对于非连续或不可导的损失函数,无法计算梯度,梯度下降显然并无用武之地;此外,对于非凸损失函数的优化问题,梯度下降可能只能找到局部最优解而非全局最优解。
💫模型拓展
💦对数线性回归
令模型预测逼近真实值y的对数,即
,实质上是令
逼近y。形式上还是线性回归的,但实质上已是在求取输入空间到输出空间的非线性函数映射。
🎃线性回归引入正则化
在多元线性回归中,如果包含过多的自变量(特征),模型可能变得过于复杂,导致过拟合。
当X^TX不满秩时,意味着X的列向量(特征)之间存在线性关系,即存在多重共线性。这导致方程
的解析解解析解
不是唯一的。
通过引入正则化,向模型增加一种“先验知识”或“偏好”,使得模型在优化过程中更倾向于选择那些简单且有效的解。
- 其中之一是岭回归(Rigde Regression,RR)。专门用于处理多重共线性问题。通过增加L2范数项来调整损失函数,对特征的系数进行缩减,但始终保留;岭回归并不追求最小二乘法所强调的无偏估计,允许牺牲一部分的信息和精度。
- Lasso回归通过增加L2范数项来调整损失函数,产生稀疏参数,即让某些系数变成0,实现明确的特征选择。
- 弹性网(elastic net)正则化方法,通过线性组合L1和L2兼具lasso和岭回归的内容。
注释
① 仿射变换:通过加权和对特征进行线性变换,并通过偏置项进行平移
② 解析解: 也叫闭式解,是通过公式直接得出的、具有明确函数形式的解
③ 凸函数:凸函数上任意两点所作割线一定在这两点间的函数图象的上方。U型曲线的函数如f(x)=x^2,通常是凸函数。
④ 满秩矩阵:矩阵的秩等于阶数。没有多余信息、行列都线性独立的方阵,它的行列式不为零,是可逆的。在解线性方程组时,如果系数矩阵是满秩的,那么方程组有唯一解。
⑤ 正定矩阵:是满秩的、可逆的矩阵。矩阵是对称的,所有特征值均为正。正定矩阵与任何非零向量的乘积都大于零。
⑥ 梯度:表示函数在每个点上的斜率或或变化率,数学上用导数表示。由于数据一般是多维特征,对模型求梯度即对各维度分量分别求偏导数,求得的梯度是一个向量,包含了函数变化的速率和方向。
参考资料
- 周志华《机器学习》P53-57
- 李沐《动手学深度学习》第三章3.1
- 最大似然估计