线性回归:最简单也最深刻的 ML 模型
你以为线性回归很简单?神经网络的最后一层、几乎所有 ML 的起点——都是它。
线性回归是机器学习里最古老的算法——比”机器学习”这个词早 100 多年(高斯 1809 年就用过)。
但别小看它。你今天的所有 ML 项目都从它开始——要么直接用,要么作为 baseline,要么是某个更复杂模型的”最后一层”。
一句话定义
找一条直线(或超平面)来拟合数据。
最简单的形式:
- :输入特征
- :要预测的数值
- :模型参数(要训出来的)
一个具体例子
任务:根据房屋面积预测房价。
| 面积 (m²) | 房价 (万) |
|---|---|
| 50 | 100 |
| 80 | 180 |
| 100 | 230 |
| 120 | 280 |
| 150 | 350 |
直觉:每多 1 平米大约多 2.3 万。可以试 。
那 。模型训练就是找最佳的 。
怎么”训”
L1-03 我们手算过这个过程:定义损失函数,用梯度下降最小化。
损失函数(MSE)
均方误差——预测和真实之差的平方平均:
解析解(不用梯度下降也能算)
线性回归有个独特优势:最优解能直接用公式算出来,不需要迭代。
这就是最小二乘法——19 世纪的数学。今天 sklearn.LinearRegression 用的就是它。
小知识:当特征只有一个时,最小二乘有解析解(5 行代码就够)。多特征时,解析解涉及矩阵求逆——也能算,但样本超过 10 万时通常用梯度下降更快。
多元线性回归
实际数据有很多特征。比如房价不只看面积,还看:
- 卧室数(rooms)
- 地段评分(location)
- 房龄(age)
模型变成:
写成矩阵形式:
——这就是 L1-02 那个让你眼熟的公式。线性回归就是 的最简单实例。
用 sklearn 跑一遍
from sklearn.linear_model import LinearRegression
import numpy as np
# 数据
X = np.array([[50], [80], [100], [120], [150]])
y = np.array([100, 180, 230, 280, 350])
# 训练(一行)
model = LinearRegression()
model.fit(X, y)
# 看结果
print(f"w = {model.coef_[0]:.2f}") # ≈ 2.3
print(f"b = {model.intercept_:.2f}") # ≈ -5
# 预测
print(model.predict([[90]])) # ≈ 200
print(model.predict([[200]])) # ≈ 460
3 行训完,1 行预测。这就是 ML 工程的本质——大多数复杂工作都被 sklearn 这种库封装好了。
多特征版本
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# 假设我们有更完整的数据
df = pd.read_csv('housing.csv')
X = df[['area', 'rooms', 'location_score', 'age']]
y = df['price']
# 训练/测试切分
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)
# 评估
score = model.score(X_test, y_test)
print(f"R² = {score:.3f}")
# 查看每个特征的权重
for name, w in zip(X.columns, model.coef_):
print(f"{name}: {w:+.3f}")
权重可解释——这是线性回归的杀手锏:你能看出”卧室数对房价的影响是 +12 万/间”,“房龄每多 1 年降 5 千”。
假设
线性回归不是万金油。它有几个核心假设:
- 关系是线性的—— 真的和 大致成直线关系
- 特征之间没有强共线性(互相不重复)
- 残差服从正态分布(统计推断时需要)
- 方差相同(同方差性)
违反假设也能跑,但模型质量会下降。
不是线性怎么办
很多关系不是直线,比如房价 vs 面积可能是平方关系(豪宅溢价)。
招数:特征工程——把 也加进去作为新特征。
df['area_sq'] = df['area'] ** 2
X = df[['area', 'area_sq', 'rooms', ...]] # 现在能拟合曲线了
模型本身仍然是线性的(关于参数),但能拟合非线性数据——很强大的小技巧。
正则化(L2-07 详讲)
加点惩罚防止过拟合:
| 名字 | 公式 | 效果 |
|---|---|---|
| Ridge(L2) | 让所有权重小一点 | |
| Lasso(L1) | 让一些权重直接 = 0(特征选择) | |
| ElasticNet | L1 + L2 混合 | 兼顾 |
from sklearn.linear_model import Ridge, Lasso
model = Ridge(alpha=1.0)
model.fit(X_train, y_train)
# 或
model = Lasso(alpha=0.1)
model.fit(X_train, y_train)
print(model.coef_) # 看哪些特征被压到 0
优缺点
✅ 优点:
- 训练超快(小数据集毫秒级)
- 可解释性极强(每个权重的意义清楚)
- 是任何 ML 项目的第一基线
- 数学性质清晰,统计推断成熟
❌ 缺点:
- 表达能力有限(不能学复杂非线性)
- 对异常值敏感
- 假设较多
真实业务中的角色
很多人以为”经典 ML 都过时了”——错。线性回归仍然是工业界最常用的算法之一:
- A/B 测试:测算某项改动对 KPI 的”边际贡献”——核心就是线性回归
- 保险定价:保费 = 基础费 + 各风险因素 × 权重——纯线性回归
- 经济学模型:估算”政策对失业率的影响”——计量经济学的基础
- 任何项目的 baseline:先跑个线性回归看看,如果比它好太多再考虑复杂模型
一个真相:绝大多数业务问题,线性回归 + 良好特征工程,已经能拿到 80% 的效果。如果你做不到那 80%,再复杂的模型也救不了你。
深度神经网络的最后一层(输出层)—— 通常就是一个线性回归。
LLM 输出每个 token 的 logits 也是——用一个 矩阵把隐藏状态映射到词表大小的向量。
线性回归不是”简单算法”——它是 ML 世界里最重要的”积木”。
下一篇:《逻辑回归与分类:从回归到决策》 —— 同样的思路,怎么从”预测数值”扩展到”预测类别”。
读到这里说明你认真在学 🎯
订阅每周精选 —— 下一篇新文章 / 新可视化第一时间送到邮箱。
讨论区
· 用 GitHub 账号登录评论src/components/Comments.astro 顶部填入
仓库 ID 和分类 ID(见组件注释里的配置步骤)。