4. 距离度量:欧氏距离、曼哈顿距离与基于距离的异常检测
聊到异常检测,距离度量是个绕不开的话题。说白了,异常就是“离群”,那怎么判断一个点是不是离群?核心就是看它跟“正常群体”有多远。距离越远,越可能是异常。
我个人习惯把距离度量比作“尺子”。不同场景下,你得用不同的尺子。用错了,结果可能差之千里。今天咱们就聊聊最常用的两把尺子——欧氏距离和曼哈顿距离,以及它们怎么用在异常检测里。
4.1 欧氏距离:最直观的“直线距离”
欧氏距离,大家中学就学过。就是两点之间的直线距离。公式很简单:
d(x, y) = sqrt( (x1 - y1)² + (x2 - y2)² + ... + (xn - yn)² )
嗯,这里要注意:欧氏距离对每个维度的差异是“平方求和”的。这意味着,如果某个维度上数值差异很大,它会主导整个距离的计算结果。
适用场景:
- 数据各维度量纲一致(比如都是厘米、都是千克)
- 各维度重要性相当,没有明显的主次之分
- 数据分布比较“圆润”,没有极端的长条形状
我在项目中遇到过一个问题:用欧氏距离做信用卡交易异常检测,结果发现很多正常的大额交易被误判为异常。为什么?因为交易金额这个维度的数值范围(几百到几万)远大于交易时间、商户类型等维度(0-1或0-23)。欧氏距离被金额维度“绑架”了。
避坑指南:我曾经因为没做标准化直接上欧氏距离,导致模型效果惨不忍睹。后来养成了习惯——用欧氏距离前,一定先做Z-score标准化或Min-Max缩放。让所有维度在同一个量级上说话。
4.2 曼哈顿距离:城市街区的“折线距离”
曼哈顿距离,也叫L1距离。想象你在曼哈顿街区走路,不能穿楼而过,只能沿着街道走直角。公式是:
d(x, y) = |x1 - y1| + |x2 - y2| + ... + |xn - yn|
你想想看,它跟欧氏距离最大的区别是什么?曼哈顿距离用的是绝对值,不是平方。这意味着它对异常值不那么敏感。一个维度上的大偏差,不会被平方放大。
| 特性 | 欧氏距离 | 曼哈顿距离 |
|---|---|---|
| 对异常值敏感度 | 高(平方放大) | 低(绝对值) |
| 计算复杂度 | 较高(开方) | 较低 |
| 高维数据表现 | 易受“维度灾难”影响 | 相对稳定 |
| 几何解释 | 直线距离 | 网格路径 |
我的经验:在风控场景中,如果特征维度很高(比如50维以上),我建议优先试试曼哈顿距离。欧氏距离在高维空间里,所有点之间的距离会趋向于相等,区分度下降。这就是所谓的“维度灾难”。曼哈顿距离能稍微缓解这个问题。
4.3 基于距离的异常检测:KNN距离法
有了距离度量,怎么做异常检测?最经典的方法就是KNN距离法。思路很简单:
- 对每个样本,计算它到最近K个邻居的平均距离
- 这个平均距离越大,说明它越“孤立”,越可能是异常
我建议把K值设成总样本数的1%-5%。太小了容易受局部噪声影响,太大了又会把局部稀疏区域的正常点误判为异常。
# 伪代码示例
def knn_anomaly_score(data, k=5):
scores = []
for i in range(len(data)):
# 计算点i到所有其他点的距离
distances = [euclidean(data[i], data[j]) for j in range(len(data)) if j != i]
# 取最小的k个距离,求平均
k_nearest = sorted(distances)[:k]
score = sum(k_nearest) / k
scores.append(score)
return scores
# 分数越高的点,越可能是异常
关键参数:
- K值:控制局部性。K越小,越关注局部异常;K越大,越关注全局异常
- 距离度量:欧氏距离适合各向同性的数据,曼哈顿距离适合高维或稀疏数据
- 阈值:通常取分数分布的前5%或1%作为异常点
我记得有一次做电商的刷单检测,用了KNN距离法。正常用户的购买行为在特征空间里聚成一团,刷单机器人则散落在边缘。KNN距离法很轻松就把它们揪出来了。但有个坑——如果刷单机器人模仿正常用户的行为模式,距离法就失效了。这时候得结合其他方法。
4.4 实战中的选择策略
说了这么多,到底什么时候用欧氏距离,什么时候用曼哈顿距离?我总结了一个简单的决策树:
- 数据量纲统一,分布较“圆” → 欧氏距离
- 维度高(>20),数据稀疏 → 曼哈顿距离
- 特征中有明显的噪声或离群点 → 曼哈顿距离(鲁棒性更好)
- 需要解释性,想知道每个维度的贡献 → 曼哈顿距离(每个维度的差异直接相加,可解释性强)
注意:我曾经在一个项目中,直接用欧氏距离做KNN异常检测,结果发现所有异常点都是因为某个特征值特别大。后来换成曼哈顿距离,并做了特征标准化,效果才正常。所以,别偷懒,先做数据探索,再选距离度量。
最后说一句:距离度量只是工具,真正重要的是理解你的数据长什么样。数据分布、量纲、噪声水平,这些决定了该用哪把尺子。做异常检测这么多年,我最大的体会就是——没有最好的距离,只有最合适的距离。