前言
想象一下:如果你知道一个人的身高,能否预测他的体重?如果你了解房屋的面积、位置、楼层等信息,能否估算出它的价格?这些看似神奇的问题,都可以通过线性回归来解决!
线性回归是机器学习中最基础、最经典的算法之一,也是踏入机器学习殿堂的必经之路。它就像一把神奇的钥匙,能够帮我们打开从数据中发现规律、预测未来的大门。
本篇将从最基础的概念出发,带你逐步理解:
- 什么是线性回归:从简单的一元线性回归到复杂的多元线性回归
- 如何求解线性回归:从损失函数到梯度下降,揭开算法背后的数学原理
- 如何评估模型效果:掌握MAE、MSE、RMSE等关键评估指标
- 实战案例演练:波士顿房价预测,将理论应用于实践
- 解决常见问题:欠拟合与过拟合的原因及解决方案
无论你是机器学习的初学者,还是想要巩固基础的进阶者,这篇文档都将为你打下坚实的线性回归基础。让我们一起开始这段探索之旅吧!
一、线性回归简介
1.1 线性回归概念
什么是线性回归?
定义:利用回归方程(函数)对一个或多个特征值和标签之间关系进行建模的一种分析方式。当这个模型是线性时,称为线性回归。
举个简单的例子
假设我们有了身高和体重数据,来了播仔的身高数据,你能预测播仔的体重吗?
思路:
- 先从已知身高X和体重Y中找规律
- 再对新数据进行预测
数学方法:用一条直线来拟合身高和体重之间的关系
方程形式:Y = kX + b
- k:斜率
- b:截距
例如:若求得 y = 0.9x + (-93)
- 预测身高176cm的体重:
0.9 × 176 + (-93) = 65.4
1.2 线性回归的分类
| 类型 | 公式 | 特点 |
|---|---|---|
| 一元线性回归 | y = wx + b | 目标值只与一个因变量有关系 |
| 多元线性回归 | y = w₁x₁ + w₂x₂ + ... + wₙxₙ + b | 目标值与多个特征有关系 |
1.3 应用场景
线性回归的应用场景非常广泛:
- 🌡️ 钢轨伸缩长度与温度的关系预测
- 🦗 昆虫鸣叫次数与天气的关系分析
- 📈 国内GDP与双十一销售额的相关性研究
- 🏠 房价预测:根据面积、位置、楼层等多特征预测价格
二、线性回归问题的求解
2.1 线性回归API
sklearn中的LinearRegression
导入方式:
python
from sklearn.linear_model import LinearRegression
基本使用流程:
python
# 1. 导入线性回归包
from sklearn.linear_model import LinearRegression
# 2. 准备数据
x = [[160], [166], [172], [174], [180]] # 身高数据
y = [56.3, 60.6, 65.1, 68.5, 75] # 体重数据
# 3. 实例化线性回归模型
estimator = LinearRegression()
# 4. 训练模型
estimator.fit(x, y)
# 5. 查看模型参数
print('斜率 coef_ -->', estimator.coef_) # 权重系数
print('截距 intercept_ -->', estimator.intercept_) # 偏置
# 6. 模型预测
myres = estimator.predict([[176]])
print('预测结果 -->', myres)
核心属性:
coef_:回归系数(权重)intercept_:截距(偏置)
2.2 损失函数
为什么需要损失函数?
通过线性回归API可以快速找到拟合结果,但是:
- 多个线性模型,哪个才是最优解?
- 如何评估模型的好坏?
误差与损失函数
误差:每个数据点预测值ŷ与真实值y的差值
损失函数:综合衡量"模型预测结果"和"真实值"之间的整体差异
常见损失函数
1. 平方损失函数
J(θ) = (ŷ - y)²
2. 均方误差(MSE)
MSE = (1/n) × Σ(yi - ŷi)²
特点:
- 误差有正有负,平方后均为正
- 综合所有样本的误差
- 损失函数值越小,模型拟合效果越好
2.3 正规方程法
数学原理
公式:
W = (XᵀX)⁻¹Xᵀy
其中:
- X:特征矩阵
- y:目标值向量
- W:权重参数向量
优缺点
| 优点 | 缺点 |
|---|---|
| 直接得到最优解 | 计算量大(涉及矩阵求逆) |
| 不需要迭代 | 特征维度很大时效率低 |
| 适用于小规模数据 | XᵀX不可逆时无法使用 |
2.4 梯度下降算法
什么是梯度下降?
梯度下降是一种迭代优化算法,通过沿着损失函数梯度的反方向更新参数,逐步找到损失函数的最小值。
核心公式
参数更新:
W = W - α × ∂J/∂W
其中:
- α:学习率(步长)
- ∂J/∂W:损失函数对权重的梯度
梯度下降的变体
| 方法 | 特点 |
|---|---|
| 批量梯度下降(BGD) | 使用全部样本计算梯度,收敛稳定但速度慢 |
| 随机梯度下降(SGD) | 每次使用一个样本,速度快但波动大 |
| 小批量梯度下降(MBGD) | 使用小批量样本,兼顾速度和稳定性 |
学习率的影响
- 学习率过大:可能错过最优解,无法收敛
- 学习率过小:收敛速度太慢,训练时间长
sklearn中的SGDRegressor
python
from sklearn.linear_model import SGDRegressor
# 实例化模型
estimator = SGDRegressor(
loss='squared_loss', # 损失函数类型
learning_rate='constant', # 学习率策略
eta0=0.01, # 初始学习率
max_iter=1000 # 最大迭代次数
)
# 训练和预测
estimator.fit(x, y)
predictions = estimator.predict(x_test)
2.5 正规方程 vs 梯度下降
| 对比项 | 正规方程 | 梯度下降 |
|---|---|---|
| 原理 | 直接求解 | 迭代优化 |
| 计算复杂度 | O(n³) | O(kn²) |
| 适用场景 | 小规模数据 | 大规模数据 |
| 特征缩放 | 不需要 | 需要 |
| 收敛性 | 一步到位 | 需要选择学习率 |
三、回归模型评估方法
3.1 MAE(平均绝对误差)
公式:
MAE = (1/n) × Σ|yi - ŷi|
特点:
- 直观反映预测误差的平均大小
- 对异常值不敏感
- 单位与原始数据相同
3.2 MSE(均方误差)
公式:
MSE = (1/n) × Σ(yi - ŷi)²
特点:
- 放大较大误差的影响
- 对异常值敏感
- 常作为损失函数使用
3.3 RMSE(均方根误差)
公式:
RMSE = √MSE = √[(1/n) × Σ(yi - ŷi)²]
特点:
- 结合了MSE的优点
- 单位与原始数据相同,便于理解
- 是最常用的评估指标之一
3.4 代码实现
python
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np
# 计算MSE
mse = mean_squared_error(y_true, y_pred)
# 计算RMSE
rmse = np.sqrt(mse)
# 计算MAE
mae = mean_absolute_error(y_true, y_pred)
print(f'MSE: {mse}')
print(f'RMSE: {rmse}')
print(f'MAE: {mae}')
四、线性回归案例:波士顿房价预测
4.1 案例背景
波士顿房价数据集是机器学习领域的经典数据集,包含506个样本,每个样本有13个特征:
| 特征 | 说明 |
|---|---|
| CRIM | 城镇人均犯罪率 |
| ZN | 住宅用地所占比例 |
| INDUS | 城镇中非住宅用地所占比例 |
| CHAS | 是否靠近查尔斯河 |
| NOX | 一氧化氮浓度 |
| RM | 住宅平均房间数 |
| AGE | 1940年以前建成的自住单位比例 |
| DIS | 距离五个波士顿就业中心的加权距离 |
| RAD | 距离高速公路的便利指数 |
| TAX | 不动产税率 |
| PTRATIO | 城镇中教师与学生比例 |
| B | 城镇中黑人比例 |
| LSTAT | 低收入人群比例 |
4.2 完整实现流程
python
# 1. 导入必要的库
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
import pandas as pd
# 2. 获取数据
boston = fetch_openml(name='boston', version=1, as_frame=True)
data = boston.data
target = boston.target
# 3. 数据集划分
x_train, x_test, y_train, y_test = train_test_split(
data, target, test_size=0.2, random_state=42
)
# 4. 特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 5. 模型训练
# 方法1:正规方程
estimator = LinearRegression()
estimator.fit(x_train, y_train)
# 方法2:梯度下降
# estimator = SGDRegressor(learning_rate='constant', eta0=0.01)
# estimator.fit(x_train, y_train)
# 6. 模型评估
y_pred = estimator.predict(x_test)
mse = mean_squared_error(y_test, y_pred)
print(f'均方误差: {mse}')
# 7. 查看模型参数
print(f'权重系数: {estimator.coef_}')
print(f'截距: {estimator.intercept_}')
4.3 模型优化建议
- 特征选择:分析特征重要性,去除冗余特征
- 特征工程:创建新的组合特征
- 正则化:使用Ridge或Lasso防止过拟合
- 交叉验证:使用交叉验证选择最佳超参数
五、欠拟合与过拟合
5.1 问题引入
在模型训练过程中,常常遇到两种极端情况:
训练集表现与测试集表现对比:
| 情况 | 训练集 | 测试集 | 问题类型 |
|---|---|---|---|
| 都不好 | 差 | 差 | 欠拟合 |
| 训练好测试差 | 好 | 差 | 过拟合 |
| 都好 | 好 | 好 | 理想状态 |
5.2 欠拟合
定义
模型学习到的特征过少,无法准确预测未知样本。
原因
- 模型复杂度不够
- 特征数量太少
- 训练时间不足
解决方法
-
添加其他特征项:挖掘更多有价值的特征
-
添加多项式特征:增加模型复杂度
pythonfrom sklearn.preprocessing import PolynomialFeatures poly = PolynomialFeatures(degree=2) X_poly = poly.fit_transform(X) -
减少正则化程度:减小正则化系数
5.3 过拟合
定义
模型学习到的特征过多,导致模型只能在训练样本上表现良好,在未知样本上效果差。
原因
- 模型过于复杂
- 训练数据太少
- 特征维度太高
- 存在噪声数据
解决方法
- 重新清洗数据:去除噪声和异常值
- 增大数据训练量:收集更多训练数据
- 减少特征维度:特征选择或降维
- 正则化:L1正则化或L2正则化
5.4 正则化
什么是正则化?
正则化是为了防止过拟合,在损失函数中加入正则化项,控制模型参数(尤其是高次项的权重参数)的大小。
L1正则化(Lasso回归)
损失函数:
J(θ) = MSE + α × Σ|wi|
特点:
- 会将某些特征的系数变为0
- 具有特征选择的功能
- 产生稀疏解
代码示例:
python
from sklearn.linear_model import Lasso
# alpha: 正则化系数,越大正则化力度越强
estimator = Lasso(alpha=0.1)
estimator.fit(X_train, y_train)
L2正则化(Ridge回归)
损失函数:
J(θ) = MSE + α × Σwi²
特点:
- 不会将系数变为0,但会使其变小
- 使权重系数更加平滑
- 工程开发中更常用
代码示例:
python
from sklearn.linear_model import Ridge
# alpha: 正则化系数
estimator = Ridge(alpha=1.0)
estimator.fit(X_train, y_train)
L1 vs L2 正则化对比
| 特性 | L1正则化 | L2正则化 |
|---|---|---|
| 系数变化 | 可变为0 | 趋近于0但不为0 |
| 特征选择 | 有 | 无 |
| 计算效率 | 较低 | 较高 |
| 适用场景 | 特征筛选 | 防止过拟合 |
| 工程建议 | 特征多且需要筛选时使用 | 一般场景优先使用 |
正则化系数α的影响
- α越大:正则化力度越强,权重系数越小
- α越小:正则化力度越弱,权重系数越大
- α=0:相当于无正则化
python
# 不同正则化强度的效果对比
for alpha in [0.001, 0.01, 0.1, 1.0, 10.0]:
ridge = Ridge(alpha=alpha)
ridge.fit(X_train, y_train)
print(f'alpha={alpha}, coefficients={ridge.coef_}')
六、总结
核心知识点回顾
线性回归
├── 基础概念
│ ├── 一元线性回归: y = wx + b
│ └── 多元线性回归: y = w₁x₁ + w₂x₂ + ... + b
│
├── 求解方法
│ ├── 正规方程法: W = (XᵀX)⁻¹Xᵀy
│ └── 梯度下降法: W = W - α × ∂J/∂W
│
├── 评估指标
│ ├── MAE: 平均绝对误差
│ ├── MSE: 均方误差
│ └── RMSE: 均方根误差
│
├── 常见问题
│ ├── 欠拟合 → 增加特征、多项式扩展
│ └── 过拟合 → 正则化、特征降维
│
└── 正则化
├── L1正则化 (Lasso): 产生稀疏解
└── L2正则化 (Ridge): 权重平滑
实践建议
- 数据预处理很重要:标准化处理能显著提升模型效果
- 选择合适的求解方法:小数据用正规方程,大数据用梯度下降
- 关注模型评估:不要只看训练集表现,测试集才是真实能力的体现
- 合理使用正则化:防止过拟合,提升模型泛化能力
进一步学习
- 推导正规方程和梯度下降的数学证明
- 学习其他回归算法:逻辑回归、决策树回归等
- 探索集成学习方法:随机森林、梯度提升树
- 实践更多回归案例:股票预测、销量预测等
💡 学习小贴士:线性回归虽然简单,但它是理解更复杂算法的基础。掌握好线性回归,就为后续学习逻辑回归、神经网络等算法打下了坚实的基础!