正在加载中...

展开本页目录
算法教程OPTICS-OPTICS

OPTICS-OPTICS

No.129 · 在线教程

OPTICS(Ordering Points To Identify the Clustering Structure)是一种基于密度的聚类方法。它与 DBSCAN 同属于密度聚类路线,但并不直接只输出某一个固定邻域半径下的簇划分,而是先构造样本的有序访问序列、核心距离和可达距…

OPTICS-OPTICS

1. 方法概述

OPTICS(Ordering Points To Identify the Clustering Structure)是一种基于密度的聚类方法。它与 DBSCAN 同属于密度聚类路线,但并不直接只输出某一个固定邻域半径下的簇划分,而是先构造样本的有序访问序列、核心距离和可达距离,再据此提取不同密度层次下的簇结构,因此更适合处理簇密度不一致的数据。

本项目中的 OPTICS-OPTICS 模块并不是手写 OPTICS 搜索过程,而是对 sklearn.cluster.OPTICS 的工程化封装。根据当前代码实现,它具有以下特点:

  1. 支持从任意列中选择 label_col 作为样本名称列;
  2. 支持 noneminmaxzscore 三种预处理方式;
  3. 支持 euclideanmanhattancosine 三种距离度量;
  4. 支持 xidbscan 两种簇提取方式;
  5. 支持把 max_eps=0 解释为无限半径,把 min_cluster_size=0 解释为自动;
  6. 输出样本标签、可达距离表、簇汇总表、指标表以及散点图和 Reachability Plot。

与前面的 K-Means、LLE 等模块一致,本模块并不要求首列必须是样本 ID。程序会先识别可完整转为数值的列,用户再在界面中指定可选的 label_col 与真正参与聚类的特征列。

设共有 \(n\) 个样本、\(p\) 个被选中的特征,记原始特征矩阵为

$$ X=(x_{ij})_{n\times p},\quad i=1,2,\ldots,n,\ j=1,2,\ldots,p \tag{1} $$

2. 数据要求与预处理

2.1 数据约束

根据 upload_widget.pyindicators_widget.pydata_validator.pycore/calculator.py 的实现,模块对输入数据的真实要求如下:

  1. 数据表不能为空;
  2. 数据中至少存在 1 列可完整转换为数值的列;
  3. 被选中的特征列必须存在;
  4. 特征列不能含空值或非数值;
  5. 特征列不能为常数列;
  6. 至少选择 1 个特征列;
  7. min_samples 必须满足 min_samples >= 2
  8. 真正开始拟合时,还要求样本数满足 \(n>\texttt{min\_samples}\)。

若用户没有指定 label_col,程序会自动生成

$$ \text{样本1},\text{样本2},\ldots,\text{样本}n \tag{2} $$

作为结果表中的样本标识。

2.2 Min-Max 归一化

normalize="minmax" 时,代码按列执行

$$ z_{ij}=\frac{x_{ij}-x_j^{\min}}{x_j^{\max}-x_j^{\min}} \tag{3} $$

若某一列满足 \(x_j^{\max}=x_j^{\min}\),程序会把分母替换为 1,以避免除零。

2.3 Z-score 标准化

normalize="zscore" 时,代码执行

$$ z_{ij}=\frac{x_{ij}-\mu_j}{\sigma_j} \tag{4} $$

其中 \(\mu_j\) 为第 \(j\) 列均值,\(\sigma_j\) 为按 ddof=0 计算的总体标准差。若某列 \(\sigma_j=0\),代码同样会把它替换为 1。

normalize="none",则直接令

$$ z_{ij}=x_{ij} \tag{5} $$

记最终进入 OPTICS 模型的特征矩阵为

$$ Z=(z_{ij})_{n\times p} \tag{6} $$

2.4 符号说明

符号 含义
\(n\) 样本数量
\(p\) 特征维数
\(m\) min_samples
\(z_i\) 第 \(i\) 个样本的预处理后特征向量
\(d(\cdot,\cdot)\) 给定距离度量下的样本距离
\(\operatorname{core}(z_i)\) 样本 \(z_i\) 的核心距离
\(\operatorname{reach}(z_i\mid z_j)\) 从 \(z_j\) 到 \(z_i\) 的可达距离
\(y_i\) 第 \(i\) 个样本的簇标签
\(K\) 最终非噪声簇数量

3. 核心数学模型

3.1 核心距离

在给定 min_samples=m 后,OPTICS 会考察样本 \(z_i\) 到其第 \(m\) 个近邻的距离,并将其作为核心距离,可写为

$$ \operatorname{core}(z_i)=d_{(m)}(z_i) \tag{7} $$

其中 \(d_{(m)}(z_i)\) 表示按从小到大排序后的第 \(m\) 个近邻距离。核心距离越小,说明该点附近密度越高。

3.2 可达距离

在从已有种子点 \(z_j\) 向外扩展样本 \(z_i\) 时,可达距离通常表示为

$$ \operatorname{reach}(z_i\mid z_j)=\max\big(\operatorname{core}(z_j),\, d(z_i,z_j)\big) \tag{8} $$

OPTICS 通过不断维护候选点的最小可达距离,得到一个反映密度连通结构的访问顺序。

3.3 排序结果与 Reachability Plot

拟合完成后,模型会输出样本访问顺序

$$ \pi=(\pi_1,\pi_2,\ldots,\pi_n) \tag{9} $$

以及对应顺序下的可达距离序列

$$ r_t=\operatorname{reach}(z_{\pi_t}),\quad t=1,2,\ldots,n \tag{10} $$

当前项目会把这两组结果导出到 Reachability 工作表,并据此生成 reachability_plot.png。在图形上,较低的可达距离谷底通常对应更稳定的高密度簇结构。

3.4 簇提取方式

当前项目支持两种簇提取方式:

  1. cluster_method="xi"
  2. cluster_method="dbscan"

从概念上看,xi 方法根据 Reachability Plot 中相对陡降与陡升来识别簇边界;dbscan 方法则相当于在已经构建好的可达结构上,用给定阈值 eps 再抽取一次类似 DBSCAN 的簇划分。

最终每个样本被赋予标签

$$ y_i\in\{-1,0,1,\ldots,K-1\} \tag{11} $$

其中 \(y_i=-1\) 表示噪声点。

4. 项目中的参数解释与实现口径

4.1 max_eps 的真实含义

界面上把 max_eps 设置为 0 时,代码并不会真的传入 0,而是执行

$$ \texttt{max\_eps}\leftarrow \infty \tag{12} $$

也就是说,0=无限 是当前项目的一个明确实现约定。

4.2 min_cluster_size 的自动逻辑

当界面上 min_cluster_size=0 时,代码会执行

$$ \texttt{min\_cluster\_size}\leftarrow \texttt{None} \tag{13} $$

从而让 sklearn.cluster.OPTICS 按其默认逻辑自动处理最小簇规模。

4.3 eps 的自动逻辑与界面限制

代码中,当

$$ \texttt{eps}\le 0 \tag{14} $$

时,会执行

$$ \texttt{eps}\leftarrow \texttt{None} \tag{15} $$

但需要注意,界面层在 cluster_method="dbscan" 时额外要求 eps>0,因此真正通过图形界面使用 dbscan 提取时,通常不会走到 eps=None 这一分支;它更多体现为底层代码兼容逻辑。

4.4 样本量与 min_samples 的关系

_prepare_data() 中,程序要求

$$ n>\texttt{min\_samples} \tag{16} $$

若样本数小于或等于 min_samples,则直接报错,而不是自动下调参数。

5. 评价指标

5.1 簇数量与噪声点数量

项目会在 Metrics 表中记录:

  1. 样本数
  2. 特征数
  3. 簇数量(不含噪声)
  4. 噪声点数量
  5. 轮廓系数

其中非噪声簇数量可写为

$$ K=\left|\{y_i:\ y_i\neq -1\}\right| \tag{17} $$

噪声点数量为

$$ N_{\text{noise}}=\sum_{i=1}^{n}\mathbf{1}(y_i=-1) \tag{18} $$

5.2 轮廓系数的代码口径

当前代码会先剔除噪声点,只对

$$ \mathcal{I}=\{i:\ y_i\neq -1\} \tag{19} $$

中的样本计算轮廓系数,并且还要求:

  1. 非噪声簇数量大于 1;
  2. 非噪声样本数大于簇数量。

满足条件时,程序调用 silhouette_score(Xn[mask], cluster_labels[mask]) 计算

$$ \mathrm{Silhouette}=\frac{1}{|\mathcal{I}|}\sum_{i\in\mathcal{I}} \frac{b_i-a_i}{\max(a_i,b_i)} \tag{20} $$

若条件不满足,则结果留空字符串,而不是强行输出 0。

5.3 簇汇总表

项目还会构造 ClusterSummary 工作表,对每个簇以及噪声点统计:

  1. 簇ID
  2. 样本数
  3. 平均可达距离
  4. 平均核心距离

对第 \(k\) 个簇,平均可达距离可写为

$$ \bar r_k=\frac{1}{n_k}\sum_{i:y_i=k}\operatorname{reach}(z_i) \tag{21} $$

平均核心距离可写为

$$ \bar c_k=\frac{1}{n_k}\sum_{i:y_i=k}\operatorname{core}(z_i) \tag{22} $$

代码使用 np.nanmean() 计算上述均值,因此会自动忽略不可达或未定义位置上的 NaN

6. 代码实现细节

6.1 使用的是 sklearn.cluster.OPTICS

本项目没有自写优先队列扩展、排序更新或 reachability 维护逻辑,而是直接构造

  1. OPTICS(min_samples=..., max_eps=..., metric=..., cluster_method=..., xi=..., min_cluster_size=..., eps=..., n_jobs=1)

再调用 fit(X) 完成拟合。

6.2 散点图使用的是预处理后的前两维

cluster_scatter.png 绘图时直接使用的是预处理后的 Xn

  1. 若特征数不少于 2,则画 Xn[:,0]Xn[:,1]
  2. 若只有 1 个特征,则画单轴散点图;
  3. 颜色映射直接使用簇标签,包括噪声点 -1

因此,当开启 minmaxzscore 后,图中的横纵坐标实际上对应的是预处理后的尺度,而不是原始业务量纲。

6.3 Reachability 表按排序后顺序导出

结果表中的 Reachability 不是原始样本顺序,而是按 ordering_ 重新排列后的序列,字段为:

  1. 排序
  2. 可达距离
  3. 核心距离
  4. 簇标签

因此该表更适合分析密度结构,不适合直接与原始输入顺序逐行对照。

7. 算法流程

结合当前项目代码,OPTICS-OPTICS 的实际执行流程如下:

  1. 读取 .xlsx.xls.csv 文件,并识别可用数值列。
  2. 在“特征设置”页选择可选的 label_col 与参与聚类的特征列。
  3. 在“算法参数”页设置 min_samplesmax_epsmetriccluster_methodximin_cluster_sizeepsnormalize
  4. 对所选特征执行 noneminmaxzscore 预处理。
  5. 按代码规则把 max_eps<=0 处理为 inf,把 min_cluster_size<=0eps<=0 处理为 None
  6. 调用 sklearn.cluster.OPTICS.fit() 完成排序、核心距离与可达距离计算。
  7. 提取 labels_ordering_reachability_core_distances_
  8. 统计簇汇总表、噪声点数量与轮廓系数。
  9. 生成 cluster_scatter.pngreachability_plot.png
  10. 导出 optics_results.xlsx,并保存在 results/OPTICS-OPTICS分析结果_时间戳/ 目录下。

8. 关键参数说明

8.1 min_samples

表示核心距离与密度可达性判断时使用的最小邻域样本数。该值越大,算法越倾向于识别更稳健、更高密度的簇。

8.2 max_eps

表示搜索邻域的最大半径。当前代码中 0 被解释为无限半径,因此在报告中应写明这一点,而不要误写为“邻域半径为 0”。

8.3 metric

当前支持:

  1. euclidean
  2. manhattan
  3. cosine

不同度量会直接影响近邻结构、可达距离和最终聚类结果。

8.4 cluster_method

当前支持:

  1. xi
  2. dbscan

其中 xi 更强调从 Reachability Plot 中提取层次结构,dbscan 则更接近固定阈值簇抽取。

8.5 xi

仅在 cluster_method="xi" 时有效,用于控制相对陡降/陡升阈值。代码要求 xi>0

8.6 min_cluster_size

仅在 cluster_method="xi" 时有效。界面中设置为 0 时,底层代码会传入 None,表示自动处理。

8.7 eps

仅在 cluster_method="dbscan" 时有效。界面校验要求 eps>0,用于控制 DBSCAN 式簇提取半径。

9. 输出结果与导出说明

9.1 Excel 工作表

根据 _export_excel() 的实现,导出的 optics_results.xlsx 包含:

  1. Parameters
  2. RawData
  3. ProcessedData
  4. Labels
  5. Reachability
  6. ClusterSummary
  7. Metrics
  8. Charts

其中:

  1. ProcessedData 为预处理后的特征矩阵,并在首列保留样本名称;
  2. Labels 为样本标签结果;
  3. Reachability 为按 ordering_ 排序后的可达距离结果;
  4. Charts 记录图表文件路径。

9.2 图表文件

当前代码会在结果目录下的 plots/ 子目录中生成:

  1. cluster_scatter.png
  2. reachability_plot.png

前者用于观察前两维上的聚类分布,后者用于观察密度结构与簇边界。

10. 论文写作建议

10.1 方法描述模板

“本文采用 OPTICS 密度聚类方法对样本进行聚类分析。该方法首先在给定最小样本数条件下计算样本的核心距离和可达距离,并构造反映密度连通关系的排序序列;随后基于 xi 或 DBSCAN 式阈值策略提取簇结构。相较于单一固定半径的 DBSCAN,OPTICS 更适合分析不同密度水平下的簇分布。”

10.2 结果解释模板

结果部分可写为:Labels 表反映每个样本所属簇及噪声点情况,而 Reachability 表及 Reachability Plot 更适合解释簇边界和密度层次。ClusterSummary 中的平均可达距离和平均核心距离可辅助判断各簇的紧密程度。需要特别说明的是,轮廓系数只基于非噪声样本计算,解释时应明确这一统计口径。

10.3 图表题注模板

  • 图 1 OPTICS 聚类结果散点图。
  • 图 2 OPTICS 可达距离曲线(Reachability Plot)。
  • 表 1 OPTICS 聚类标签与噪声点识别结果。
  • 表 2 OPTICS 簇汇总统计与模型评价指标。

11. 实现说明与注意事项

  1. 当前散点图使用的是预处理后的前两维特征,而不是原始尺度数据。
  2. cluster_method="dbscan" 时,界面要求 eps>0;不要把界面上的 0=自动 与底层代码的兼容逻辑混为一谈。
  3. 轮廓系数会排除噪声点 -1,因此它不能简单理解为“全体样本”的聚类质量指标。
  4. Reachability 工作表按 ordering_ 排序后输出,不是原始数据顺序。
  5. min_samples 设得过大,或数据本身密度结构较弱,可能出现大部分样本被判为噪声或仅形成很少的簇。

12. 单篇终审补充

12.1 图题与表题对齐建议

当前 OPTICS 模块的真实工作簿包含:

  • Parameters
  • RawData
  • ProcessedData
  • Labels
  • Reachability
  • ClusterSummary
  • Metrics
  • Charts

其中 Reachability 是这篇文档最应该在论文中单独强调的结果页,因为它直接对应 OPTICS 的排序可达距离输出,不能被简单并入普通聚类标签表。若正文只保留 LabelsClusterSummary,会把 OPTICS 写得过于接近 DBSCAN。

图文件保存在结果目录下的 plots/ 子目录,当前实现真实输出:

  • cluster_scatter.png
  • reachability_plot.png

因此图题建议分别写成“OPTICS 聚类散点图”“OPTICS 可达距离曲线”。不要把第二张图写成“损失收敛曲线”或“密度分布直方图”,因为它的含义是按 ordering_ 序列排列的 reachability。

12.2 终审说明

这篇文档最需要避免的误写,是把 Reachability 当作原始样本顺序下的逐点统计。当前实现明确按 model.ordering_ 重排后再导出 Reachability 表,因此图表和工作表都是“OPTICS 排序空间”的结果,而不是输入表顺序。

另外,当前 repro 脚本已经使用 repro_inputs/... 相对路径,结果目录中可见如 repro_inputs/window1_optics_input.csv 的输入引用。因此可复现性描述应按新框架写,不应再沿用旧版绝对路径口径。

12.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/聚类与降维/OPTICS-OPTICS,本次采用的代表性结果目录为 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341

主结果工作簿为 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341/optics_results.xlsx,实测工作表为:

  • Parameters
  • RawData
  • ProcessedData
  • Labels
  • Reachability
  • ClusterSummary
  • Metrics
  • Charts

Reachability 这一页在当前目录里是真实存在的,因此本轮结果不能被简化成普通聚类标签导出。论文或软件说明若只写 LabelsClusterSummary,会把 OPTICS 与 DBSCAN 的关键差异写丢。

本轮真实图文件为:

  • 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341/plots/cluster_scatter.png
  • 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341/plots/reachability_plot.png

因此当前目录应真实表述为“聚类散点图 + 可达距离曲线”双图结构,而不是别的密度曲线或收敛曲线。

复现实物方面,该目录实际包含:

  • 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341/repro_optics_optics.py
  • 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341/repro_inputs/window1_optics_input.csv

脚本中明确写成 INPUT_FILE = 'repro_inputs/window1_optics_input.csv'OUTPUT_FILE = 'optics_results.xlsx'。这说明当前目录内的 optics_results.xlsx 既是主结果口径,也是 repro 默认重建时会覆盖或重写的目标文件名,文档中应说明这一点,避免误把同名输出视作完全独立的新文件。

11. 软件实现核查补充(2026-07)

  • 当前主结果目录应写作 具体的算法3/聚类与降维/OPTICS-OPTICS/results/OPTICS-OPTICS分析结果_20260329_171341
  • 正文应围绕 LabelsReachabilityClusterSummaryMetricsCharts 来写。
  • 图证应对应 cluster_scatter.pngreachability_plot.png,并把可达距离曲线和最终簇解释清楚。
  • 复现脚本应按 repro_optics_optics.py + repro_inputs/window1_optics_input.csv 的口径说明。