🧠 集成学习(Ensemble Learning)
集成学习通过组合多个“弱学习器”,构建一个更强、更稳定、泛化能力更好的“强学习器”。核心思想:“三个臭皮匠,顶个诸葛亮”。
✅ 一、为什么集成学习有效?
1. 降低方差(Variance)→ Bagging 类方法
- 多个模型平均预测 → 减少过拟合
- 如:随机森林
2. 降低偏差(Bias)→ Boosting 类方法
- 逐步修正错误 → 提升拟合能力
- 如:AdaBoost、GBDT
3. 提升泛化能力
- 模型“好而不同” → 错误相互抵消
- 对噪声、异常值更鲁棒
🧩 二、三大主流方法对比
| 方法 | 核心思想 | 代表算法 | 是否串行 | 降低偏差 | 降低方差 | 是否并行 |
|---|---|---|---|---|---|---|
| Bagging | 并行训练,平均/投票 | 随机森林 | ❌ | ❌ | ✅ | ✅ |
| Boosting | 串行训练,关注错误样本 | AdaBoost, GBDT, XGBoost | ✅ | ✅ | ✅(后期) | ❌ |
| Stacking | 用预测结果训练元模型 | 二级模型(如逻辑回归) | 混合 | ✅ | ✅ | 部分 |
🌳 三、Bagging(Bootstrap Aggregating)
✅ 核心思想
- 有放回抽样生成多个训练子集(Bootstrap)
- 并行训练多个基学习器
- 最终预测:分类→投票,回归→平均
🧮 公式(回归)
设 $T$ 个基学习器 $h_1, h_2, …, h_T$:
(分类任务为多数投票)
🌰 代表算法:随机森林(Random Forest)
- 在 Bagging 基础上,**随机选择特征子集**进行分裂 → 增加多样性
- 天然支持 OOB 误差估计
✅ 优点
- 并行训练,速度快
- 显著降低方差,抗过拟合
- 自带特征重要性、OOB 评估
⚡ 四、Boosting(提升法)
✅ 核心思想
- 串行训练:每轮根据前一轮错误调整样本权重或拟合残差
- 关注难样本 → 逐步提升性能
- 最终模型为加权组合
🧮 公式(加法模型)
- $\alpha_t$:第 $t$ 个学习器的权重
- $h_t$:第 $t$ 个弱学习器
📈 常见算法
1. AdaBoost(Adaptive Boosting)
- 调整样本权重:错分样本权重增加
- 学习器权重:$\alpha_t = \frac{1}{2} \ln \left( \frac{1 - e_t}{e_t} \right)$,$e_t$ 为加权错误率
2. GBDT(Gradient Boosting Decision Tree)
- 拟合负梯度(残差):$r_{ti} = - \left[ \frac{\partial L(y_i, H_{t-1}(\mathbf{x}_i))}{\partial H_{t-1}(\mathbf{x}_i)} \right]$
- 用决策树拟合残差,逐步逼近目标
3. XGBoost / LightGBM / CatBoost
- GBDT 的高效工业实现
- 支持并行、正则化、缺失值处理、类别特征等
✅ 优点
- 精度极高,Kaggle 常胜将军
- 支持特征重要性
- 可处理非线性关系
⚠️ 缺点
- 串行训练 → 速度慢
- 易过拟合 → 需控制学习率、早停、正则化
🧠 五、Stacking(堆叠)
✅ 核心思想
- 训练多个**异构基学习器**(如 SVM + 决策树 + 逻辑回归)
- 用它们的**预测结果作为新特征**,输入“元学习器”进行最终预测
🧮 公式
设 Level 1 有 个模型,预测为
设 Level 1 有 $T$ 个模型,预测为 $z_1, z_2, …, z_T$
元学习器:
- $g$:元学习器(如逻辑回归、XGBoost)
🧩 两层结构示例
Level 1: [LogisticRegression, SVM, RandomForest] → 输出预测(验证集)
Level 2: LogisticRegression(以 Level 1 输出为输入)→ 最终预测
✅ 优点
- 融合不同模型优势,性能常最优
- 灵活性高
⚠️ 缺点
- 易过拟合 → 必须用交叉验证构造 Level 1 特征
- 实现复杂
🛠️ 六、伪代码示例
▶︎ Bagging
for t in 1 to T:
D_t = bootstrap_sample(D) # 有放回抽样
h_t = train_base_learner(D_t) # 训练基学习器
ensemble.add(h_t)
def predict(x):
predictions = [h_t(x) for h_t in ensemble]
return average(predictions) # 回归:平均;分类:投票
▶︎ AdaBoost
初始化样本权重 w_i = 1/n
for t in 1 to T:
h_t = train_weak_learner(D, w) # 带权重训练
e_t = compute_weighted_error(h_t, D, w)
alpha_t = 0.5 * ln((1 - e_t) / e_t)
update_weights(w, h_t, alpha_t) # 提高错分样本权重
ensemble.add((h_t, alpha_t))
def predict(x):
score = sum(alpha_t * h_t(x) for h_t, alpha_t in ensemble)
return sign(score)
▶︎ Stacking(简化版)
# Level 1: 训练多个基模型
models = [LogisticRegression(), SVM(), DecisionTree()]
level1_preds = []
for model in models:
model.fit(X_train, y_train)
val_pred = model.predict(X_val) # 预测验证集(需交叉验证防泄漏)
level1_preds.append(val_pred)
# 构建新训练集
X_meta = np.column_stack(level1_preds)
meta_learner = LogisticRegression()
meta_learner.fit(X_meta, y_val)
# 预测
test_preds = [model.predict(X_test) for model in models]
X_test_meta = np.column_stack(test_preds)
final_pred = meta_learner.predict(X_test_meta)
📊 七、基学习器选择
📌 理想基学习器:
- 有一定准确性(不能太差)
- “好而不同”(多样性)
✅ 最常用:**决策树**(易构造弱学习器、支持多分类、无需预处理)
✅ 其他可选:神经网络、SVM、朴素贝叶斯、KNN
🎓 八、关键概念
1. 偏差-方差分解
- Bagging → 主要降低方差
- Boosting → 主要降低偏差(初期),后期可能增加方差
- Stacking → 同时降低偏差和方差
2. 多样性(Diversity)
模型需“好而不同”,否则集成=单模型。
📌 增加多样性方法:
- Bagging:数据扰动(Bootstrap)
- Random Forest:特征扰动
- Boosting:算法扰动(关注不同样本)
- Stacking:模型扰动(不同类型模型)
🚀 九、工业界应用
| 算法 | 应用场景 |
|---|---|
| 随机森林 | 金融风控、医疗诊断、特征选择 |
| XGBoost | Kaggle、广告点击率、推荐系统 |
| LightGBM | 大数据、高维稀疏特征(如推荐) |
| CatBoost | 类别特征丰富场景 |
| Stacking | 模型融合、竞赛冲榜 |
🧩 聚类(Clustering)
聚类是无监督学习的核心任务,目标是“物以类聚”——在没有标签的情况下,根据样本相似性自动分组,使得“组内相似,组间不同”。
✅ 一、聚类 vs 分类
| 聚类(Clustering) | 分类(Classification) | |
|---|---|---|
| 学习类型 | 无监督 | 有监督 |
| 是否有标签 | ❌ 没有 | ✅ 有 |
| 目标 | 发现数据内在结构 | 预测新样本类别 |
| 输出 | 簇编号(如 0,1,2…) | 预定义类别(如猫、狗、鸟) |
| 评估 | 无绝对标准,常用轮廓系数等 | 准确率、F1、AUC 等 |
📌 聚类是“探索性分析”,分类是“预测性建模”
🧭 二、三大主流聚类算法对比
| 算法 | 核心思想 | 是否需指定簇数 | 是否凸形簇 | 是否需距离度量 | 是否抗噪 |
|---|---|---|---|---|---|
| K-Means | 最小化簇内平方误差 | ✅ 需指定 K | ✅ | ✅ | ❌ |
| 层次聚类 | 自底向上合并 / 自顶向下分裂 | ❌ 可事后选 | ✅ | ✅ | ❌ |
| DBSCAN | 基于密度,自动发现簇和噪声 | ❌ 不需指定 | ❌(任意形状) | ✅ | ✅ |
🌟 三、K-Means(最经典、最常用)
✅ 核心思想
- 随机初始化 K 个质心
- 迭代:分配样本 → 更新质心 → 收敛
🧮 目标函数(簇内平方误差 SSE)
- $C_i$:第 $i$ 个簇
- $\mu_i$:第 $i$ 个簇的质心(均值)
🔄 算法步骤
- 随机初始化 K 个质心 $\mu_1, \mu_2, …, \mu_K$
分配(Assignment):对每个样本 $\mathbf{x}^{(i)}$,分配到最近质心:
更新(Update):对每个簇 $k$,重新计算质心:
- 重复 2~3,直到收敛或达到最大迭代
✅ 优点
- 简单、高效、易实现
- 适合大数据集
- 结果可解释(质心=群体代表)
❌ 缺点
- 必须预先指定 K
- 对初始质心敏感 → 推荐用 K-Means++ 初始化
- 只能发现“球形”或“凸形”簇
- 对噪声和异常值敏感
- 对特征尺度敏感 → 必须标准化!
🌳 四、层次聚类(Hierarchical Clustering)
✅ 核心思想(凝聚法,Agglomerative)
- 每个样本自成一类 → 逐步合并最相似的类 → 形成树状图(Dendrogram)
📏 簇间距离度量方式
- 单链(Single Linkage):两个簇中最近两个样本的距离 → 易形成“链状”
- 全链(Complete Linkage):两个簇中最远两个样本的距离 → 倾向“紧凑”簇
- 平均链(Average Linkage):两个簇中所有样本对的平均距离 → 折中
✅ 优点
- 不需要预先指定 K
- 可视化好(树状图)
- 结果稳定(无随机性)
❌ 缺点
- 计算复杂度高($O(n^3)$)→ 不适合大数据
- 一旦合并不能撤销 → 贪心算法,局部最优
- 对噪声敏感
🌀 五、DBSCAN(基于密度)
✅ 核心思想
- 基于“密度”:簇是“高密度区域”,被“低密度区域”分隔
- 能发现任意形状的簇
- 自动识别噪声点
🎛️ 关键参数
- eps(ε):邻域半径
- MinPts:核心点所需的最小邻居数
📌 三个概念
- 核心点(Core Point):在 eps 范围内,邻居数 ≥ MinPts
- 边界点(Border Point):邻居数 < MinPts,但属于某个核心点的邻居
- 噪声点(Noise Point):既不是核心点也不是边界点
✅ 优点
- 不需要指定簇数 K
- 可发现任意形状簇(如月牙形、环形)
- 自动识别噪声点
- 对异常值鲁棒
❌ 缺点
- 对参数 eps 和 MinPts 敏感
- 高维数据中“距离失效” → 效果下降(维度灾难)
- 密度差异大的数据效果不好
📊 六、聚类评估指标
✅ 1. 内部指标(无真实标签)
(1)轮廓系数(Silhouette Coefficient)
- $a(i)$:样本 $i$ 到同簇其他样本的平均距离
- $b(i)$:样本 $i$ 到最近其他簇所有样本的平均距离
- $s(i) \in [-1, 1]$,越接近 1 越好 → 对所有样本求平均
(2)Calinski-Harabasz Index(CH 指数)
→ 值越大,聚类效果越好
(3)Davies-Bouldin Index(DBI)
- $S_i$:簇 $i$ 的平均簇内距离
- $d(c_i, c_j)$:簇 $i$ 与 $j$ 质心距离
- → 值越小越好
✅ 2. 外部指标(有真实标签,用于实验)
- 调整兰德指数(Adjusted Rand Index, ARI)
- 互信息(Normalized Mutual Information, NMI)
→ 衡量聚类结果与真实标签的一致性
📌 实际中常用轮廓系数 + 业务解释结合评估
🎯 七、如何选择聚类算法?
| 场景 | 推荐算法 | 理由 |
|---|---|---|
| 数据量大,需快速聚类 | K-Means | 高效,可扩展 |
| 不知道分几类,想探索 | 层次聚类 | 树状图帮助选 K |
| 数据有噪声,簇形状复杂 | DBSCAN | 抗噪,任意形状 |
| 高维稀疏数据(如文本) | K-Means + 降维 | DBSCAN 在高维失效 |
| 需要概率归属(软聚类) | 高斯混合模型 GMM | 每个样本属于各簇的概率 |
📌 K-Means 是默认首选,除非你有特殊需求(如噪声、非凸形状)
🛠️ 八、伪代码示例
▶︎ K-Means
随机初始化 K 个质心 μ[1..K]
repeat:
# 分配:每个样本分配到最近质心
for 每个样本 x_i:
c_i = argmin_k ||x_i - μ_k||^2
# 更新:重新计算每个簇的质心
for 每个簇 k:
μ_k = mean{ x_i | c_i == k }
until 质心变化 < 阈值 或 达到最大迭代
▶︎ DBSCAN(简化)
for 每个未访问点 p:
标记 p 为已访问
N = regionQuery(p, eps) # 找 eps 邻域内点
if len(N) < MinPts:
标记 p 为噪声
else:
创建新簇 C
将 p 加入 C
for 每个点 q in N:
if q 未被访问:
标记 q 为已访问
N_q = regionQuery(q, eps)
if len(N_q) >= MinPts:
N = N ∪ N_q
if q 不属于任何簇:
将 q 加入 C
📌 九、关键注意事项
- 必须做特征缩放(尤其 K-Means、DBSCAN)→ 否则距离被大尺度特征主导
- K-Means 对初始值敏感 → 用
K-Means++初始化(sklearn 默认) - 高维数据聚类困难 → 考虑先用 PCA/t-SNE 降维
- 聚类结果需要业务解释 → 技术指标好 ≠ 业务有用
- DBSCAN 参数难调 → 可用 K-Distance 图辅助选 eps
- 没有“最好”的聚类算法 → 多试几种,结合业务判断
✅ 十、一句话总结
聚类 = “让相似的人坐在一起” —— 无监督、重相似性、需评估、讲业务,是数据探索的利器!