深度学习小白必备基础 | 手撕8大线性模型算法(回归与分类):原理+代码+实战,谁才是真神?
想象你是一家披萨店老板:
-
想通过"披萨直径"预测价格(线性回归)
-
想根据"配料数量+直径+芝士厚度"预测价格,但担心特征太多导致过拟合(岭回归/Lasso)
-
想判断一份订单"是否会投诉"(逻辑回归)
-
想给披萨分类:"素食/肉食/海鲜"(多分类逻辑回归/LDA) 这些问题,线性模型都能搞定!它就像一把把锋利的瑞士军刀——结构简单到小学生都能理解,却能解决80%的机器学习基础问题。从房价预测到癌症诊断,从股票分析到垃圾邮件过滤,到处都有它的身影。
最神奇的是:它用最简单的直线/平面/超平面(数学上的线性关系),就能拟合现实世界的复杂规律。这篇文章不仅会揭开它的数学奥秘,还会用实战代码让你亲眼见证:几行代码如何让线性模型在真实数据上大显神威!
➔➔➔➔点击查看原文,获取更多机器学习干货和资料!
https://mp.weixin.qq.com/s/p3efahsNNixoBDqe9cP0Rw
完整原理详解:线性模型的数学魔法
1. 线性回归(Linear Regression):最简单却最强大的预测工具
核心思想:用一条直线(或超平面)拟合自变量X和因变量y的关系。
数学公式:
其中:
-
是预测值
-
是偏置项(截距)
-
是特征权重(斜率)
-
是输入特征
训练目标:最小化预测值与真实值的平方差(最小二乘法):
几何意义:找到一条直线,让所有数据点到直线的垂直距离平方和最小。

线性回归
2. 岭回归(Ridge Regression):给线性回归装"刹车"防过拟合
解决问题:当特征存在多重共线性(如"房屋面积"和"房间数"高度相关),线性回归会出现权重过大的问题(过拟合)。
数学改进:在损失函数中加入L2正则化(权重平方和):
其中 是正则化强度:
-
:退化为普通线性回归
-
增大:权重被强制缩小("刹车"效果)
特点:会让所有特征的权重都变小,但不会归零(保留所有特征)。

岭回归
3. Lasso回归(Lasso Regression):会"自动踢掉无用特征"的回归
核心创新:用L1正则化替代L2正则化,实现特征选择:
神奇效果:当 足够大时,部分特征的权重会被压缩到0(相当于自动删除无用特征)。例如预测房价时,"房屋颜色"这类无关特征会被Lasso直接踢掉。
几何意义:L1正则化的约束是菱形,与损失函数等高线的交点更可能出现在坐标轴上(导致部分权重为0)。 
4. 弹性网络(Elastic Net):岭回归+Lasso的"强强联合"
解决问题:当特征数量远大于样本量时,Lasso可能只选一个特征而忽略其他相关特征。
数学公式:同时加入L1和L2正则化:
优势:既像Lasso那样能做特征选择,又像岭回归那样能处理多重共线性,是高维数据的首选。 
5. 逻辑回归(Logistic Regression):披着回归外衣的分类神器
核心思想:用Sigmoid函数将线性输出映射到[0,1]区间(概率),解决二分类问题(如"垃圾邮件/正常邮件")。
Sigmoid函数:
其中
预测规则:
训练目标:最大化对数似然函数:
等价于最小化交叉熵损失。

逻辑回归
6. 多分类逻辑回归(Multinomial Logistic Regression)
解决策略:将二分类扩展到多类(如"猫/狗/鸟"),常用"一对多"(One-vs-Rest):
-
为每个类别训练一个逻辑回归模型(如"猫vs非猫"、"狗vs非狗")
-
预测时取概率最大的类别
数学优化:直接使用Softmax函数输出多类概率:
其中 是第k类的线性输出。

多分类示意图(偏置未画出)
7. 线性判别分析(LDA):通过降维实现分类
核心思想:找到一个投影方向,让投影后的同类样本距离尽可能近,不同类样本距离尽可能远。
数学目标:最大化类间散度与类内散度的比值:
其中:
-
是类间散度矩阵(衡量类中心距离)
-
是类内散度矩阵(衡量类内样本分散程度)
优势:降低维度的同时保留分类信息,适合高维数据(如图像分类)。
8. 二次判别分析(QDA):LDA的"非线性兄弟"
与LDA的区别:LDA假设所有类的协方差矩阵相同(线性边界),QDA则允许每个类有自己的协方差矩阵(二次边界)。
适用场景:当数据呈现明显的非线性分布时(如圆形、椭圆形聚类),QDA分类效果更好,但需要更多样本估计协方差矩阵。
实战项目:模拟房价预测与鸢尾花分类大比拼
任务1:模拟房价预测(回归模型对比)
# 本地生成模拟房价数据(无需下载,瞬间生成)
np.random.seed(42) # 固定随机种子,结果可复现
n_samples = 2000 # 样本数量(适中,训练快)
# 生成4个真实影响房价的特征(贴合实际场景)
feature_names_reg = ["Area(sqm)", "Rooms", "Distance(km)", "YearBuilt"]
X_reg = np.zeros((n_samples, len(feature_names_reg)))
# 特征1:面积(60-180平方米,符合普通住宅范围)
X_reg[:, 0] = np.random.uniform(60, 180, n_samples)
# 特征2:房间数(2-5间,常见户型)
X_reg[:, 1] = np.random.randint(2, 6, n_samples)
# 特征3:距离市中心距离(1-20公里,越近房价越高)
X_reg[:, 2] = np.random.uniform(1, 20, n_samples)
# 特征4:建造年份(1980-2020年,新房更贵)
X_reg[:, 3] = np.random.uniform(1980, 2020, n_samples)
# 生成真实房价(基于特征的线性关系+少量噪声,模拟真实规律)
y_reg = (X_reg[:, 0] * 8000 + # 每平米涨8000元
X_reg[:, 1] * 50000 + # 每多1间房涨50000元
-X_reg[:, 2] * 12000 + # 每远1公里降12000元
(X_reg[:, 3] - 1980) * 2000 + # 每新1年涨2000元
300000 + # 基础房价30万
np.random.normal(0, 50000, n_samples)) # 随机噪声(±5万,模拟市场波动)
# 房价单位转换为"万元",更易读
y_reg = y_reg / 10000
# 划分训练集(80%)和测试集(20%)
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(
X_reg, y_reg, test_size=0.2, random_state=42
)
# 定义回归模型(带标准化,避免特征尺度影响)
reg_models = {
"Linear Regression (Basic)": Pipeline([
("scaler", StandardScaler()),
("model", LinearRegression())
]),
"Linear Regression (Poly)": Pipeline([
("scaler", StandardScaler()),
("poly", PolynomialFeatures(degree=2, include_bias=False)), # 2次多项式特征
("model", LinearRegression())
]),
"Ridge (λ=5)": Pipeline([
("scaler", StandardScaler()),
("model", Ridge(alpha=5, random_state=42))
]),
"Ridge (λ=20)": Pipeline([
("scaler", StandardScaler()),
("model", Ridge(alpha=20, random_state=42))
]),
"Lasso (λ=0.5)": Pipeline([
("scaler", StandardScaler()),
("model", Lasso(alpha=0.5, random_state=42))
]),
"Elastic Net (α=0.5, l1=0.7)": Pipeline([
("scaler", StandardScaler()),
("model", ElasticNet(alpha=0.5, l1_ratio=0.7, random_state=42)) # 偏L1正则
])
}
# 训练并评估回归模型
reg_results = {}
print("="*60)
print("Regression Model Training & Evaluation (Simulated House Price Data)")
print("="*60)
for name, model in reg_models.items():
# 训练
model.fit(X_train_reg, y_train_reg)
# 预测
y_pred = model.predict(X_test_reg)
# 评估指标
mse = mean_squared_error(y_test_reg, y_pred)
r2 = r2_score(y_test_reg, y_pred)
reg_results[name] = {"mse": mse, "r2": r2, "y_pred": y_pred, "model": model}
# 打印结果(清晰对齐)
print(f"{name:28} | MSE: {mse:8.4f} | R²: {r2:6.4f}")
print("="*60)

实验结果
任务2:鸢尾花分类(分类模型对比)
# 加载鸢尾花数据集(3类花,150样本×4特征)
from sklearn.datasets import load_iris
iris = load_iris()
X_clf = iris.data # 特征:花瓣长度、宽度等
y_clf = iris.target # 目标:0=山鸢尾,1=变色鸢尾,2=维吉尼亚鸢尾
feature_names_clf = iris.feature_names
class_names_clf = list(iris.target_names)
# 划分训练集和测试集
X_train_clf, X_test_clf, y_train_clf, y_test_clf = train_test_split(
X_clf, y_clf, test_size=0.2, random_state=42, stratify=y_clf # stratify保证类别分布一致
)
# 定义分类模型
clf_models = {
"Logistic Regression (Multi)": Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression(multi_class="multinomial", C=1.0, random_state=42))
]),
"Logistic Regression (OvR)": Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression(multi_class="ovr", C=1.0, random_state=42)) # 一对多策略
]),
"SGD Classifier (Linear)": Pipeline([
("scaler", StandardScaler()),
("model", SGDClassifier(loss="log_loss", penalty="l2", random_state=42)) # 线性SGD分类
]),
"LDA": Pipeline([
("scaler", StandardScaler()),
("model", LinearDiscriminantAnalysis())
]),
"QDA": Pipeline([
("scaler", StandardScaler()),
("model", QuadraticDiscriminantAnalysis())
])
}
# 训练并评估分类模型
clf_results = {}
print("="*60)
print("Classification Model Training & Evaluation (Iris Dataset)")
print("="*60)
for name, model in clf_models.items():
# 5折交叉验证(评估模型稳定性)
cv_scores = cross_val_score(model, X_train_clf, y_train_clf, cv=5, scoring="accuracy")
cv_acc = round(cv_scores.mean(), 4)
cv_std = round(cv_scores.std(), 4)
# 训练模型并测试
model.fit(X_train_clf, y_train_clf)
y_pred = model.predict(X_test_clf)
test_acc = round(accuracy_score(y_test_clf, y_pred), 4)
# 保存结果
clf_results[name] = {
"cv_acc": cv_acc,
"cv_std": cv_std,
"test_acc": test_acc,
"y_pred": y_pred,
"model": model,
"cv_scores": cv_scores
}
# 打印结果
print(f"{name:30} | CV Acc: {cv_acc:.4f} (±{cv_std:.4f}) | Test Acc: {test_acc:.4f}")
print("="*60)

classification results
各模型优缺点与适用场景
| 模型 | 优点 | 缺点 | 最佳适用场景 |
|---|---|---|---|
| 线性回归 | 简单易解释,计算快 | 无法处理非线性,易过拟合 | 特征与目标线性关系明确的回归问题 |
| 岭回归 | 解决共线性,防止过拟合 | 不做特征选择 | 特征多且可能相关的回归问题 |
| Lasso回归 | 自动特征选择,模型简洁 | 特征多且相关时可能选偏 | 高维稀疏数据(如基因数据) |
| 弹性网络 | 结合L1和L2优势,鲁棒性强 | 需要调两个参数 | 特征数量>样本量的回归问题 |
| 逻辑回归 | 输出概率,可解释性强 | 只能处理线性可分数据 | 二分类问题(如垃圾邮件识别) |
| 多分类逻辑回归 | 扩展简单,适合多类平衡数据 | 类别多时有偏差 | 类别少且线性可分的多分类 |
| SGD分类器 | 训练速度快,适合大规模数据 | 对学习率敏感,需数据标准化 | 在线学习、大规模分类任务 |
| LDA | 降维+分类一体,抗噪声强 | 假设数据正态分布,线性边界 | 高维数据分类(如图像、文本) |
| QDA | 捕捉非线性关系,分类边界灵活 | 需要更多样本,易过拟合 | 样本量大且类别分布差异大的数据 |
线性模型vs非线性模型:什么时候该选谁?
| 维度 | 线性模型 | 非线性模型(如决策树、SVM) |
|---|---|---|
| 可解释性 | ★★★★★(权重直接反映特征重要性) | ★☆☆☆☆(黑箱模型) |
| 训练速度 | ★★★★★(O(n)复杂度) | ★★☆☆☆(如SVM是O(n²)) |
| 处理非线性 | ★☆☆☆☆(需手动特征工程) | ★★★★★(自动捕捉非线性) |
| 对异常值敏感 | ★★★★☆(受极端值影响大) | ★★☆☆☆(如树模型抗噪声) |
| 内存占用 | ★★★★★(仅需存储权重) | ★★☆☆☆(如树模型存储结构复杂) |
经验法则:
-
先试线性模型:简单问题用简单模型,效果可能意外好
-
特征工程救场:若线性模型效果差,试试多项式特征(升维变线性)
-
数据量小必选:线性模型在小样本上更稳定,不易过拟合
-
解释优先必选:金融、医疗等领域需要解释决策原因,线性模型是首选
小白入门指南
-
代码跑起来:模拟数据无需下载,1分钟内跑完所有模型和可视化
- 调参小技巧:
-
岭回归/Lasso的λ:从小(0.1)到大(100)试,看MSE何时稳定
-
弹性网络的l1_ratio:0=纯岭回归,1=纯Lasso,0.5是平衡选择
-
逻辑回归的C值:越小正则化越强,防止过拟合
-
- 结果怎么看:
-
回归看R²(越接近1越好),分类看准确率(越高越好)
-
混淆矩阵对角线越亮,说明分类越准
-
特征权重图中,绝对值越大的特征对结果影响越强
-
线性模型是机器学习的"基石"——学会它,你就能理解更复杂模型(如神经网络的第一层其实就是线性变换)。赶紧运行代码,亲眼见证这些"数学魔术"的威力吧!
➔➔➔➔点击查看原文,获取更多机器学习干货和资料!
https://mp.weixin.qq.com/s/p3efahsNNixoBDqe9cP0Rw
更多推荐
所有评论(0)