SOM算法原理

SOM算法是一种将高维数据通过两层神经网络(输入层和竞争层)映射至用户定义的拓扑结构中,一般常用2D矩阵拓扑结构。下图是对SOM的形象展示:


所以算法一般分为以下几步:

第一:用户自定义拓扑结构,并对其中的每个节点的自身向量做随机初始化,向量长度与训练数据的维度相等。

第二:将一条训练数据输入至神经网络,节点间展开竞争,节点的自身向量与训练数据的欧式距离最短者作为获胜节点(winner unit),则该节点在此次迭代过程中拥有此训练数据(每次迭代前都要将上轮的训练数据归属结果清空,最后一轮迭代不清空作为最终结果)

第三:获胜节点以及其周边的节点的自身向量都可依照梯度下降的思想向训练数据调整。调整的幅度与学习率(随迭代次数递减)以及邻域函数(确定在获胜节点周边多大的范围内的节点可以调整自身向量以及调整力度,离获胜节点越远的邻域节点的调整幅度越小,随迭代次数递减,最终只调整获胜节点)有关。

其中,t表示迭代轮数,mi(t)表示拓扑结构中的第i个节点的初始自身向量,x(t)表示一条训练数据,α(t)表示学习率函数,hci(t)表示邻域函数其定义如下:

其中,rc表示获胜节点在拓扑结构中的位置(2D矩阵坐标),ri表示第i个节点在拓扑结构中的 位置,δ(t)表示调整的力度,随迭代次数递减。

第四:第二第三步迭代执行,直到满足迭代次数或收敛。


代码实现

mysom.m

由训练集,初始map,迭代次数,学习率生成新的map

function new_map = mysom(data,map,iter,learn_rate_init)
%mysom(data,map,time)
%data:训练集
%map:拓扑关系(map为结构体,含有字段units、submap、MQE;units为结构体数组,由结构体unit组成;
%unit结构体含有字段vector、qe、mqe、dataindex)
%iter:迭代次数
%learn_rate_init:学习率初始值
%new_map:数据分类拓扑结果
[data_row,~]=size(data);
[map_row,map_col]=size(map.units);%获取map的拓扑结构(2D矩形)
%获得邻域半径
if map_row>map_colneighbor_redius_init=map_col/2;
elseneighbor_redius_init=map_row/2;
end
%设置学习率、邻域半径更新参数
learn_para=iter/3;%exp(-3)=0.0498已经足够小了
neighbor_para=learn_para/log(neighbor_redius_init);
%迭代开始
for i=1:iterlearn_rate=learn_rate_init*exp(-i/learn_para);%学习率更新neighbor_redius=neighbor_redius_init*exp(-i/neighbor_para);%影响半径更新for j=1:data_row%1计算获胜神经元[win_row,win_col]=som_compare(map.units,data(j,:));%2添加训练数据进入获胜神经元map.units(win_row,win_col).dataindex=[map.units(win_row,win_col).dataindex,j];%3更新邻域内神经元向量map=som_adaption(map,win_row,win_col,data(j,:),learn_rate,neighbor_redius);end%若非最后一轮,下次迭代会将训练数据重新分配,所以将此轮分类结果清空if i~=iterfor ii=1:map_rowfor jj=1:map_colmap.units(ii,jj).dataindex=[];endendend
end
new_map=map;
end

som_compare.m

根据原有拓扑结构和某条训练数据,得出获胜节点的坐标。

function [ win_row,win_col ] = som_compare( units,data )
%som_compare( units,data )
%data:一条训练数据 1*n向量
%units:2维结构体数组描述map内的拓扑结构
%win_row:获胜神经元在拓扑结构中的行号
%win_col:获胜神经元在拓扑结构中的列号[unit_row,unit_col]=size(units);
dist=zeros(unit_row,unit_col);%初始化距离矩阵
for i=1:unit_rowfor j=1:unit_col%计算欧式距离dist(i,j)=sqrt(sum(((units(i,j).vector)-data).*((units(i,j).vector)-data)));end
end
%寻找最小距离的坐标
[min1,minrow]=min(dist);
[~,win_col]=min(min1);
win_row=minrow(win_col);
end

som_adaption.m

根据获胜节点坐标、原有map、学习率和邻域半径对节点进行调整。

function adp_map = som_adaption( old_map,row,col,data,learn_rate,neighbor_redius )
%som_adaption( old_map,row,col,learn_rate,neighbor_redius )
%old_map:原有拓扑结构
%row:获胜神经元在原有拓扑结构中的行号
%col:获胜神经元在原有拓扑结构中的列号
%data:刚分类到获胜神经元的训练集向量
%learn_rate:本次迭代学习率
%neighbor_redius:本次迭代邻域半径
%adp_map:更新神经元向量后的新拓扑结构[unit_row,unit_col]=size(old_map.units);
for i=1:unit_rowfor j=1:unit_colif i>=row-floor(neighbor_redius)&&i<=row+floor(neighbor_redius)...&&j>=col-floor(neighbor_redius)&&j<=col+floor(neighbor_redius)distance=(row-i)^2+(col-j)^2;old_map.units(i,j).vector=old_map.units(i,j).vector+learn_rate...*exp(-distance/(2*neighbor_redius^2))*(data-old_map.units(i,j).vector);endend
end
adp_map=old_map;
end

createmap.m

指定拓扑结构维度和向量长度,随机初始化一个map。

function map = createmap( unit_row,unit_col,lenOfvec )
%createmap( unit_row,unit_col,lenOfvec )
%unit_row:指定拓扑结构的行数
%unit_col:指定拓扑结构的列数
%lenOfvec:向量长度
%map:生成的map
map=struct('units',[],'submap',[],'MQE',0);
for i=1:unit_rowfor j=1:unit_colunits(i,j)=struct('vector',rand(1,lenOfvec),'qe',0,'mqe',0,'dataindex',[]);end
end
map.units=units;
end

在Iris数据集上的实验结果

当初始化拓扑结构为3*3时,初始学习率设为0.6,迭代次数设为20时,对150条数据的聚类拓扑结果如下图:

当初始化拓扑结构为4*4时,初始学习率、迭代次数不变,结果如下:


结论

实现了对150条数据的拓扑展示:setosa在拓扑结构的左上角,且50条数据全部分配到一个节点中;versicolor在拓扑结构的右上行和左下列;virginica在拓扑结构的右下区域。可以从上图中看出versicolor与virginica区域有所交叉,但随着拓扑结构的增大,交叉数据数量减少。在3*3中共交叉22条数据,在4*4中交叉5条数据。

以上是个人观察实验结果得出的一些结论,当然代码还存在可优化可修改的地方,比如学习率的初始值及递减公式和邻域半径的衰减公式都可根据实际情况而定义。总体上som算法的对于发现数据内固有的拓扑结构有很好的效果!

自组织神经网络SOM算法对Iris数据集进行聚类的matlab实现相关推荐

  1. 几种聚类算法在IRIS数据集上的应用(python)

    分解聚类.C均值聚类及其改进.ISODATA应用在IRIS数据集的表现 IRIS数据集 分解聚类 C均值聚类 ISODATA K均值聚类 这个其实是之前的一次课程作业,要求是对鸢尾花数据集IRIS做聚 ...

  2. KNN算法预测iris数据集

    KNN算法预测iris数据集 1.数据集介绍 鸢尾花灰Iris数据集中有150个样本,每个样本有4个特征,1个标签.其中,鸢尾花种类可取0.1.2,分别代表山鸢尾setosa.变色鸢尾versicol ...

  3. 自组织神经网络SOM——MATLAB

    Kohonen网络的拓扑结构 下图是1维和2维的两个SOM网络示意图. 网络上层为输出结点(假设为m个),按二维形式排成一个结点矩阵. 输入结点处于下方,若输入向量由n个元素,则输入端共有n个结点. ...

  4. 自组织神经网络SOM原理——结合例子MATLAB实现

    本文主要内容为SOM神经网络原理的介绍,并结合实例给出相应的MATLAB代码实现,方便初学者接触学习,本人才疏学浅,如有纰漏,还望各路大神积极指点. 一.SOM神经网络介绍 自组织映射神经网络, 即S ...

  5. Python实现knn分类算法(Iris 数据集)

    1.KNN分类算法 KNN分类算法(K-Nearest-Neighbors Classification),又叫K近邻算法,是一个概念极其简单,而分类效果又很优秀的分类算法. 他的核心思想就是,要确定 ...

  6. matlab iris kmeans,K-means算法用于Iris数据集

    首先是K-menas算法函数,这里使用3维形式,尽管Iris数据集有4维,但是考虑到4维数据无法绘制图像,所以在这里选择三维. function [ resX,resY,resZ,recordd] = ...

  7. Python 3实现k-邻近算法以及 iris 数据集分类应用

    前言 这个周基本在琢磨这个算法以及自己利用Python3 实现自主编程实现该算法.持续时间比较长,主要是Pyhton可能还不是很熟练,走了很多路,基本是一边写一边学.不过,总算是基本搞出来了.不多说, ...

  8. 机器学习与深度学习——通过knn算法分类鸢尾花数据集iris求出错误率并进行可视化

    什么是knn算法? KNN算法是一种基于实例的机器学习算法,其全称为K-最近邻算法(K-Nearest Neighbors Algorithm).它是一种简单但非常有效的分类和回归算法. 该算法的基本 ...

  9. 神经网络是算法还是模型,神经元网络算法的思想

    神经网络算法原理 4.2.1概述人工神经网络的研究与计算机的研究几乎是同步发展的. 1943年心理学家McCulloch和数学家Pitts合作提出了形式神经元的数学模型,20世纪50年代末,Rosen ...

最新文章

  1. 速冻果蔬青麦源品牌-农业大健康·李喜贵:谋定功能性技术
  2. linux多线程信号总结
  3. webpack打包过程如何调试?
  4. dotnet 将C#编译为wasm让前端html使用
  5. ITPro Magazine2006年第6期发布
  6. mysql3.5 所有表_mysql学习笔记3.5
  7. 【南邮操作系统实验】页面置换算法(FIFO、LRU、OPT) Python 版
  8. 基于tutk方案的p2p源码_基于JAVA的局域网文件共享平台P2P实训项目源码(毕业设计 课程设计)...
  9. java 汉字乱码_Java中文乱码问题
  10. Android友盟分享(微信简单集成)
  11. 收据模板_使用智能收据简化支出报告
  12. Java支付宝订单查询
  13. layui table动态选中_NeurIPS 2020 | 伯克利新工作: 基于动态关系推理的多智能体轨迹预测问题...
  14. 自学 Photoshop 2022 Mac版-笔记1
  15. 前端vue几款模板介绍
  16. 3个方法恢复彻底删除的苹果手机视频!
  17. 为什么 SD-WAN 很重要?
  18. mysql查询补齐12个月_MySQL查询12个月数据,无数据补0
  19. 7代cpu能装虚拟xp系统吗_Intel 10代PC/笔记本安装Win7踩坑记 amp; 驱动分享
  20. 这15个特性,身为.NET开发者的你全部都了解吗?

热门文章

  1. 外语学习应试教育时如何高效的背单词?
  2. 扬子晚报:杨百万 PK 巴菲特
  3. 一线互联网架构师筑基必备技能之Java篇,一招彻底弄懂!
  4. L2-021 点赞狂魔(Python3)
  5. 传输层——计算机网络
  6. hnoi2014米特运输
  7. 关于月亮双鱼,早已超越弱与强。
  8. 美团面试全流程详解(一面 + 二面)
  9. 关键帧与地图点(二):关键帧
  10. 女生无法拒绝的表白拼图