无监督学习:聚类、降维与异常检测
核心:没有标签时,从数据本身找结构。
无监督学习在工业界的真实用途比教科书说的更明确:分群、压缩、找异常、找相似。
四类任务与用途
| 任务 | 干什么 | 工业用途 |
|---|---|---|
| 聚类 | 把相似的样本分到一组 | 用户分群、商品分组、标签体系冷启动 |
| 降维 | 用更少的维度表示数据 | 可视化、去噪、加速、embedding 压缩 |
| 异常检测 | 找出「不像其他样本」的点 | 欺诈、设备故障、质量检测 |
| 密度估计/生成 | 学数据分布 | 采样、数据增强 |
一、K-Means:最常用的聚类
思想:找 K 个中心点,让每个样本到最近中心的距离平方和最小。
python
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
X_scaled = StandardScaler().fit_transform(X) # 聚类前必须标准化!
km = KMeans(n_clusters=5, n_init=10, random_state=42)
labels = km.fit_predict(X_scaled)
print("每个簇的样本数:", np.bincount(labels))
print("簇中心:\n", km.cluster_centers_)
print("惯性 (inertia):", km.inertia_) # 越小越紧K 怎么选
| 方法 | 做法 | 判读 |
|---|---|---|
| 肘部法 | 画 K vs inertia | 找拐点 |
| 轮廓系数 | silhouette_score | 越接近 1 越好,通常 0.2+ 可接受 |
| 业务约束 | 团队能维护几个分群 | 往往最实际(如运营只能管 5 类) |
python
from sklearn.metrics import silhouette_score
for k in range(2, 11):
km = KMeans(n_clusters=k, n_init=10, random_state=42).fit(X_scaled)
print(k, round(silhouette_score(X_scaled, km.labels_), 3))K-Means 的四个前提(不满足就别用)
| 前提 | 不满足时 |
|---|---|
| 簇是球形、大小相近 | 长条形/环形分布 → 用 DBSCAN |
| 需要预先给 K | 不知道几类 → 用层次聚类 / HDBSCAN |
| 对尺度敏感 | 必须标准化 |
| 对异常值敏感 | 先剔除或用 K-Medoids |
二、层次聚类与 DBSCAN
python
# 层次聚类:给出树状图,能看「层级结构」
from scipy.cluster.hierarchy import linkage, dendrogram
Z = linkage(X_scaled, method="ward")
dendrogram(Z, truncate_mode="lastp", p=20)
# DBSCAN:不需要 K,能找出任意形状,并标记噪声
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=0.5, min_samples=5).fit(X_scaled)
print("簇标签:", set(db.labels_)) # -1 表示噪声点| 算法 | 需要 K | 形状 | 异常点 | 大数据 |
|---|---|---|---|---|
| K-Means | 是 | 球形 | 敏感 | 快 |
| 层次聚类 | 否 | 任意 | 敏感 | 慢(O(n²)) |
| DBSCAN | 否(用 eps) | 任意 | 能识别 | 中 |
三、PCA:降维与可视化
python
from sklearn.decomposition import PCA
pca = PCA(n_components=0.95) # 保留 95% 方差,自动定维数
X_pca = pca.fit_transform(X_scaled)
print("保留维度:", X_pca.shape[1])
print("各主成分解释方差比:", pca.explained_variance_ratio_[:10].round(3))
# 二维可视化
pca2 = PCA(n_components=2)
vis = pca2.fit_transform(X_scaled)
plt.scatter(vis[:, 0], vis[:, 1], c=labels, s=8, cmap="tab10", alpha=0.7)用途排序:可视化(最常用)> 去噪 > 加速下游模型 > 特征压缩。
PCA 的两个误解
- PCA 不是特征选择:它是把原特征线性组合成新特征,可解释性会丢
- PCA 前必须标准化,否则量纲大的列会独占主成分
相关方法怎么选
| 方法 | 特点 | 场景 |
|---|---|---|
| PCA | 线性、快 | 通用降维/可视化 |
| t-SNE | 非线性,保局部结构 | 只用于可视化,不能当特征 |
| UMAP | 非线性,比 t-SNE 快且保全局 | 可视化 + 可做特征 |
| 自编码器 | 神经网络版降维 | 图像/文本 |
四、异常检测:三种主流做法
| 方法 | 原理 | 适用 |
|---|---|---|
| 统计法 | 3σ / IQR / z-score | 单变量、分布已知 |
| 孤立森林 | 异常点更容易被随机切分孤立 | 高维表格、样本多 |
| LOF | 局部密度明显低于邻居 | 密度不均的数据 |
| 自编码器 | 重建误差大即为异常 | 图像、序列 |
python
from sklearn.ensemble import IsolationForest
iso = IsolationForest(contamination=0.01, random_state=42, n_jobs=-1)
flags = iso.fit_predict(X_scaled) # -1 = 异常
print("异常点数量:", (flags == -1).sum())
# 用分数排序取 Top-N 更可控
score = -iso.score_samples(X_scaled)
top_idx = np.argsort(score)[-20:] # 最异常的 20 个工程建议:异常检测几乎总是「用分数排序 + 人工复核 Top-N」,而不是自动判定。contamination 猜错会毁掉召回。
五、embedding 聚类(现代最实用的一种)
文本/图像的 embedding + 聚类,是构建标签体系最快的办法。
python
# 假设 embeddings: (n_samples, 768)
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
normed = embeddings / np.linalg.norm(embeddings, axis=1, keepdims=True) # 归一化
km = KMeans(n_clusters=8, n_init=10, random_state=42).fit(normed)
# 看每个簇的代表样本 —— 这一步才是关键
for c in range(8):
idx = np.where(km.labels_ == c)[0][:5]
print(f"\n簇 {c}({len(idx)} 条示例):")
for i in idx:
print(" ", texts[i][:60])人工检查簇内容是必须的:聚类算法只保证「相似」,不保证「有意义」。
六、评估无监督模型(难点)
没有标签就没有标准答案。可用的间接方法:
| 方法 | 说明 |
|---|---|
| 内部指标 | 轮廓系数、Calinski-Harabasz(只看几何紧密度) |
| 稳定性 | 换随机种子/重采样,簇结构是否稳定 |
| 下游收益 | 分群后做营销,转化率提升多少(唯一真正标准) |
| 人工可解释 | 簇内样本是否说得通 |
判断标准
无监督模型的验收标准永远在业务侧,不在算法侧。 「轮廓系数 0.6」不算成果,「分群后 A 组转化率是 B 组的 2.3 倍」才算。
通过标准
下一步
L2 完成。进入 L3 深度学习。