ISODATA-ISODATA
ISODATA(Iterative Self-Organizing Data Analysis Technique)通常被理解为一种在 K-Means 基础上引入簇分裂与簇合并机制的自适应聚类方法。与固定簇数的传统 K-Means 不同,ISODATA 会在迭代过程中根据簇内离…
ISODATA-ISODATA
1. 方法概述
ISODATA(Iterative Self-Organizing Data Analysis Technique)通常被理解为一种在 K-Means 基础上引入簇分裂与簇合并机制的自适应聚类方法。与固定簇数的传统 K-Means 不同,ISODATA 会在迭代过程中根据簇内离散程度和簇间距离动态调整簇结构,从而在一定程度上实现“边聚类、边修正簇数”。
本项目中的 ISODATA-ISODATA 模块并不是直接调用现成的 ISODATA 库,而是实现了KMeans 初始化 + 迭代重分配 + 小簇清理 + 分裂/合并的自写流程。根据当前代码,模块的核心特征包括:
- 先以
sklearn.cluster.KMeans生成初始簇中心; - 迭代执行样本重分配、删除过小簇并重新分配;
- 根据簇内最大标准差与平均距离决定是否分裂;
- 根据簇中心距离决定是否合并;
- 若某轮既没有分裂也没有合并,且标签不再变化,则提前停止。
设共有 \(n\) 个样本、\(p\) 个参与聚类的数值特征。记原始特征矩阵为
$$ X=(x_{ij})_{n\times p},\quad i=1,2,\ldots,n,\ j=1,2,\ldots,p \tag{1} $$
当前界面约定第 1 列必须为样本 ID/名称,其余列为数值型特征;指标页默认采用第 1 列以外的全部列参与聚类,当前 UI 实际上并未提供逐列勾选开关。
2. 问题定义与数据预处理
对第 \(i\) 个样本,记其特征向量为 \(x_i\in\mathbb{R}^p\)。项目支持 none、standard、minmax 三种预处理方式。
2.1 Z-score 标准化
当 normalization="standard" 时,程序调用 StandardScaler 对每个特征执行标准化:
$$ z_{ij}=\frac{x_{ij}-\mu_j}{\sigma_j} \tag{2} $$
其中 \(\mu_j\) 与 \(\sigma_j\) 分别为第 \(j\) 个特征的均值与标准差。
2.2 Min-Max 归一化
当 normalization="minmax" 时,程序调用 MinMaxScaler 执行归一化:
$$ z_{ij}=\frac{x_{ij}-x_j^{\min}}{x_j^{\max}-x_j^{\min}} \tag{3} $$
若 normalization="none",则直接令 \(z_{ij}=x_{ij}\)。经预处理后得到实际参与聚类的矩阵
$$ Z=(z_{ij})_{n\times p} \tag{4} $$
2.3 符号说明
| 符号 | 含义 |
|---|---|
| \(n\) | 样本数量 |
| \(p\) | 特征维数 |
| \(K_0\) | 初始簇数 clusters |
| \(K_t\) | 第 \(t\) 轮迭代时的簇数 |
| \(z_i\) | 第 \(i\) 个样本的预处理后特征向量 |
| \(c_k^{(t)}\) | 第 \(t\) 轮第 \(k\) 个簇中心 |
| \(y_i^{(t)}\) | 第 \(t\) 轮样本 \(i\) 的簇标签 |
| \(n_k^{(t)}\) | 第 \(t\) 轮第 \(k\) 个簇的样本数 |
| \(d_{ik}^{(t)}\) | 样本 \(i\) 到第 \(k\) 个簇中心的距离 |
| \(\delta_s\) | 分裂标准差阈值 split_std_threshold |
| \(\delta_m\) | 合并距离阈值 merge_threshold |
| \(n_{\min}\) | 最小簇大小 min_cluster_size |
| \(K_{\max}\) | 最大簇数 max_clusters |
3. 核心数学模型
3.1 KMeans 初始化
程序首先以用户设定的初始簇数 clusters=K_0 对预处理后的数据执行 KMeans 初始化。其优化目标可写为
$$ \min_{\{G_k,c_k\}_{k=1}^{K_0}} \sum_{k=1}^{K_0}\sum_{z_i\in G_k}\|z_i-c_k\|_2^2 \tag{5} $$
初始化阶段的样本标签由
$$ y_i^{(0)}=\arg\min_{1\le k\le K_0}\|z_i-c_k^{(0)}\|_2 \tag{6} $$
得到。当前代码中,KMeans 固定使用 n_init=10,最大迭代次数直接复用 max_iter,随机性由 random_state 控制。
3.2 迭代重分配与中心重估
在后续每轮迭代中,程序都按最近中心重新分配样本:
$$ y_i^{(t)}=\arg\min_{1\le k\le K_t}\|z_i-c_k^{(t)}\|_2 \tag{7} $$
在标签给定时,第 \(k\) 个簇的中心按样本均值重估:
$$ c_k^{(t+1)}=\frac{1}{n_k^{(t)}}\sum_{i:y_i^{(t)}=k}z_i \tag{8} $$
如果某个簇为空,则当前实现会在重估中心时直接跳过该空簇,不保留空簇中心。
3.3 小簇删除与重新分配
当前实现不是把过小簇标记为噪声,而是将其直接删除后重新分配全部样本。若第 \(k\) 个簇的样本数满足
$$ n_k^{(t)}<n_{\min} \tag{9} $$
则该簇不会被保留。设保留下来的中心集合为 \(\mathcal{C}_{\text{keep}}^{(t)}\),程序会基于这些中心重新对全部样本执行式(7) 的最近中心分配。
这意味着,虽然代码和结果参数中预留了 noise_count 字段,当前实现流程下通常不会真正产生 -1 噪声标签;小簇样本会被重新吸收到其他簇,而不是被丢弃为噪声点。
3.4 簇统计量
对第 \(k\) 个簇,程序计算簇内平均距离
$$ \bar d_k=\frac{1}{n_k}\sum_{i:y_i=k}\|z_i-c_k\|_2 \tag{10} $$
并计算每个特征维度上的标准差向量
$$ s_k=(s_{k1},s_{k2},\ldots,s_{kp}) \tag{11} $$
其中
$$ s_{kj}=\sqrt{\frac{1}{n_k}\sum_{i:y_i=k}(z_{ij}-c_{kj})^2} \tag{12} $$
程序在 Stats 表中额外输出
$$ s_k^{\max}=\max_{1\le j\le p}s_{kj} \tag{13} $$
用于后续分裂判定。
3.5 分裂规则
若启用分裂,即 split_std_threshold > 0,程序会筛选满足以下条件的簇作为分裂候选:
- 簇大小至少满足 \(n_k \ge 2n_{\min}\);
- 最大标准差满足 \(s_k^{\max}>\delta_s\);
- 该簇平均距离大于当前所有非空簇平均距离的总体均值。
设总体平均距离为
$$ \bar d_{\text{all}}=\frac{1}{|\mathcal{K}_{+}|}\sum_{k\in\mathcal{K}_{+}}\bar d_k \tag{14} $$
其中 \(\mathcal{K}_{+}\) 为非空簇集合。若某个簇 \(k\) 满足
$$ n_k\ge 2n_{\min},\qquad s_k^{\max}>\delta_s,\qquad \bar d_k\ge \bar d_{\text{all}} \tag{15} $$
则该簇有资格被分裂。程序会取标准差最大的维度
$$ j_k^*=\arg\max_{1\le j\le p}s_{kj} \tag{16} $$
并沿该维度把原中心 \(c_k\) 拆成两个新中心:
$$ c_k^{(+)}=c_k+\frac{1}{2}s_k^{\max}e_{j_k^*},\qquad c_k^{(-)}=c_k-\frac{1}{2}s_k^{\max}e_{j_k^*} \tag{17} $$
其中 \(e_{j_k^*}\) 为第 \(j_k^*\) 个标准基向量。当前实现还会受最大簇数 \(K_{\max}\) 限制;若本轮继续分裂会使簇数超过上限,则停止增加新簇。
3.6 合并规则
若启用合并,即 merge_threshold > 0,程序会计算任意两个簇中心之间的距离:
$$ D_{ab}=\|c_a-c_b\|_2,\qquad a<b \tag{18} $$
当两簇中心距离满足
$$ D_{ab}<\delta_m \tag{19} $$
时,二者会进入合并候选集合。程序按距离从小到大排序后,采用“每个簇在本轮最多参与一次合并”的策略。若簇 \(a\) 与簇 \(b\) 被合并,则新中心按簇大小加权平均:
$$ c_{ab}=\frac{n_a c_a+n_b c_b}{n_a+n_b} \tag{20} $$
这使得样本数更多的簇对合并后的中心位置影响更大。
3.7 停止条件
程序最多执行 max_iter 轮外层迭代。若相邻两轮的标签完全一致,且本轮没有发生分裂和合并,则提前停止,即满足
$$ y^{(t)}=y^{(t-1)},\qquad \text{split\_count}^{(t)}=0,\qquad \text{merge\_count}^{(t)}=0 \tag{21} $$
时终止。这是当前实现的主要收敛判据。
4. 算法流程
结合当前项目代码,ISODATA-ISODATA 的实际流程如下:
- 读取数据文件,要求至少两列:第 1 列为样本 ID,其余列为数值型特征。
- 上传阶段通过
DataValidator检查:- 数据不能为空;
- 第 1 列样本名称不能重复;
- 其余列必须能转成数值且不能含空值;
- 其余列不能是常数列。
- 指标页默认把第 1 列以外的全部列作为聚类特征。
- 按
normalization设置对特征矩阵执行none、standard或minmax预处理。 - 以 KMeans 生成初始簇标签和初始中心。
- 迭代执行最近中心分配、小簇删除并重分配、簇统计计算、分裂和合并。
- 若标签不再变化且本轮无分裂/合并,则提前停止;否则继续,直到达到
max_iter。 - 生成
Labels、Summary、Stats与Parameters等结果表。 - 当特征数大于 2 时,用 PCA 把数据投影到二维后绘制聚类散点图;当特征数等于 2 时直接用前两维作图;当特征数等于 1 时补零形成单轴散点图。
- 导出 Excel 文件和可视化图,并自动生成复现脚本
repro_isodata_isodata.py。
5. 关键参数说明
5.1 clusters
初始簇数 \(K_0\),界面允许范围为 1 到 1000,默认值为 3。程序会把它截断到不超过样本数的范围内,因此实际初始化簇数为
$$ K_0=\min(\texttt{clusters},n) \tag{22} $$
但最少会保留 1 个簇。
5.2 max_iter
最大迭代次数,界面允许范围为 1 到 5000,默认值为 300。它同时影响 KMeans 初始化阶段和后续外层 ISODATA 迭代的最大轮数。
5.3 min_cluster_size
最小簇大小 \(n_{\min}\),界面允许范围为 1 到 1000,默认值为 1。若某个簇样本数小于该阈值,程序不会把它保留为独立簇,而是删除后重新分配。
5.4 max_clusters
最大簇数上限,界面允许范围为 0 到 1000,默认值为 0。其中 0 表示自动,当前实现会把最大簇数设为
$$ K_{\max}=\max\left(K_0,\ \min\left(n,\ \operatorname{round}(2.5K_0)\right)\right) \tag{23} $$
若用户显式输入正整数,则程序会在不小于 \(K_0\) 且不超过样本数的范围内取该值。
5.5 merge_threshold
合并阈值 \(\delta_m\),界面允许范围为 0.0 到 1e6,默认值为 0.0。当其为 0 时,合并功能关闭;当其大于 0 时,中心距离小于该阈值的簇可能被合并。
5.6 split_std_threshold
分裂标准差阈值 \(\delta_s\),界面允许范围为 0.0 到 1e6,默认值为 0.0。当其为 0 时,分裂功能关闭;当其大于 0 时,满足式(15) 的簇可能被沿最大标准差方向分裂。
5.7 normalization
预处理方式取值为:
nonestandardminmax
若不同特征量纲差异较大,通常建议优先尝试 standard 或 minmax。
5.8 random_state
随机种子。界面中留空表示随机;输入整数时,程序会把该值同时传给 KMeans 初始化和 PCA 二维投影,以提高结果复现性。
6. 评价指标与输出结果解释
程序在主流程中会把结果保存到形如
results/ISODATA-ISODATA分析结果_<时间戳>/
的目录下,文件名通常为:
isodata_result_<时间戳>.xlsxisodata_plot_<时间戳>.pngrepro_isodata_isodata.pyrepro_inputs/
当前 Excel 输出结构与前面几个聚类模块不同,固定包含以下工作表:
RawData:原始数据表。Features:参与聚类的原始数值特征矩阵。需要注意,这里输出的是数值化后的特征,而不是标准化/归一化后的矩阵。Labels:样本 ID 与最终簇标签。Summary:每个簇的标签和样本数量。Stats:每个簇的样本数、平均距离和最大标准差。Parameters:参数配置以及最终统计量,如cluster_count、noise_count、iterations、split_total、merge_total、max_clusters。Charts:聚类图路径索引。
从结果解释角度看:
Summary中的count反映每个最终簇的规模。Stats中的avg_dist越小,说明该簇内部越紧凑。Stats中的max_std越大,说明该簇在某个维度上的离散程度越高,也越有可能触发分裂。Parameters中的iterations是外层 ISODATA 迭代轮数,不是单独的 KMeans 迭代次数。split_total与merge_total分别表示本次运行累计发生的分裂次数和合并次数。cluster_count表示最终非负标签簇数;当前实现下noise_count通常为 0。- 可视化图在高维情形下使用 PCA 投影到二维,因此图中的空间位置是二维投影结果,不等于原始高维空间中的真实几何关系。
7. 论文写作模板
7.1 方法描述模板
可将当前项目实现表述为:
“本文采用 ISODATA 聚类方法对样本进行无监督分类。首先对样本特征进行预处理,并以 KMeans 聚类结果作为初始划分。随后在迭代过程中,根据簇中心重新分配样本,删除样本数过少的簇,并依据簇内最大标准差和簇间中心距离分别执行分裂与合并操作。若某轮迭代中簇标签不再变化且未发生新的分裂或合并,则停止计算。最终输出样本聚类标签、各簇样本数量、簇内平均距离、最大标准差以及分裂/合并次数,用于分析样本的自适应聚类结构。”
若需要更贴近本项目工程实现,还可补充说明:本文实现并未将过小簇直接作为噪声剔除,而是把其样本重新分配到其他簇;因此结果更接近“动态调整簇数的 KMeans 扩展版”。
7.2 结果解释模板
结果部分可写为:ISODATA 在迭代过程中通过分裂与合并机制动态调整簇数,因此最终分组结果不仅反映样本间距离结构,也体现了簇规模与簇内离散程度的共同约束。若分裂次数较多,说明初始簇内部存在较强异质性;若合并次数较多,则说明部分簇中心间差异不足。
7.3 表格标题模板
表题可写为:ISODATA 聚类结果及分裂合并统计表。
7.4 图表题注模板
图注可写为:ISODATA 自适应聚类结果与簇中心分布图。
7.5 表格示例
建议列名:簇编号、样本数、簇内平均距离、最大标准差、分裂次数、合并次数、最终标签。
8. 实现说明与注意事项
- 当前实现适合希望在 KMeans 基础上引入簇分裂和簇合并机制的场景,尤其适合簇数不完全确定的数据。
- 上传阶段要求第 1 列样本名称唯一,其余列必须全部为数值型且不能为常数列。
- 当前指标页虽然提示“选择/确认特征列”,但实际实现默认采用第 1 列之外的全部列,没有逐列勾选逻辑;论文中应按实际参与聚类的列集合说明。
merge_threshold=0或split_std_threshold=0时,对应机制会被关闭,此时算法更接近普通 KMeans 迭代重分配流程。- 旧版问题记录文件中曾提到“拆分/合并阈值未生效”,但当前
core/isodata_calculator.py已实现拆分与合并,论文说明应以当前代码为准。 - 当前结果 Excel 不输出标准化/归一化后的特征矩阵,也不输出各簇中心表;若论文需要展示标准化空间中的中心位置,需要额外从代码流程或图形结果补充说明。
- 程序预留了
noise_count统计,但当前实现中小簇样本会被重新分配,因此通常不会得到真正的噪声标签-1。 - 二维可视化在高维情况下依赖 PCA 投影,只能作为辅助解释,不能完全代表高维空间中的真实簇形结构。
9. 论文写作建议
论文中建议重点解释 ISODATA 相比 KMeans 的两点扩展:
- 簇分裂;
- 簇合并。
结果表最好同时报告初始簇数、最终簇数、分裂/合并阈值和最终聚类评价指标。若论文需要强调方法优势,可补充与普通 KMeans 在相同数据上的结果对比。
10. 单篇终审补充
10.1 图题与表题对齐建议
当前 ISODATA 模块的真实工作簿包含:
RawDataFeaturesLabelsSummaryStatsParametersCharts
这里最需要注意的是,当前实现真实导出的是 Features,而不是很多聚类模块常见的 ProcessedData。因此论文表题若引用该表,更准确的写法应是“ISODATA 参与聚类特征矩阵”或“ISODATA 建模特征表”,不要机械套用其他算法的“预处理后数据表”表题。
图文件由 save_to_excel() 触发生成,真实命名口径可见两类:
isodata_plot_<时间戳>.png<xlsx 文件名 stem>_clusters.png
因此图题建议统一写成“ISODATA 聚类结果二维投影图”或“ISODATA 最终聚类分布图”,不要把文件名逐字写进论文;文件名本身在不同导出路径下会有时间戳差异,但图义是稳定的。
10.2 终审说明
这篇文档最容易误写的地方有两个。第一,当前实现虽然属于 ISODATA,但导出结果里并没有单独输出“簇中心表”,而是通过 Summary、Stats 和聚类图来体现最终结构,因此论文结果部分不应虚构一个“中心点工作表”。
第二,plot_clusters() 在高维场景下会先对归一化特征做 PCA 二维投影,再绘制 cluster 与 center 标记。因此图中黑色 X 更准确的解释是“投影空间中的簇中心近似位置”,而不是原始高维空间的真实中心坐标。这个口径需要在论文图注或正文中点明。
10.3 全量强化补充
本次全量强化绑定的真实结果目录为 具体的算法3/聚类与降维/ISODATA-ISODATA/results/ISODATA-ISODATA分析结果_20260329_171259。该目录内主工作簿为 isodata_result_20260329_171259.xlsx,实际工作表为 RawData、Features、Labels、Summary、Stats、Parameters、Charts。这说明当前单轮结果仍然没有独立的簇中心工作表,文档正文应继续保持这一写实口径,不能额外虚构“中心表”。
同一目录下实际存在两张图:isodata_plot_20260329_171259.png 与 isodata_result_20260329_171259_clusters.png。前者对应程序主绘图输出,后者对应按结果文件 stem 生成的聚类投影图;二者都是真实产物,因此论文图题可以统一概括为“ISODATA 聚类二维投影图”和“ISODATA 最终聚类分布图”,但不应把它们误解为不同算法步骤的两种完全独立可视化。
复现脚本为 repro_isodata_isodata.py,目录内 repro_inputs/window2_isodata_baseline_input.csv 真实存在。脚本当前参数写法为 INPUT_FILE = 'repro_inputs/window2_isodata_baseline_input.csv'、OUTPUT_FILE = 'isodata_result_20260329_171259.xlsx',并绑定 clusters = 3、max_iter = 300、min_cluster_size = 1、max_clusters = 6、merge_threshold = 0.6、split_std_threshold = 0.35、normalization = 'none'、random_state = 11。因此 ISODATA 当前也已经具备相对路径输入副本和单目录 repro 链,工程复现口径是完整的。
11. 软件实现核查补充(2026-07)
- 当前主结果目录应写作
具体的算法3/聚类与降维/ISODATA-ISODATA/results/ISODATA-ISODATA分析结果_20260329_171259。 - 正文应围绕
RawData、Features、Labels、Summary、Stats、Parameters、Charts来写。 - 图证应对应
isodata_plot_20260329_171259.png与isodata_result_20260329_171259_clusters.png,并把分裂/合并、再分配和中心投影图说明清楚。 - 复现脚本应按
repro_isodata_isodata.py + repro_inputs/window2_isodata_baseline_input.csv的口径说明。