Course 3:无监督学习
课程简介
K-Means 聚类、DBSCAN、异常检测。
一、无监督学习概述
1.1 什么是无监督学习
无监督学习处理的是没有标签的数据。模型需要自己发现数据中的结构、模式和关系。
主要任务:
- 聚类:将相似样本分组
- 降维:将数据映射到低维空间
- 密度估计:估计数据的概率分布
- 异常检测:识别与大多数样本不同的异常点
1.2 为什么需要无监督学习
- 标注成本高:现实中大量数据没有标签,人工标注费时费力
- 发现隐藏模式:数据中可能存在我们不知道的结构
- 数据预处理:聚类和降维常常是监督学习的预处理步骤
二、K-Means 聚类
2.1 算法步骤
K-Means 是最经典的聚类算法。它的目标是将样本划分为 K 个簇,使得簇内样本相似度最大、簇间样本相似度最小。
算法流程:
- 随机初始化 K 个聚类中心 μ₁, μ₂, ..., μ_K
- 重复以下步骤直到收敛:
a. 分配步骤:计算每个样本到各聚类中心的距离,将其分配到最近的簇
b. 更新步骤:重新计算每个簇的中心(簇内样本均值)
分配步骤的数学表述:
$$c^{(i)} = \arg\min_k |x^{(i)} - \mu_k|^2$$
更新步骤的数学表述:
$$\mu_k = \frac{1}{m_k} \sum_{i: c^{(i)}=k} x^{(i)}$$
2.2 失真函数
K-Means 优化的是以下失真函数:
$$J(c, \mu) = \sum_{i=1}^{m} |x^{(i)} - \mu_{c^{(i)}}|^2$$
它衡量所有样本到其所属簇中心的距离平方和。
2.3 初始化策略
不好的初始化可能导致 K-Means 陷入局部最优。常用策略:
K-Means++:初始化时选择距离尽可能远的中心点
多次运行:不同的随机初始化运行多次,选择失真最小的结果
def kmeans_plus_plus(X, K):
n_samples = X.shape[0]
centers = [X[np.random.randint(n_samples)]]
for _ in range(1, K):
dists = np.min([np.sum((X - c) ** 2, axis=1) for c in centers], axis=0)
probs = dists / np.sum(dists)
new_center = X[np.random.choice(n_samples, p=probs)]
centers.append(new_center)
return np.array(centers)
2.4 选择 K 值
肘部法则:绘制 K 与失真函数的关系曲线,选择曲线"肘部"位置的 K 值。
轮廓系数:衡量簇内紧密度和簇间分离度的综合指标。取值范围 [-1, 1],越大越好。
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=5, init='k-means++', n_init=10, random_state=42)
kmeans.fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
三、DBSCAN
3.1 基于密度的聚类
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)基于密度的聚类方法,不需要预先指定簇的数量,可以识别任意形状的簇和噪声点。
3.2 核心概念
- 核心点:在半径 ε 内至少有 min_samples 个点
- 边界点:在核心点的 ε 邻域内,但自身不是核心点
- 噪声点:既不是核心点也不是边界点
3.3 算法流程
- 对每个点,计算其 ε 邻域内的点数
- 标记核心点(邻域点数 ≥ min_samples)
- 连接核心点:如果两个核心点在彼此的 ε 邻域内,属于同一簇
- 分配边界点:边界点分配到其邻域内核心点所属的簇
- 剩余点为噪声
3.4 DBSCAN vs K-Means
| 特性 | K-Means | DBSCAN |
|---|---|---|
| 簇形状 | 凸形(球形) | 任意形状 |
| 预设 K | 需要 | 不需要 |
| 噪声处理 | 所有点都被分配 | 可以标记噪声 |
| 密度变化 | 难以处理 | 需要调 ε 和 min_samples |
| 计算复杂度 | O(n) | O(n²) |
四、异常检测
4.1 密度估计方法
假设正常数据服从某个分布(如高斯分布),概率密度很低的样本视为异常。
$$\mu_j = \frac{1}{m} \sum_{i=1}^{m} x_j^{(i)}$$
$$\sigma_j^2 = \frac{1}{m} \sum_{i=1}^{m} (x_j^{(i)} - \mu_j)^2$$
假设特征独立,样本的联合概率为:
$$p(x) = \prod_{j=1}^{n} \frac{1}{\sqrt{2\pi \sigma_j^2}} \exp\left(-\frac{(x_j - \mu_j)^2}{2\sigma_j^2}\right)$$
如果 p(x) < ε,判定为异常。
4.2 异常检测 vs 监督分类
异常检测适合的情况:
- 异常样本极少(1-20%)
- 异常类型多样且不可预测
- 未来可能出现新的异常类型
from sklearn.ensemble import IsolationForest
model = IsolationForest(contamination=0.1, random_state=42)
# -1 表示异常,1 表示正常
anomaly_labels = model.fit_predict(X)
延伸阅读
- 📺 B 站播放列表:Machine Learning Specialization (2022) — 新版机器学习
- 📚 更多学习资源,请访问 deeplearning.ai 官网