
简介本资源是面向机器学习初学者与Matlab实践者的Iris数据集K均值聚类完整实现包聚焦无监督学习核心算法的代码级落地与可视化验证。压缩包共6个文件3个txt说明文档、1个cpp源码、1个dat数据文件、1个exe可执行程序总大小仅32KB轻量易部署其中cpp文件提供K-Means核心逻辑dat文件封装Iris四维特征数据exe支持一键运行聚类结果txt文件含操作指引、算法说明及来源备注结构紧凑、即开即用。已有235人下载学习适合课程实验、算法原理验证及Matlab聚类入门实战。读者可直接复现从数据加载、聚类迭代到二维散点图可视化的全流程深入理解初始中心敏感性、收敛判据设定及聚类效果评估方法为后续学习DBSCAN、GMM等进阶聚类算法奠定扎实实践基础。1. Iris 数据集上跑通 K-means 聚类为什么用 MATLAB 做比 Python 更快看到聚类边界你手头有一份Iris.csv或 MATLAB 自带的meas/species数据想快速验证 K-means 是否能自动分出三类花——但不是为了发论文而是要当天下午就给产线同事演示「无标签数据也能分组」。这时候打开 MATLAB5 行代码画出散点图聚类中心划分边界比配环境、装 scikit-learn、调 random_state、反复改 n_init 还快。标题里反复出现的KMEANS.zip_Iris聚类matlab不是巧合它代表一类真实需求——在教学、快速原型、嵌入式算法预研或与 Simulink 联合仿真场景下用 MATLAB 原生函数完成端到端聚类验证不依赖外部包、不碰编译、不处理 pip 冲突。iris matlab和k均值聚类matlab是高频搜索词背后是高校实验课助教、工业检测算法工程师、控制系研究生的真实工作流他们需要可复现、可截图、可嵌入报告、能直接导出.m文件供后续 Simulink 调用的聚类结果。本文不讲 K-means 数学推导只聚焦一件事如何用最简原生 MATLAB 语法在 Iris 上跑出可解释、可调试、可复用的 K-means 聚类流程并避开 90% 新手卡住的坑。2. 用kmeans()在 Iris 上跑通最小闭环从加载数据到可视化聚类边界2.1 加载 Iris 数据别用csvread()load fisheriris.mat才是 MATLAB 官方推荐路径MATLAB 自带 Fisher Iris 数据集存于fisheriris.mat包含两个变量meas150×4 矩阵四维特征萼片长宽、花瓣长宽和species150×1 cell真实类别标签。这是最稳妥的起点——避免手动下载 CSV、编码错误、列名错位。% 推荐直接加载官方 mat 文件MATLAB R2014a 及以后版本均内置 load fisheriris.mat % 此时工作区自动出现 meas (150x4) 和 species (150x1 cell) size(meas) % ans 150 4 numel(species) % ans 150注意不要用readtable(iris.csv)或csvread()。前者返回 table 类型kmeans()不接受后者在中文路径或 UTF-8 BOM 下易报错。load fisheriris.mat是 MathWorks 官方文档明确指定的 Iris 加载方式见doc kmeans示例零兼容性风险。2.2 调用kmeans()核心参数只有 3 个但MaxIter和Replicates必须显式设kmeans()默认使用欧氏距离、k-means 初始化、100 次最大迭代、10 次重复运行取最优。但对 Iris 这种小数据这些默认值常导致「结果每次都不一样」或「收敛太慢」。必须显式控制% 设置 K3Iris 有 3 类并强制 Replicates5至少 5 次随机初始化 [idx, C, sumd, D] kmeans(meas, 3, ... MaxIter, 200, ... % 防止陷入局部极小而过早停止 Replicates, 5, ... % 多次重启选总距离最小的一次 Distance, sqeuclidean, ... % 显式声明避免隐式转换开销 EmptyAction, singleton); % 防止某类无样本时崩溃Iris 不会但养成习惯idx: 150×1 向量每个样本的聚类标签1/2/3C: 3×4 矩阵三个聚类中心坐标每行对应一个中心的四维特征sumd: 3×1 向量每个聚类内所有点到中心的平方欧氏距离之和D: 150×3 矩阵每个样本到三个中心的距离用于后续可视化逻辑说明kmeans()返回的是硬聚类hard clustering结果即每个点只属于一个类。Replicates是关键——它让算法在不同初始中心下运行多次最终选sumd总和最小的一次。Iris 数据虽小但若设Replicates1可能因初始化差导致聚类错误如把 versicolor 和 virginica 混为一类。2.3 可视化聚类结果用gscatter()画原始分布再叠加plot()画中心和边界仅看idx向量无法判断聚类质量。必须可视化先画原始四维数据的二维投影常用前两维萼片长 vs 萼片宽再标出聚类中心最后画 Voronoi 边界即 K-means 的决策边界。% 取前两维做散点图更直观 figure; gscatter(meas(:,1), meas(:,2), idx, rgb, o, 8); % 按聚类结果着色 hold on; plot(C(:,1), C(:,2), kx, MarkerSize, 12, LineWidth, 2); % 黑叉标中心 xlabel(Sepal Length (cm)); ylabel(Sepal Width (cm)); title(K-means Clustering on Iris (First Two Features)); legend(Cluster 1,Cluster 2,Cluster 3,Centroids); grid on;参数说明gscatter(x,y,group)中group必须是数值向量idx正好满足rgb指定三类颜色o是标记形状8是大小。plot(C(:,1),C(:,2),kx)用黑叉画中心——注意C是 3×4取第1、2列对应前两维坐标。2.4 绘制 Voronoi 决策边界这才是 K-means 的「真实划分」散点图只能看分组Voronoi 图才能显示「空间划分规则」。MATLAB 提供voronoi()函数但需将聚类中心作为输入点% 计算 Voronoi 图仅基于中心点 vx C(:,1); vy C(:,2); [vxout,vyout] voronoi(vx,vy); plot(vxout,vyout,k--,LineWidth,1.2); axis equal;逻辑说明Voronoi 图将平面划分为若干区域每个区域内任意点到对应中心的距离小于到其他中心的距离——这正是 K-means 的决策逻辑。叠加后你能清晰看到为何某些 versicolor 样本被划入 cluster 1因为它们离 cluster 1 中心更近即使人眼觉得该点「应该」属于另一类。这就是无监督学习的客观性。3. 评估聚类效果不用外部指标MATLAB 原生函数就能算轮廓系数和 Calinski-Harabasz3.1 用silhouette()算轮廓系数量化每个点的聚类合理性轮廓系数Silhouette Score范围 [-1,1]越接近 1 表示聚类越合理。MATLAB 原生支持无需sklearn.metrics.silhouette_score% 计算 silhouette 值基于欧氏距离 silh silhouette(meas, idx, sqeuclidean); figure; histogram(silh, 20); xlabel(Silhouette Value); ylabel(Frequency); title(sprintf(Average Silhouette: %.3f, mean(silh)));silh是 150×1 向量每个元素对应一个样本的 silhouette 值平均值 0.7 表示聚类结构强0.5~0.7 一般0.25 则聚类意义弱参数说明第三个参数sqeuclidean必须与kmeans()中Distance一致否则距离计算不匹配。Iris 的平均 silhouette 通常在 0.6~0.75 之间说明 K-means 对 Iris 效果中等偏上——这与事实吻合Iris 中 setosa 完全可分但 versicolor 和 virginica 有重叠。3.2 用evalclusters()自动选 K避免拍脑袋定 K3虽然 Iris 已知 K3但实际项目中 K 未知。evalclusters()可自动尝试 K1~6用不同准则评估% 尝试 K1 到 6用 Calinski-Harabasz 准则 eva evalclusters(meas, kmeans, CalinskiHarabasz, KList, 1:6); figure; plot(eva); title(Calinski-Harabasz Evaluation); xlabel(Number of Clusters (K)); ylabel(Score);CalinskiHarabasz准则类间离散度 / 类内离散度越大越好eva.OptimalK直接返回最优 KIris 通常返回 3其他可选CriterionSilhouette、Gap需提供 reference distribution逻辑说明evalclusters()内部会多次调用kmeans()所以耗时比单次运行高。但它输出的是客观指标曲线而非主观判断。对新手这是避免「我感觉 K4 更好」这类玄学决策的后悔药。3.3 与真实标签对比用clustermetrics计算 Adjusted Rand Index既然 Iris 有真值就该验证聚类是否靠谱。MATLAB R2023b 起内置clustermetrics但老版本可用randindex需自行实现或contingencytable% 将 cell 类型 species 转为数值标签setosa1, versicolor2, virginica3 true_labels grp2idx(species); % 自动按字典序编号setosa→1, versicolor→2, virginica→3 % 计算 Adjusted Rand Index需 Statistics and Machine Learning Toolbox if ver(stats) ver(12.0) % R2021a ari adjustedRandIndex(idx, true_labels); fprintf(Adjusted Rand Index: %.4f\n, ari); % 理想值为 1.0 else % 兼容旧版用 contingency table 手动算 ct confusionmat(true_labels, idx); % 后续计算 ARI 公式略本文聚焦原生方案旧版建议升级 end参数说明grp2idx()是安全转换方式比categorical(species)double()更稳定。ARI 值 0.7 表示聚类结果与真实标签高度一致。Iris 上 K-means 通常得 0.7~0.85说明它能较好还原已知结构。4. 避坑K-means 在 Iris 上的 4 个典型翻车现场与血泪解法4.1 现象kmeans()报错X must have more rows than columns原因传入了转置矩阵如kmeans(meas, 3)。meas是 150×4meas是 4×150MATLAB 认为「4 行 3 类」违反最小样本数要求。解决永远确保数据矩阵是n_samples × n_features格式。检查size(meas)若第二维是 150则meas meas;。4.2 现象聚类结果每次运行都不一样且idx中出现0或4原因EmptyAction默认为drop当某次初始化导致某类无样本时kmeans()会丢弃该类导致idx中标签不连续如只有 1,2,4。解决显式设置EmptyAction, singleton强制每类至少有一个点哪怕只是离群点保证标签为 1,2,3。4.3 现象Voronoi 边界画出来是碎线段或超出图框乱飞原因voronoi()默认绘制无限延伸的射线而gscatter()的坐标轴范围有限导致截断。解决用xlim/ylim手动设图框或改用voronoiDiagram()R2019a获取有限多边形% 替代方案获取有限 Voronoi 区域推荐 v voronoiDiagram([vx,vy]); % 后续用 v.Vertices, v.Regions 提取多边形顶点代码略需 polygon 处理4.4 现象silhouette()报错X and y must have the same number of rows原因idx是double类型但silhouette()要求y是整数向量。若idx由kmeans()返回通常是double但某些旧版 MATLAB 或手动赋值时可能混入NaN。解决强制转换并清理idx round(idx); % 确保为整数 idx(isnan(idx)) 1; % 填充 NaN理论上 kmeans 不产生 NaN但防御性编程 silh silhouette(meas, idx, sqeuclidean);血泪经验所有kmeans()输出都应视为double但下游函数如silhouette,confusionmat对类型敏感。宁可多写一行round()和isnan()检查也别等报错再 debug。5. 进阶技巧把 K-means 封装成可复用函数支持批量数据与参数配置5.1 写一个iris_kmeans.m函数输入数据、K、选项输出结构体把前面所有步骤封装成函数避免重复粘贴代码。函数签名设计为function result iris_kmeans(X, K, opts) % IRIS_KMEANS 对输入数据 X 执行 K-means 聚类返回完整结果 % 输入 % X: n x d 数据矩阵如 meas % K: 聚类数 % opts: 结构体含字段 MaxIter, Replicates, Distance, Plot2D是否画图 % 输出 % result.idx, result.centroids, result.silhouette_avg, result.ari 等 % 默认选项 defaults.MaxIter 200; defaults.Replicates 5; defaults.Distance sqeuclidean; defaults.Plot2D true; opts mergeopts(opts, defaults); % 自定义 mergeopts 函数见下方 % 执行 kmeans [idx, C, sumd, D] kmeans(X, K, ... MaxIter, opts.MaxIter, ... Replicates, opts.Replicates, ... Distance, opts.Distance, ... EmptyAction, singleton); % 计算评估指标 silh silhouette(X, idx, opts.Distance); result.idx idx; result.centroids C; result.silhouette_avg mean(silh); result.sumd sumd; result.D D; % 可选绘图 if opts.Plot2D size(X,2) 2 figure; gscatter(X(:,1), X(:,2), idx, rgb, o, 6); hold on; plot(C(:,1), C(:,2), kx, MarkerSize, 10); title(sprintf(K-means (K%d), Avg Silhouette %.3f, K, result.silhouette_avg)); end end配套的mergeopts函数放在同一文件末尾function opts mergeopts(user, default) % 合并用户选项与默认选项用户未设的用默认值 opts default; fields fieldnames(user); for i 1:length(fields) f fields{i}; if isfield(user, f) opts.(f) user.(f); end end end逻辑说明此函数屏蔽了底层细节使用者只需r iris_kmeans(meas, 3, struct(Plot2D,false))即可静默运行。结构体opts使参数管理清晰避免函数签名爆炸。mergeopts是 MATLAB 工程实践标配比varargin更安全。5.2 批量测试不同 K 值用arrayfun一键生成评估表不用 for 循环用函数式写法批量跑 K2~5K_list 2:5; results arrayfun((k) iris_kmeans(meas, k, struct(Plot2D,false)), ... K_list, UniformOutput, false); % 整理成表格 T table(K_list, ... cell2mat(cellfun((r) r.silhouette_avg, results, UniformOutput, false)), ... cell2mat(cellfun((r) sum(r.sumd), results, UniformOutput, false)), ... VariableNames, {K, AvgSilhouette, TotalSumd}); disp(T);KAvgSilhouetteTotalSumd20.621125.630.67278.940.58362.450.52154.7参数说明arrayfun对每个 K 调用iris_kmeansUniformOutput,false返回 cell 数组再用cell2mat提取数值。TotalSumd越小表示聚类越紧凑但 K 过大会过拟合——这里 K3 的AvgSilhouette最高TotalSumd下降明显是最佳平衡点。5.3 导出聚类结果为 Simulink 可用格式.mat和.m双保险工业场景常需将聚类中心部署到 Simulink 模型中做实时分类% 导出中心点为 .matSimulink From File 模块可读 save(iris_kmeans_centers.mat, C); % 同时生成 .m 脚本Simulink MATLAB Function 模块可调用 fid fopen(classify_iris.m,w); fprintf(fid, function label classify_iris(x)\n); fprintf(fid, %% x: 1x4 特征向量\n); fprintf(fid, C %s;\n, mat2str(C, 4)); % 转为字符串精度 4 位 fprintf(fid, dist sqrt(sum((repmat(x,[3,1]) - C).^2,2));\n); fprintf(fid, label find(dist min(dist), 1);\n); fclose(fid);逻辑说明.mat文件供 Simulink 的「From File」模块加载.m脚本供「MATLAB Function」模块调用其中mat2str(C,4)将中心矩阵转为可执行代码避免运行时依赖外部文件。这是 MATLAB 工程落地的关键一步——聚类不能只停留在 Figure 窗口。我写这个函数时踩过最大的坑是忘了kmeans()对EmptyAction的默认行为导致某次产线测试中聚类标签突然变成 1,2,4下游 PLC 解析失败。从此所有kmeans()调用都加EmptyAction就像写 C 语言必加\0结尾。希望帮到你。本文还有配套的精品资源点击获取