[大模型教我成为大模型算法工程师之day2:传统机器学习算法(上)]
Day 2: 传统机器学习算法(上)—— 从线性模型到SVM
写在前面:如果说数学是内功,那么算法就是招式。今天我们将正式踏入机器学习的江湖,从最简单直观的线性模型开始,一路打怪升级,直到掌握曾经的"算法之王" SVM。我们将遵循由易到难、从直觉到原理的路径,揭开这些经典算法的面纱。
目录
- 线性模型:回归与分类的基石
- 朴素贝叶斯:概率的力量
- 决策树与随机森林:从规则到集成
- 支持向量机 (SVM):数学美学的巅峰
- 算法大比拼与总结
1. 线性模型:回归与分类的基石
一切复杂的模型,往往都源于最简单的线性关系。
1.1 线性回归 (Linear Regression)
直觉:试图画一条直线(或高维平面),让它尽可能穿过所有的数据点。
数学表达:
f(x)=wTx+bf(\mathbf{x}) = \mathbf{w}^T \mathbf{x} + bf(x)=wTx+b
怎么才算"好"?
我们要最小化预测值与真实值之间的差距。最常用的是均方误差 (MSE):
L(w,b)=∑i=1n(yi−(wTxi+b))2L(\mathbf{w}, b) = \sum_{i=1}^{n} (y_i - (\mathbf{w}^T \mathbf{x}_i + b))^2L(w,b)=i=1∑n(yi−(wTxi+b))2
这就变成了一个优化问题(Day 1 中的凸优化)。
代码实战 (numpy手写 vs sklearn):
import numpy as np
from sklearn.linear_model import LinearRegression
# 生成数据
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
# 方式1: sklearn一把梭
lin_reg = LinearRegression()
lin_reg.fit(X, y)
print(f"Sklearn截距: {lin_reg.intercept_}, 系数: {lin_reg.coef_}")
# 方式2: 解析解 (Normal Equation) theta = (X^T X)^-1 X^T y
X_b = np.c_[np.ones((100, 1)), X] # 添加偏置项x0=1
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
print(f"解析解截距: {theta_best[0]}, 系数: {theta_best[1]}")
1.2 逻辑回归 (Logistic Regression)
不要被名字骗了,它是分类算法,不是回归算法。
核心思想:线性回归输出的是 (−∞,+∞)(-\infty, +\infty)(−∞,+∞) 的实数,怎么变成概率 [0,1][0, 1][0,1] 呢?
答案是Sigmoid函数:
σ(z)=11+e−z\sigma(z) = \frac{1}{1 + e^{-z}}σ(z)=1+e−z1
将线性输出 z=wTx+bz = \mathbf{w}^T \mathbf{x} + bz=wTx+b 压缩到 (0,1)(0, 1)(0,1) 之间。
决策边界:
- P(y=1∣x)>0.5⇒P(y=1|x) > 0.5 \RightarrowP(y=1∣x)>0.5⇒ 预测为正类
- 这一步等价于 wTx+b>0\mathbf{w}^T \mathbf{x} + b > 0wTx+b>0
损失函数:
MSE 不再适用(非凸),我们使用对数损失 (Log Loss),也就是交叉熵:
J(θ)=−1m∑i=1m[y(i)log(p^(i))+(1−y(i))log(1−p^(i))]J(\theta) = - \frac{1}{m} \sum_{i=1}^{m} [y^{(i)}\log(\hat{p}^{(i)}) + (1-y^{(i)})\log(1-\hat{p}^{(i)})]J(θ)=−m1i=1∑m[y(i)log(p^(i))+(1−y(i))log(1−p^(i))]
面试考点:逻辑回归是线性分类器还是非线性?
答:本质是线性分类器,因为它的决策边界 wTx+b=0\mathbf{w}^T \mathbf{x} + b = 0wTx+b=0 是线性的。但我们可以通过引入多项式特征,使其具备处理非线性数据的能力。
2. 朴素贝叶斯 (Naive Bayes)
这是基于 Day 1 讲过的贝叶斯定理的算法。
2.1 为什么叫"朴素"?
它做了一个极强的假设:特征之间相互独立。
即 P(x1,x2∣y)=P(x1∣y)P(x2∣y)P(x_1, x_2 | y) = P(x_1 | y) P(x_2 | y)P(x1,x2∣y)=P(x1∣y)P(x2∣y)。
虽然这在现实中几乎不可能成立(比如"虽然"和"但是"在文本中显然相关),但在垃圾邮件过滤、文本分类等任务中,它却出奇地有效且高效。
2.2 核心公式
P(y∣x1,…,xn)∝P(y)∏i=1nP(xi∣y)P(y|x_1, \dots, x_n) \propto P(y) \prod_{i=1}^{n} P(x_i|y)P(y∣x1,…,xn)∝P(y)i=1∏nP(xi∣y)
- P(y)P(y)P(y):先验概率(直接统计类别占比)
- P(xi∣y)P(x_i|y)P(xi∣y):似然概率(统计每个特征在各类中出现的频率)
from sklearn.naive_bayes import GaussianNB, MultinomialNB
# GaussianNB: 假设特征服从高斯分布(适合连续变量)
# MultinomialNB: 假设特征服从多项分布(适合文本词频)
clf = GaussianNB()
clf.fit(X_train, y_train)
# 预测就是查表+乘法,速度极快
3. 决策树与随机森林
如果说线性模型是数学家的工具,那决策树就是程序员的逻辑。
3.1 决策树 (Decision Tree)
直觉:就是一堆 if-else 规则的集合。
关键问题是:如何自动生成这些规则?先判断哪个特征?
这就用到了 Day 1 的信息论知识:我们希望每次分裂,都能让数据变得更"纯"。
常用的分裂指标:
- 信息增益 (ID3):分裂前后熵减少了多少?
Gain(D,A)=H(D)−∑∣Dv∣∣D∣H(Dv)Gain(D, A) = H(D) - \sum \frac{|D_v|}{|D|} H(D_v)Gain(D,A)=H(D)−∑∣D∣∣Dv∣H(Dv) - 信息增益比 (C4.5):解决了ID3偏向取值多特征的问题。
- 基尼系数 (CART):Sklearn 默认使用。
Gini(p)=1−∑pk2Gini(p) = 1 - \sum p_k^2Gini(p)=1−∑pk2
Gini系数越小,纯度越高。
3.2 随机森林 (Random Forest)
一棵树的问题:容易过拟合。如果树太深,它会记住每一个训练样本,但对新数据束手无策。
解决方案:三个臭皮匠,顶个诸葛亮——集成学习 (Ensemble Learning)。
随机森林属于 Bagging 类集成:
- 样本随机:有放回地采样 (Bootstrap),每棵树训练集不同。
- 特征随机:每个节点分裂时,只考虑随机选取的一部分特征。
优势:
- 准确率高,抗过拟合能力强。
- 可以并行训练(速度快)。
- 能输出特征重要性 (Feature Importance),这在工业界非常有用。
from sklearn.ensemble import RandomForestClassifier
# n_estimators: 树的数量
# max_depth: 树的最大深度(防止过拟合)
rf = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
rf.fit(X_train, y_train)
# 查看特征重要性
importances = rf.feature_importances_
4. 支持向量机 (SVM)
这是传统机器学习时代的"王者",数学推导最为优美,但也最难理解。
4.1 直觉:最大间隔
对于二分类问题,可能有无数条线能把两类分开。SVM 寻找的是中间那条最宽的马路。
- 这条马路中间的线就是决策边界。
- 马路边缘碰到样本点,这些点就是支持向量 (Support Vectors)。
- 其他样本点对模型没有任何影响(这让SVM具有很好的鲁棒性)。
4.2 核技巧 (Kernel Trick)
如果数据是线性不可分的怎么办?(比如圆环状数据)
核心思想:将低维空间的数据映射到高维空间,在低维纠缠不清的数据,在高维可能只需要切一刀就能分开。
直接计算高维映射 ϕ(x)\phi(x)ϕ(x) 计算量太大,核技巧允许我们在低维直接计算高维的内积:
K(xi,xj)=⟨ϕ(xi),ϕ(xj)⟩K(x_i, x_j) = \langle \phi(x_i), \phi(x_j) \rangleK(xi,xj)=⟨ϕ(xi),ϕ(xj)⟩
常见核函数:
- Linear Kernel:线性核,不做映射(快,适合高维稀疏数据如文本)。
- RBF Kernel (高斯核):最常用,将数据映射到无穷维空间。
K(x,y)=exp(−γ∥x−y∥2)K(x, y) = \exp(-\gamma \|x-y\|^2)K(x,y)=exp(−γ∥x−y∥2)
4.3 软间隔与C参数
现实数据往往有噪声,不仅不可分,还可能有一些异常点混在对方阵营里。
我们允许犯一点错,这就是软间隔。
参数 C 控制着对错误的容忍度:
- C 很大:容忍度低,试图把所有点都分对(容易过拟合)。
- C 很小:容忍度高,追求更宽的间隔(容易欠拟合,但泛化好)。
from sklearn.svm import SVC
# C: 正则化参数
# kernel: 核函数 ('linear', 'rbf', 'poly')
# gamma: 核系数,控制高斯核的"宽度"
svm_clf = SVC(kernel="rbf", C=1.0, gamma='scale')
svm_clf.fit(X_train, y_train)
5. 总结与算法大比拼
我们今天学习了四类经典算法,它们各有千秋:
| 算法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 逻辑回归 | 简单、解释性强、训练快 | 只能处理线性边界(除非特征工程) | 搜广推基线、二分类 |
| 朴素贝叶斯 | 极快、对缺失数据不敏感 | 独立性假设太强 | 文本分类、垃圾邮件 |
| 随机森林 | 准确率高、抗过拟合、无需特征缩放 | 模型较大、预测稍慢 | 表格数据竞赛首选 |
| SVM | 小样本效果好、数学理论完备 | 对噪声敏感、大样本训练慢 | 小样本、高维数据 |
实战建议
- 拿到数据,先跑一个 Baseline(通常用逻辑回归或随机森林)。
- 如果是表格数据 (Tabular Data),XGBoost/LightGBM (Day 3 内容) 通常是 SOTA。
- 如果是稀疏高维数据(如文本 TF-IDF),SVM (Linear) 或 LR 往往表现不错。
- 特征工程的重要性往往大于算法选择。
思考题:
- 为什么逻辑回归在工业界(如广告点击率预测)这么受欢迎?
- 随机森林需要做特征归一化吗?SVM呢?
(答案将在评论区揭晓)
📚 参考资源
- sklearn官方文档:机器学习的百科全书
- 《统计学习方法》李航:推导SVM的必读经典
- Visualizing SVM:网上有很多SVM的可视化演示,推荐搜来看看
明日预告:Day 3 我们将迎来集成学习的盛宴。XGBoost、LightGBM 这些在 Kaggle 拿奖拿到手软的神器,到底强在哪里?敬请期待!
如果有更多问题,欢迎关注公众号【算法最TOP】进一步讨论!
更多推荐
所有评论(0)