本节摘要:无监督学习方法不需要任何标签,通过学习数据的内在结构识别异常。本节展开两条主线:聚类思路(K-Means 的簇心距离、DBSCAN 的噪声点)与降维思路(PCA 的重构误差),并预告自编码器的重构思想。核心逻辑是两种判据——"离群太远"(距离异常)与"重建不上来"(重构异常)。优点是不需要标签、能发现未知异常;代价是没有"标准答案",参数与结果都需要人工背书。
阅读完本节,你应当能够:
一家污水处理厂的监测系统上线前,项目经理问数据团队:"你们能告诉我接下来一年会出现哪些故障模式吗?" 数据团队沉默了——没人知道。过去没有故障数据,也没有任何标签,只有一屋子"正常运行"的传感器记录。
这时候监督学习直接出局(没有标签),半监督也需要"正常数据"的概念,但最省事的选择其实是无监督:让数据自己说话。 正常工况下,传感器读数会自然地形成几个"习惯聚集区"——比如不同进水负荷下的不同运行模式。任何"游离在习惯聚集区之外"的读数,都是值得怀疑的对象。
无监督的核心逻辑很简单:正常的数据有结构(聚团、低维、可压缩),异常破坏这种结构。 围绕这句话,衍生出两种判据:
无监督的好处是"不需要标签、能发现从没见过的异常"——这对"不知道未来会发生什么故障"的场景是刚需。代价同样明确:没有标准答案,模型自己说谁异常就是谁异常,业务必须人工复核,否则检测结果没法被采信。
K-Means 把数据聚成 K 簇,每个点属于最近的簇中心。两个异常判据:
K 值怎么选? 肘部法则(看 SSE 随 K 的拐点)、轮廓系数、或领域知识。K 选错了,异常判据会整体失真——K 太小,正常点被强行塞进大簇,离群距离普遍变大;K 太大,异常点也会有自己的"小簇",被当成正常。
from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler import numpy as np # X 为特征矩阵 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) kmeans = KMeans(n_clusters=3, random_state=42, n_init='auto') kmeans.fit(X_scaled) # 计算每个点到所属簇中心的距离 distances = [np.linalg.norm(X_scaled[i] - kmeans.cluster_centers_[kmeans.labels_[i]]) for i in range(len(X_scaled))] # 把距离大于 95 分位数的点视为异常 threshold = np.percentile(distances, 95) anomalies = np.where(np.array(distances) > threshold)[0] print("Anomalies:", anomalies)
注意两点:特征必须标准化(K-Means 对尺度敏感);"95 分位"这个阈值是人工背书的——这就是无监督的日常:算法给候选,人来定标尺。
PCA 找到方差最大的几个主成分,把数据投影到低维空间再还原。如果低维空间留得住正常数据的结构,那么正常点的"重建误差"很小;异常点破坏了可压缩性,重建误差大。
from sklearn.decomposition import PCA import numpy as np pca = PCA(n_components=2) pca.fit(X_scaled) X_pca = pca.transform(X_scaled) # 重建并计算重构误差 X_reconstructed = pca.inverse_transform(X_pca) recon_error = np.mean(np.square(X_scaled - X_reconstructed), axis=1) threshold = np.percentile(recon_error, 95) anomalies = np.where(recon_error > threshold)[0]
PCA 的异常检测本质是"降维维数"的选择问题:保留的维数太少,正常点也重建不好,误报高;维数太多,异常也能被重建,漏报高。实践上通常保留能解释 85%–95% 方差的维数。PCA 的重构思想是自编码器的线性祖先——第 6 章的自编码器就是把"重构"这个思想用神经网络非线性化。
DBSCAN(第 4.4 节已详述)从密度出发:核心点连成簇,噪声点即异常。它和 K-Means 的差别在于不需要预设簇数量、能发现任意形状的簇,更适合"正常形状不规整"的数据。缺点是对 eps/minPts 敏感。
严格来说,"只用正常数据训练"的半监督(One-Class SVM、Isolation Forest)和无监督(K-Means、PCA)在工程里经常被混用,但有一个清晰的区分标准:半监督假定"训练数据里只有正常",无监督允许"训练数据里混着异常"。 这个区分影响深远:
现实里训练集通常不干净,所以无监督的鲁棒性往往被低估。
| 方法 | 异常判据 | 关键参数 | 优点 | 缺点 |
|---|---|---|---|---|
| K-Means | 簇心距离/极小簇 | K | 简单快、好解释 | 需要定 K、形状受限 |
| DBSCAN | 噪声点 | eps、minPts | 任意形状、无 K | 参数敏感、密度差异难调 |
| PCA | 重构误差 | 降维维数 | 线性快、可解释 | 只能捕捉线性结构 |
| 自编码器 | 重构误差 | 网络结构 | 非线性、强 | 数据要求高(第6章详述) |
无监督没有标准答案,但它有个非常实用的工作流:算法给出连续评分(距离、重构误差),业务/专家定阈值(多少分算异常)。 这条"机器出分、人定界"的流水线,既发挥了无监督"发现未知异常"的长处,又用人工背书补上了"没人告诉它对错"的短板。这也是第 7 章评估体系的自然衔接点。
无监督最值钱的能力是发现从没见过的异常。监督模型只会报警"训练集里的异常类型",无监督模型会报警"任何不在正常结构里的东西"。对一个业务在快速变化、故障模式未知的系统,无监督是唯一能"盲扫"的选择。
⚠️ 常见坑:把无监督结果直接上线,不做人工复核。 无监督的"异常"里混着三类东西:真异常、正常波动的新常态(比如业务涨了,流量形态变了)、数据质量问题。没有复核就自动报警,系统会被"新常态"刷爆。
💡 关键直觉:无监督检测的每一步都是"结构假设"。 K-Means 假设正常是"球状簇",PCA 假设正常是"线性低维",DBSCAN 假设正常是"密度相连"。选无监督方法,本质是选一个你信得过的"正常结构假设"。 结构假设对不对,直接决定检测效果。
探索期盲扫:新业务上线,不知道会出什么问题 → 无监督全量扫描,人工看候选。数据质量监控:传感器数据异常往往就是"数据质量"问题本身,无监督兜底。滚动监控基线:当业务快速变化、历史标签全部过期时,无监督"只认当前结构"的特性反而保值。
把几种无监督方法放到不同数据形态里看,选型思路会清晰很多:
选型的本质是选"结构假设":你信哪种"正常结构"(球状、任意形状、低维平面、非线性流形),就选对应的方法。结构假设和数据真实形态越匹配,检测越准。
无监督没有标签,怎么评估"检得好不好"?四个实用手段:
这四招组合起来,能在没有标签的情况下给无监督"相对可信"的评估——比"完全没有评估、系统裸奔"强得多,也是第 7 章评估思想的延伸。
看正常数据的形状:大致是球状团 → K-Means;形状不规整(环形、月牙、S 形)→ DBSCAN。先画个二维分布图看一眼,比纠结算法参数有用得多。
当正常结构是非线性的时候。PCA 只能捕捉线性低维结构,正常数据躺在一个弯曲的"流形"上时,PCA 重建误差普遍偏大,分不清异常。数据量大、结构非线性 → 用自编码器(第 6.3 节)。
"新常态"(业务涨了、流量形态变了)会让大量正常点变成"离群"。区分信号:新常态通常成簇出现且持续——单个离群点是异常,成片成团出现的"离群点"更可能是新常态。观察报警在时间和空间上是否聚集,是初步判别的快捷方式。
要,而且比监督更需要。无监督的"结构"全靠特征定义——喂什么特征,它就按什么特征找结构。特征没做对(比如没去趋势),无监督会把"正常的趋势段"当成离群。第 2.4 节的特征工程,对无监督同样是上限所在。
下一节进入异常检测最"对症下药"的范式——半监督:只用正常数据训练。One-Class SVM 画边界、Isolation Forest 量孤立难度,两条思路直击"异常样本稀缺"的命门。