跳到主要内容 Python 聚类实战:OPTICS 算法原理与可视化全流程 | 极客日志
Python AI 算法
Python 聚类实战:OPTICS 算法原理与可视化全流程 介绍 OPTICS 聚类算法的 Python 实现流程。通过生成环形与球形混合数据模拟非线性分布场景,演示了核心概念如可达距离与核心距离的计算。文章包含环境配置、数据生成、模型训练、可达距离曲线分析及聚类结果可视化。对比了 OPTICS 与 K-Means、DBSCAN 的效果差异,并提供了参数调优指南及常见问题解决方案,适用于用户行为分析、异常检测等复杂密度结构场景。
利刃 发布于 2026/3/24 更新于 2026/4/17 14K 浏览一、引言:聚类算法中的'密度层次专家'
在无监督学习领域,聚类算法是挖掘数据内在结构的核心工具。传统聚类方法中,K-Means 依赖'球形簇'假设、DBSCAN 对参数敏感,而 OPTICS(Ordering Points To Identify the Clustering Structure,基于密度的层次聚类算法)凭借'任意形状簇识别''密度分布可视化'的特性,成为非线性数据聚类的优选方案。
本文以环形与球形混合数据为实验对象,从环境配置、数据生成、算法实现、结果解析、问题解决五个维度,完整复现 OPTICS 算法的实战流程。
二、环境准备与依赖库安装
2.1 核心库说明
numpy:数据处理;
matplotlib:可视化;
sklearn:数据生成、OPTICS 算法实现。
!pip install numpy matplotlib scikit-learn
2.2 库导入与中文配置 导入库并解决 Matplotlib 中文显示问题(避免后续可视化出现乱码):
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles, make_blobs
from sklearn.cluster import OPTICS
plt.rcParams["font.sans-serif" ] = ["SimHei" ]
plt.rcParams["axes.unicode_minus" ] = False
三、实验数据生成:模拟非线性分布场景 为体现 OPTICS 处理'非球形簇'的优势,我们生成'环形 + 球形混合数据'(模拟真实场景中不规则分布的数据集)。
3.1 数据生成代码
X1, _ = make_circles(
n_samples=1000 ,
factor=0.2 ,
noise=0.05 ,
random_state=5
)
X2, _ = make_blobs(
n_samples=200 ,
n_features=2 ,
centers=[[1 , 2 ]],
cluster_std=[0.1 ],
random_state=5
)
X3, _ = make_blobs(
n_samples=300 ,
n_features=2 ,
centers=[[-0.5 , -1.2 ]],
cluster_std=[0.1 ],
random_state=5
)
X = np.concatenate((X1, X2, X3))
plt.figure(figsize=(8 , 6 ))
plt.scatter(X[:, 0 ], X[:, 1 ], marker="*" , c="gray" )
plt.title("原始数据分布:环形 + 球形混合结构" )
plt.xlabel("特征 1" )
plt.ylabel("特征 2" )
plt.show()
图中可以看到:数据包含内外双层环形结构和两个独立球形簇,传统 K-Means 无法区分环形结构(会将内外环划分为同一簇),而 OPTICS 可通过密度差异识别这种不规则结构。
四、OPTICS 算法核心原理与实现
4.1 OPTICS 核心概念 OPTICS 的核心是'可达距离'与'核心距离':
核心距离 :某样本成为'核心点'所需的最小邻域半径(由 min_samples 决定);
可达距离 :样本 A 到样本 B 的距离,若 B 是核心点,则可达距离为 B 的核心距离与 A-B 实际距离的较大值。
通过对样本按'可达距离'排序,OPTICS 可生成可达距离曲线,曲线的'陡峭段'对应簇的边界,'平缓段'对应簇的核心区域。
4.2 OPTICS 模型训练代码
model = OPTICS(
min_samples=15 ,
xi=0.05 ,
min_cluster_size=0.05 ,
cluster_method="xi"
)
model.fit(X)
4.3 可达距离曲线可视化 可达距离曲线是 OPTICS 的核心输出,代码如下:
ordering = model.ordering_
reachability = model.reachability_[ordering]
plt.figure(figsize=(10 , 4 ))
plt.plot(reachability, marker="." , linestyle="none" , color="#1f77b4" )
plt.xlabel("样本排序(密度从高到低)" )
plt.ylabel("可达距离" )
plt.title("OPTICS 可达距离曲线" )
plt.grid(alpha=0.3 )
plt.show()
曲线中平缓的区域对应'高密度簇的核心'(如环形结构的主体);
曲线中骤升的点对应'簇的边界'(如球形簇与环形簇的分隔处);
图中右侧的高值点对应独立的球形簇(密度较低,可达距离大)。
4.4 聚类结果可视化 通过 model.labels_ 可获取簇标签(-1 代表噪声点),代码如下:
labels = model.labels_[ordering]
plt.figure(figsize=(8 , 6 ))
plt.scatter(X[:, 0 ], X[:, 1 ], c=labels, cmap="tab10" , s=50 , alpha=0.8 )
plt.title("OPTICS 聚类结果:环形 + 球形簇区分" )
plt.xlabel("特征 1" )
plt.ylabel("特征 2" )
plt.colorbar(label="簇标签" )
plt.show()
OPTICS 成功区分了内外环形簇(不同颜色的环形结构);
两个独立的球形簇(X2、X3)被划分为单独的簇;
仅少量噪声点被标记为 -1(图中未明显显示,因本次数据噪声较少)。
五、参数调优:优化 OPTICS 聚类效果 OPTICS 的聚类结果对参数敏感,我们通过调整 min_samples(核心点的最小邻域样本数),对比聚类效果的变化。
5.1 调优后模型训练代码
model_tuned = OPTICS(
min_samples=10 ,
xi=0.05 ,
min_cluster_size=0.05 ,
cluster_method="xi"
)
model_tuned.fit(X)
labels_tuned = model_tuned.labels_
5.2 调优后聚类结果
plt.figure(figsize=(8 , 6 ))
plt.scatter(X[:, 0 ], X[:, 1 ], c=labels_tuned, cmap="tab10" , s=50 , alpha=0.8 )
plt.title("OPTICS 调优后结果(min_samples=10)" )
plt.xlabel("特征 1" )
plt.ylabel("特征 2" )
plt.colorbar(label="簇标签" )
plt.show()
当 min_samples 从 15 减小到 10 后,环形簇的划分更精细(区分了内环的子结构);
球形簇的边界更清晰,簇内样本的同质性更高。
5.3 OPTICS 参数选择指南
min_samples :建议设置为 2*特征数(如 2 维数据设为 4~10),值越大,簇划分越'粗糙';
xi :一般取 0.01~0.1,值越小,簇划分越精细;
min_cluster_size :根据业务需求设置(如过滤占比 < 5% 的小簇)。
六、实战问题解决:Jupyter 可视化报错处理 在实验过程中,可能会遇到'HTML 可视化无法渲染'的提示,这是因为 sklearn 的 OPTICS 默认输出 HTML 格式的聚类树。
6.1 解决方法 在初始化模型时,添加 cluster_method="xi" 参数,指定用'xi 方法'划分簇,而非输出 HTML 树:
model = OPTICS(
min_samples=15 ,
xi=0.05 ,
min_cluster_size=0.05 ,
cluster_method="xi"
)
七、OPTICS 与其他聚类算法的对比实验 为了更直观地体现 OPTICS 的优势,我们将其与 K-Means、DBSCAN 在同一数据上的效果做对比:
7.1 对比实验代码 from sklearn.cluster import KMeans, DBSCAN
kmeans = KMeans(n_clusters=4 , random_state=5 )
kmeans_labels = kmeans.fit_predict(X)
dbscan = DBSCAN(eps=0.2 , min_samples=5 )
dbscan_labels = dbscan.fit_predict(X)
fig, axes = plt.subplots(1 , 3 , figsize=(18 , 5 ))
axes[0 ].scatter(X[:, 0 ], X[:, 1 ], c=kmeans_labels, cmap="tab10" )
axes[0 ].set_title("K-Means 聚类结果" )
axes[1 ].scatter(X[:, 0 ], X[:, 1 ], c=dbscan_labels, cmap="tab10" )
axes[1 ].set_title("DBSCAN 聚类结果" )
axes[2 ].scatter(X[:, 0 ], X[:, 1 ], c=labels, cmap="tab10" )
axes[2 ].set_title("OPTICS 聚类结果" )
plt.tight_layout()
plt.show()
7.2 对比结论 算法 优势 劣势 本次数据效果 OPTICS 识别任意形状簇、展示密度分布 参数较多、训练时间较长 优秀(区分环形) K-Means 速度快、实现简单 仅支持球形簇、依赖 K 值 差(无法区分环形) DBSCAN 抗噪声、无需指定簇数 对 eps 和 min_samples 敏感 较好(需精细调参)
八、总结与应用场景
8.1 实验总结
生成'环形 + 球形'混合数据,模拟非线性分布场景;
训练 OPTICS 模型,解析可达距离曲线的密度意义;
调优参数,优化簇的划分效果;
解决 Jupyter 中可视化报错的问题。
8.2 OPTICS 应用场景 OPTICS 适用于非线性分布、需探索密度结构的业务场景:
用户行为聚类 :区分'高频低消''低频高消'等不规则用户群体;
异常检测 :可达距离极高的样本可判定为异常点;
图像分割 :识别不规则形状的目标区域;
生物信息学 :聚类基因表达数据中的复杂结构。
九、完整代码附录
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles, make_blobs
from sklearn.cluster import OPTICS
plt.rcParams["font.sans-serif" ] = ["SimHei" ]
plt.rcParams["axes.unicode_minus" ] = False
X1, _ = make_circles(n_samples=1000 , factor=0.2 , noise=0.05 , random_state=5 )
X2, _ = make_blobs(n_samples=200 , n_features=2 , centers=[[1 ,2 ]], cluster_std=[0.1 ], random_state=5 )
X3, _ = make_blobs(n_samples=300 , n_features=2 , centers=[[-0.5 ,-1.2 ]], cluster_std=[0.1 ], random_state=5 )
X = np.concatenate((X1, X2, X3))
plt.figure(figsize=(8 ,6 ))
plt.scatter(X[:,0 ], X[:,1 ], marker="*" , c="gray" )
plt.title("原始数据分布:环形 + 球形混合结构" )
plt.xlabel("特征 1" )
plt.ylabel("特征 2" )
plt.show()
model = OPTICS(min_samples=15 , xi=0.05 , min_cluster_size=0.05 , cluster_method="xi" )
model.fit(X)
ordering = model.ordering_
reachability = model.reachability_[ordering]
plt.figure(figsize=(10 ,4 ))
plt.plot(reachability, marker="." , linestyle="none" , color="#1f77b4" )
plt.xlabel("样本排序(密度从高到低)" )
plt.ylabel("可达距离" )
plt.title("OPTICS 可达距离曲线" )
plt.grid(alpha=0.3 )
plt.show()
labels = model.labels_[ordering]
plt.figure(figsize=(8 ,6 ))
plt.scatter(X[:,0 ], X[:,1 ], c=labels, cmap="tab10" , s=50 , alpha=0.8 )
plt.title("OPTICS 聚类结果:环形 + 球形簇区分" )
plt.xlabel("特征 1" )
plt.ylabel("特征 2" )
plt.colorbar(label="簇标签" )
plt.show()
model_tuned = OPTICS(min_samples=10 , xi=0.05 , min_cluster_size=0.05 , cluster_method="xi" )
model_tuned.fit(X)
labels_tuned = model_tuned.labels_
plt.figure(figsize=(8 ,6 ))
plt.scatter(X[:,0 ], X[:,1 ], c=labels_tuned, cmap="tab10" , s=50 , alpha=0.8 )
plt.title("OPTICS 调优后结果(min_samples=10)" )
plt.xlabel("特征 1" )
plt.ylabel("特征 2" )
plt.colorbar(label="簇标签" )
plt.show()
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online