当面对一堆杂乱无章的数据点时,我们的大脑会本能地寻找其中的规律和分组。这种寻找自然分组的本能,正是聚类算法的核心思想。在众多聚类方法中,基于密度的OPTICS算法提供了一种独特的视角——它不直接给出聚类结果,而是生成一张反映数据"地形起伏"的可达距离图,让我们像地理学家解读等高线图一样,直观地理解数据的聚类结构。
传统聚类算法如K-means需要预先指定簇的数量,而DBSCAN虽然能自动发现簇,但对参数eps(邻域半径)非常敏感。OPTICS的巧妙之处在于:
提示:可达距离图中的"波谷"对应数据密集区域,"波峰"则表示稀疏过渡带
这两个概念是理解OPTICS的关键:
| 概念 | 数学定义 | 直观解释 |
|---|---|---|
| 核心距离 | 使样本成为核心对象的最小邻域半径 | 反映该点所在区域的局部密度 |
| 可达距离 | max(核心距离,两点间欧氏距离) | 从某点到达另一点需要跨越的"地形高度" |
python复制# 计算核心距离的伪代码
def core_distance(point, neighbors, min_samples):
sorted_distances = sorted([distance(point, neighbor) for neighbor in neighbors])
return sorted_distances[min_samples - 1]
OPTICS的工作过程可以类比登山探险:
这个过程产生的输出序列,就是绘制可达距离图的基础。
我们使用一个二维数据集演示完整流程:
python复制import numpy as np
from sklearn.cluster import OPTICS
import matplotlib.pyplot as plt
# 示例数据:两个明显分离的簇
X = np.array([
[1, 2], [2, 2], [2, 3], [8, 7],
[8, 8], [7, 8], [20, 20], [21, 20]
])
# 调用OPTICS算法
clustering = OPTICS(min_samples=2, max_eps=np.inf).fit(X)
生成的可达距离图是理解数据结构的钥匙:
python复制# 绘制可达距离图
plt.figure(figsize=(10, 4))
plt.plot(range(1, len(X)+1), clustering.reachability_[clustering.ordering_])
plt.xlabel('Sample Index (Ordered)')
plt.ylabel('Reachability Distance')
plt.title('Reachability Plot')
plt.grid(True)
# 标记明显的波谷位置
plt.annotate('Cluster 1', xy=(3.5, 0.5), xytext=(2, 3),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.annotate('Cluster 2', xy=(6, 0.5), xytext=(5, 3),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.annotate('Outlier', xy=(7.5, 15), xytext=(6, 12),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
这段代码会生成一张典型的可达距离图,其中:
可达距离图的美妙之处在于,它让我们可以直观地选择DBSCAN的eps参数:
实际操作中,可以这样实现:
python复制from sklearn.cluster import DBSCAN
# 从图形观察确定eps阈值
estimated_eps = 5.0
# 使用DBSCAN验证
db = DBSCAN(eps=estimated_eps, min_samples=2).fit(X)
print("Cluster labels:", db.labels_)
当数据具有嵌套簇或密度变化较大时,可达距离图会呈现更复杂的形态:
虽然OPTICS对参数不敏感,但合理设置仍能提升效果:
| 参数 | 推荐值 | 影响 |
|---|---|---|
| min_samples | 2-5(小数据集) 5-20(大数据集) |
值越大,对噪声越鲁棒 |
| max_eps | 数据直径的1/5到1/2 | 限制算法探索范围 |
| metric | 'euclidean'(默认) 'cosine'(文本数据) |
影响距离计算方式 |
在某电商用户行为分析中,我们使用OPTICS处理用户购买频率和金额的二维数据:
python复制# 实际业务数据示例
user_data = load_real_usage_data()
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(user_data)
# 运行OPTICS
optics_model = OPTICS(min_samples=10, xi=0.05).fit(X_scaled)
# 自动提取聚类(基于ξ方法)
labels = optics_model.labels_[optics_model.ordering_]
unique_labels = set(labels)
通过分析可达距离图,我们发现了4个自然客户群体:
这种可视化分析帮助业务团队快速理解客户结构,无需深入算法细节。