尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

MATLAB中SOM聚类的完整实现:从原理到可视化

发布时间:2026/9/16 19:01:00

资讯中心
01
ARTICLE

MATLAB中SOM聚类的完整实现:从原理到可视化

MATLAB中SOM聚类的完整实现:从原理到可视化
简介这是一份基于MATLAB的SOM自组织映射聚类实战案例以鱼类种类特征挖掘为切入点解决如何利用Kohonen网络对多维特征进行无监督聚类与可视化的问题。资源共2个文件main.m实现完整聚类流程attribute_color.mat提供配套颜色数据整体仅2KB轻量精炼。案例从selforgmap构建5x5网格网络入手涵盖数据标准化、train网络训练、BMU竞争映射到colorplot和scatterplot的二维拓扑可视化以及利用SOM输出进行进一步聚类的策略步骤连贯、注释清晰便于动手复现。代码中清晰标出网络尺寸、学习率与迭代次数等关键参数方便结合不同数据调整。已有756人学习其小巧的数据规模与演示路径对初学者友好也适合作为理解神经网络聚类原理的快速启动模板。读者可借此掌握SOM的非线性降维、拓扑保持特性并能将同一套方法扩展到其他特征聚类或探索性数据分析任务中。1. SOM 聚类在 MATLAB 里到底解决什么问题一提聚类大部分 MATLAB 用户第一反应是 kmeans。但数据一旦进入高维、簇形状不规则、类别边界模糊的状态kmeans 的球形质心假设很快失效结果经常把本该连成一片的样本切成好几块。SOM自组织映射把问题换了个角度它不直接在原始空间里找质心而是把高维输入映射到一个低维的神经元网格上让拓扑上相近的样本落到邻近的神经元。这意味着 SOM 同时完成三件事——聚类、降维、可视化训练完之后不仅能得到每个样本的归属还能用一张二维图直接观察数据里到底有几簇。本文要讲的是在 MATLAB 环境下把 SOM 聚类完整跑通的路径从工具箱选型、数据标准化、网格设计到二次聚类、效果评估和相关的排错经验适合做客户分群、图像特征量化、工业过程状态识别这类任务的工程师参考。2. SOM 原理与 MATLAB 里的对应实现2.1 竞争学习与 BMUSOM 聚类的核心机制SOM 属于竞争学习网络整个结构只有两层输入层和竞争层。竞争层里的每个神经元都携带一个与输入样本同维度的权重向量训练的过程就是不断寻找“最匹配神经元”Best Matching UnitBMU并只更新 BMU 及其邻域内神经元权重。更新公式的核心思想是让 BMU 的权重向当前样本靠近同时带动邻域内的神经元一起靠近但邻域半径会随训练轮次逐步收缩。正是这个“邻域收缩”机制让最终训练出的神经元网格在拓扑上保持了输入数据的结构原始空间中距离近的样本映射到网格上也是相邻的。对比 kmeans 聚类算法能看得更清楚。kmeans 只更新距离样本最近的质心质心之间没有任何空间位置关系SOM 的竞争层神经元天然排列在一个二维网格上邻域更新让相邻神经元之间的权重向量趋向平滑过渡。所以 SOM 网格本身就是一张保持拓扑的低维嵌入图这是它和传统聚类算法最大的区别。也正因为如此SOM 的用途不局限于给出类别标签它常被用来做数据可视化、特征映射和高维数据的初步探索。2.2 MATLAB 神经网络工具箱里的 SOM 函数MATLAB 中实现 SOM 聚类主要依赖 Deep Learning Toolbox旧称 Neural Network Toolbox里的自组织映射函数。老版本里常用的newsom在 R2010b 之后已经被selforgmap取代现在写新代码直接使用selforgmap即可。下面这张表列出的是实际动手时最常用到的几个函数。函数作用selforgmap(dimensions)创建自组织映射网络dimensions 是竞争层网格尺寸如[5 5]train(net, X)训练网络X 的每一列是一个样本net(X)或sim(net, X)对输入数据做预测返回竞争层的输出向量vec2ind(a)把 one-hot 形式的竞争层输出转换成神经元编号plotsomum(net)绘制 U-matrix观察簇边界plotsomhits(net, X)绘制命中图统计每个神经元覆盖的样本数plotsomplanes(net)绘制每个输入特征的权重平面图使用这套函数时要特别注意一个约定神经网络工具箱的数据格式是“每列一个样本”和 MATLAB 常见的数据处理习惯每行一个样本正好相反。如果直接用行样本数据去训练模型不会报错但聚类结果会完全不可用这是新手最容易踩的第一个坑。2.3 用最小代码在 MATLAB 里跑通 SOM 训练下面是一段最小可运行代码用三簇模拟数据演示 SOM 的完整训练流程。% 生成三簇二维数据每簇 100 个样本 rng(42); X [randn(100, 2) [2 2]; randn(100, 2) [-2 2]; randn(100, 2) [0 -2]]; X X; % 转换为工具箱格式每列一个样本 % 创建 5x5 的 SOM 网格 net selforgmap([5 5]); net.trainParam.epochs 200; % 训练 net train(net, X); % 预测并转换为神经元编号 y net(X); labels vec2ind(y);selforgmap([5 5])创建一个 5×5 的竞争层共 25 个神经元。train函数返回训练后的网络对象因为 SOM 是无监督训练不需要标签。net(X)得到的是每个样本在每个神经元上的激活值vec2ind取激活值最大的神经元作为该样本的映射位置。注意这里的labels是神经元编号取值范围是 1 到 25它代表样本落在网格的哪个位置还不是最终聚类类别。要把神经元编号变成业务意义上的分类还需要结合网格拓扑做进一步的类别映射这部分在下一章展开。3. 用 MATLAB 跑通 SOM 聚类的完整流程与参数设置3.1 数据标准化决定聚类质量的第一步SOM 使用欧氏距离计算样本与神经元权重之间的相似度因此对特征的尺度极其敏感。假设有两个特征一个取值范围是 0 到 1另一个是 0 到 10000后者会完全主导 BMU 的选择前面的特征等于被废掉。所以数据进入网络之前必须做标准化这是整个聚类流程里投入产出比最高的一步。我一般优先用 z-score 标准化因为它能保留特征的离群信息实现也简单mu mean(X, 2); sg std(X, 0, 2); Xn (X - mu) ./ sg; % 后续对新样本做预测时必须使用同一套 mu 和 sg X_new_norm (X_new - mu) ./ sg;mean(X, 2)按行计算均值std(X, 0, 2)按行计算标准差两者返回的都是与特征维度等长的向量。这里的关键点是训练结束后对任何新样本做预测只能用训练集算出的mu和sg不能拿新样本重新计算均值和方差。否则相当于改变了数据分布前面训练的模型就白做了。如果数据里有明显的离群点也可以改用mapminmax把数据压缩到[-1, 1]区间SOM 初始化时权重范围与输入范围更匹配。两种方法实验结果差异通常不大但 z-score 对后续 U-matrix 的解释更友好。3.2 网格规模SOM 超参数里最关键的一个网格大小直接决定聚类粒度。网格越大神经元越多能表达的细节越丰富但训练时间变长还会出现大量没有样本命中的“空神经元”网格太小簇边界会被过度平滑两个不同的类别可能被压缩到同一个神经元上。常见经验公式是网格神经元总数取样本量的平方根量级大约M 5 * sqrt(N)N 是样本总数。样本量建议网格神经元数量5005×52520007×74950009×9811000011×11121网格形状方面selforgmap默认使用hextop六边形拓扑相邻关系比gridtop方形拓扑更自然一般不需要改。实际训练时如果发现某个簇被切得太碎优先减小网格如果多个不同的业务类别挤在一个神经元里优先增大网格。3.3 selforgmap 的邻居结构与训练参数设置selforgmap的完整参数形式是net selforgmap(dimensions, coverSteps, initNeighbor, topologyFcn, distanceFcn); net.trainParam.epochs 300; net.trainParam.showWindow true; net train(net, Xn);coverSteps表示邻域半径从初始值收缩到 1 所需的训练步数默认是 100。这个参数控制“粗调”阶段的时长值越大前期邻域保持较大半径的时间越长网络更容易形成全局有序的拓扑结构。initNeighbor是初始邻域半径默认 3 表示覆盖大约 3 格范围的神经元数据维度高或者样本噪声大时可以适当提高到 4 或 5。topologyFcn指定网格拓扑distanceFcn指定神经元间的距离计算方式。默认的linkdist计算的是网格上的链接距离曼哈顿距离和六边形拓扑搭配效果好dist计算的是欧氏距离在网格上使用会削弱邻域关系的局部性一般不建议改。训练参数里最值得关注的是epochs。SOM 的权重更新分为两个阶段排序阶段ordering phase和收敛阶段convergence phase。排序阶段学习率大、邻域宽目的是快速形成全局有序的映射收敛阶段学习率小、邻域窄目的是精细调整权重。epochs如果小于 100排序阶段还没完成就进入收敛最终映射会乱我一般设置 200 到 500。3.4 把神经元编号映射成最终聚类标签SOM 训练完直接给出的labels是神经元编号要得到业务上可用的聚类结果常见做法是对神经元的权重向量再做一次聚类也就是“二次聚类”。这一步在 MATLAB 里实现起来很简单% 提取训练好的神经元权重每行一个神经元 W net.IW{1}; % 对权重做 k-means 聚类把神经元分成 K 类 K 3; neuLabel kmeans(W, K, Replicates, 10); % 把每个样本的神经元编号映射为类别 finalLabel neuLabel(labels);net.IW{1}是输入权重矩阵行数等于神经元数量列数等于输入特征维度每一行对应一个神经元的权重向量。kmeans(W, K, Replicates, 10)对权重做聚类Replicates表示用 10 组不同的初始质心运行并取最优结果避免局部最优。neuLabel(labels)利用 MATLAB 的索引语法把每个样本的神经元编号转换成二次聚类后的类别编号。为什么要对权重聚类而不是直接对原始数据聚类因为神经元的数量远小于样本数量对权重做 k-means 计算量小而且权重向量经过 SOM 训练后已经平滑化对噪声的鲁棒性更好。这一操作相当于先用 SOM 做数据压缩和拓扑保持再用传统聚类算法做类别划分也是实际项目中 SOM 最常见的落地方式。4. SOM 聚类结果的可视化与效果评估4.1 U-matrix看簇边界而不是簇中心U-matrix统一距离矩阵是 SOM 最核心的可视化工具。它计算每个神经元与相邻神经元权重向量之间的平均距离用颜色深浅表示颜色浅表示相邻神经元权重接近属于同一簇内部颜色深表示相邻神经元权重差异大是簇与簇之间的边界。在 MATLAB 中一行代码就能画出来plotsomum(net);U-matrix 和常见的聚类热图是两种不同的东西。聚类热图是对样本-特征矩阵按聚类结果重排后的可视化展示的是原始数据的数值分布U-matrix 展示的是 SOM 网格上的拓扑距离直接反映数据在低维映射后的簇结构。看 U-matrix 时关注深色区域围成的浅色板块每个浅色板块大致对应一个簇。如果整个图颜色均匀没有明显边界说明数据本身可能没有清晰的簇结构或者网格设置不合适。4.2 命中图与权重平面图命中图plotsomhits(net, Xn)统计每个神经元覆盖的样本数量用圆的大小表示。这个图有两个用途第一观察空神经元比例如果超过三分之一的位置没有样本命中说明网格偏大可以缩小第二观察簇的密度分布样本高度集中在某几个神经元上说明这些区域的原始数据分布密集。对高维数据还可以用plotsomplanes(net)画出每个特征在网格上的权重平面图观察每个特征在哪些区域取值高能辅助解释聚类结果的实际业务含义。figure; plotsomhits(net, Xn); figure; plotsomplanes(net);4.3 用聚类有效性指标量化评估可视化只能定性判断要量化比较不同参数下的聚类效果需要用聚类有效性指标。这里给出轮廓系数的计算方式% evalclusters 要求输入为行样本格式因此需要转置 eva evalclusters(Xn, finalLabel, silhouette); fprintf(Silhouette %.3f\n, eva.CriterionValues);evalclusters是 MATLAB 统计工具箱自带的聚类评估函数第一参数是行样本数据矩阵第二参数是聚类标签第三个参数指定评估方法。轮廓系数的取值范围是[-1, 1]越接近 1 表示簇内紧凑、簇间分离聚类效果越好。实际操作中我会用同一个标准化后的数据集分别跑 SOM 二次聚类和纯 k-means对比两者的轮廓系数。SOM 的优势在高维、非线性数据上才明显如果数据本身簇结构简单k-means 聚类算法的得分通常更高这属于正常现象。4.4 样本量较大时的验证策略样本量在十万甚至百万级别时evalclusters的计算会比较慢。常见做法是先随机抽取一个子集做参数调优确定网格规模和 K 值后再全量训练。抽样子集时注意保持与全量数据相同的分布简单随机抽样即可不要只抽前 N 条。另外不同随机种子下训练出的 SOM 结果会有波动评估时建议固定种子复现或者多次训练取指标均值。5. SOM 聚类的三个实用技巧5.1 用随机种子锁住结果先跑 20 次再选优SOM 的初始权重是随机的train内部默认会在每次训练时重新初始化这导致同一份数据、同一组参数两次训练结果可能差别不小。调参阶段如果不固定随机种子你很难判断效果变化是参数引起的还是随机波动引起的。我的做法是写一个循环固定不同种子跑多次取轮廓系数最高的一次作为最终模型bestSil -Inf; for seed 1:20 rng(seed); net selforgmap([8 8]); net.trainParam.epochs 300; net train(net, Xn); y net(Xn); labels vec2ind(y); W net.IW{1}; neuLabel kmeans(W, K, Replicates, 5); finalLabel neuLabel(labels); eva evalclusters(Xn, finalLabel, silhouette); if eva.CriterionValues bestSil bestSil eva.CriterionValues; bestNet net; bestLabel finalLabel; end end5.2 网格尺寸宁小勿大空神经元比例是硬指标判断网格是否过大除了看 U-matrix还可以量化计算空神经元比例。命中图里圆面积为零的神经元就是空神经元经验阈值是空神经元不超过总数的 10%。超过这个比例优先缩小网格而不是增加训练轮数。反过来如果 U-matrix 显示簇边界横穿浅色区域说明网格太小簇被压缩了适当增大网格并重新训练。5.3 调参失败时先看 U-matrix不要只盯轮廓系数轮廓系数高不代表 SOM 的拓扑保持得好它只反映最终类别标签的分离程度。如果 U-matrix 一片模糊、没有明显深色边界但轮廓系数却很高说明二次聚类把噪声也切成了“簇”这个结果是不可信的。遇到这种情况先回到数据标准化环节检查是否漏了 z-score再看initNeighbor是否过小导致排序阶段没完成。一个有效的小技巧是把plotsomum和plotsomhits两张图并排看U-matrix 的深色边界应该穿过命中图里圆形最小的区域这才说明聚类结果在拓扑上有依据。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。