k-中心点算法(k-medoids)及Matlab代码实现
k-中心点算法(k-medoids)及Matlab代码
1. 提出:
上篇文章给出了 k-means算法的具体思想和代码实现:https://blog.csdn.net/qiu1440528444/article/details/80611942
k-means算法是每次选择簇的均值作为新的中心点,迭代直到簇中心不再变化(趋于稳定)。其缺点是对离群点特别敏感,因为一个很大的极端值对象会扭曲数据分布,使簇均值严重偏离;于是我们考虑新的簇中心不用均值表示而是选择簇内的某个对象,只要使总的代价降低就行。。
2. 优化后的算法:
PAM(围绕中心点的划分),具有代表性的k-medoids算法。
算法思想: 迭代选出簇中位置最中心的对象,试图将N个对象给出k个划分。
具体:
最初随机选择k个对象作为中心点,并代表初始簇,然后根据欧氏距离划分其余所有对象到各个中心点所代表的簇,得到初始簇划分。
该算法反复利用数据D中所有非代表对象来替换当前代表对象,试图找出更好的中心点,以改进聚类质量。 中心点也叫代表对象,其他对象叫非代表对象。
在每次迭代中,所有可能的对象都被分析,每一对替换中的一个对象是中心点,而另一个是非代表对象。如果一个当前的中心点被一个非代表对象所替换,代价函数将计算平方误差值所产生的差别;替换的总代价是所有非中心对象去替换所产生的代价之和。
如果总代价为负值,则实际的平方误差将会减少,则代表对象Oi可被非代表对象Oh替换。
中心点的定义:簇中某点的平均差异性在这一簇中所有点中最小。
3. 算法描述:
输入:
- k:簇的数目;
- N:包含N个对象的数据;
输出:k个簇,使得所有对象与其距离最近的中心点的相异度总和最小。
- 初始化:随机选择N个点中的k个点作为初始中心点;
- 将其余各点根据欧式距离划分到这k个类别中;
- 当损失值减少时:
对于每个中心点o,对于每个非中心点m;
a.)交换o和m,重新计算损失(损失值为,所有点到中心点的距离和);
b.)如果总的损失增加则不进行交换;
另外一种解释:
1. 任选k个对象作为初始簇中心;
2. 划分其余对象给离它最近的中心点所表示的簇;
3. 选择一个未被选择的中心点Oi;
4. 选择一个未被选择的非中心点Oh;
5. 计算Oh替换Oi所产生的总代价并记录在S中;
6. Utill 所有非中心点都被选择过;
7. Utill 所有中心点都被选择过;
8. if 在S中的所有替换所产生的总代价有负值存在,then 找出并用该非中心点替换对应的中心点,形成一个新的k个中心点的集合;
9. Utill 没有再发生簇的重新分配,即所有的S都大于0.
总的来说:与k均值算法一样,初始代表对象任意选取,反复用一个非代表对象替换一个代表对象,试图找出更好的中心点,以改进聚类质量。一个中心点对象被可以产生误差平方和减少的对象替换,再一次迭代中产生的最佳对象集合成为下次迭代中心点。
为判定一个非代表对象Oh是否是当前一个代表对象Oi的好的替换,对每个非中心点对象Oj,有以下四种情况:
第一种情况:Oj当前隶属于中心点对象Oi。如果Oi被Oh所代替作为中心点,且Oj离某个中心点Om最近,i≠m,那么Oj被重新分配给Om。
第二种情况:Oj当前隶属于中心点对象Oi。如果Oi被Oh所代替作为中心点,且Oj离Oh最近,那么Oj被重新分配给Oh。
第三种情况:Oj当前隶属于中心点Om,m≠i。如果Oi被Oh代替作为中心点,而Oj依然离Om最近,那么对象的隶属不发生变化。
第四种情况:Oj当前隶属于中心点Om,m≠i。如果Oi被Oh代替作为一个中心点,且Oj离Oh最近,那么Oi被重新分配给Oh。
每当重新分配发生时,绝对误差E的差会对代价函数有影响。因此,如果一个当前的代表对象被非代表对象所替换时,则代价函数就计算绝对误差值的差。交换的总代价是所有非代表对象所产生的代价之和。如果总代价为负,则实际的绝对误差和会减少,Oi可以被Oh所替换作为新中心点。如果代价为正,则本次迭代无变化。
总代价定义如下:
其中,TCih表示中心点Oi被非中心点Oh替换后产生的总代价。Cjih表示,Oj在Oi被Oh替换后产生的代价。下面将介绍上述四种情况中代价函数的计算公式,其中引用到的符号有:Oi和Om是两个原中心点,Oh将替换Oi作为新的中心点。
代价函数计算图示:
Matlab代码:
k_medoids.m文件
clc;
clear;
%读取数据文件,生成点矩阵
fileID = fopen('E:\MySoftware\matlabWorks\textKMediods\sample.txt'); C=textscan(fileID,'%f %f'); %textscan函数读取数据fclose(fileID); %关闭一个打开的fileID的文件%显示数组结果 %celldisp(C); %将cell类型转换为矩阵类型,这里只假设原数据为二维属性,且是二维的坐标点 CC_init=cat(2,C{1},C{2});%用来保存初始加载的值 CC=CC_init; %cat函数用于连接两个矩阵或数组%获得对象的数量 num=length(C{1}); %显示初始分布图 grid on;%显示表格scatter(C{1},C{2},'filled'); %filled为实心圆,该函数可以把C中所有坐标的点都画出来。%%设置任意k个簇
k=3;
%临时存放k个中心点的数组
C_temp=zeros(k,2);
%判断所设置的k值是否小于对象的数量
if k<num %产生随机的k个整数 randC=randperm(num); randC=randC(1:k); %从原数组中提出这三个点 for i=1:k C_temp(i,:)=CC(randC(1,i),:); end %将原数组中的这三个点清空 for j=1:k CC(randC(1,j),:)=zeros(1,2); end idZero=find(CC(:,1)==0); %删除为零的行 [i1,j1]=find(CC==0); row=unique(i1); CC(row,:)=[]; %分配k个二维数组,用来存放聚类点 %分配行为k的存储单元 cluster=cell(k,1,1); %将剔除的三个点加入到对应的三个存储单元,每个单元的第一行置为0,为了存储相对应的簇中心 for m=1:k cluster{m}=C_temp(m,:); end %计算其他点到这k个点的距离,然后分配这些点,第一次遍历 for i=1:num-k %分别计算到三个点的距离 minValue=1000000;%最小值,要根据实际情况设定该值 minNum=-1;%最小值序号 for j=1:k if minValue>sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2))) minValue=sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2))); minNum=j; end end cluster{minNum}=cat(1,cluster{minNum},CC(i,:)); end %随机选择p点 flag=1; count=0; while flag==1 randC=randperm(num-k); randC=randC(1:1); o_random=CC(randC,:); %找出该随机点所在的簇 recordN=0; for i=1:k for j=1:size(cluster{i},1) cc=cluster{i}(j,:); cc=cc-o_random; if cc==0 recordN=i; break; end end end %将选择的随机点从点集中删除 CC(randC,:)=[]; %计算替换代价 o=cluster{recordN}(1,:); o_rand_sum=0; o_sum=0; for i=1:length(CC) o_rand_sum=o_rand_sum+sqrt((CC(i,1)-o_random(1,1))*(CC(i,1)-o_random(1,1))+(CC(i,2)-o_random(1,2))*(CC(i,2)-o_random(1,2))); o_sum=o_sum+sqrt((CC(i,1)-o(1,1))*(CC(i,1)-o(1,1))+(CC(i,2)-o(1,2))*(CC(i,2)-o(1,2))); end %如果随机选择的点的代价小于原始代表点的代价,则替换该代表点,然后重新聚类 if o_rand_sum<o_sum cluster{recordN}(1,:)=o_random; %将代表点放入对象集 CC=cat(1,CC,o); %对所有对象重新进行聚类 %将cluster除第一行之外的数据全部清空 for i=1:k c=cluster{i}(1,:); cluster{i}=[]; cluster{i}=c; end %重新聚类 for i=1:num-k %分别计算到三个点的距离 minValue=1000000;%最小值,要根据实际情况设定该值 minNum=-1;%最小值序号 for j=1:k if minValue>sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2))) minValue=sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2))); minNum=j; end end cluster{minNum}=cat(1,cluster{minNum},CC(i,:)); end else %将随机点重新放入对象集 CC=cat(1,CC,o_random); %终止循环 flag=0; end count=count+1; end %绘制聚类结果 for i=1:k scatter(cluster{i}(:,1),cluster{i}(:,2),'filled'); hold on grid on;%显示表格end
end
运行结果如下:
当K=3时:
当K=4时:
参考文献及例子:
http://dy.163.com/v2/article/detail/CUSKS65T0511HOMM.html
欢迎扫描提问码交流
CSDN代码下载地址:
https://download.csdn.net/download/qiu1440528444/10486659
k-中心点算法(k-medoids)及Matlab代码实现相关推荐
- 25-混合A星算法Hybrid_Astar路径规划MATLAB代码
资源: Hybrid-Astar(混合A星算法)路径规划MATLAB代码-电子商务文档类资源-CSDN文库 主要内容: 以车辆的运动学模型为节点,以当前点到终点的Astar距离和RS距离两者最大的距离 ...
- 灰狼(GWO)算法(附完整Matlab代码,可直接复制)
尊重他人劳动成果,请勿转载! 有问题可留言或私信,看到了都会回复解答! 其他算法请参考: 1.粒子群(PSO)优化算法(附完整Matlab代码,可直接复制)https://blog.csdn.net/ ...
- 粒子群(PSO)算法(附完整Matlab代码,可直接复制)
在粒子群优化算法中,每个解可用一只鸟(粒子)表示,目标函数就是鸟群所需要寻找的食物源.寻找最优解的过程中,粒子包含两种行为:个体行为和群体行为. 个体行为:粒子根据自身在寻优过程中的最优解更新自己的位 ...
- 图像处理:边缘提取算法(边缘提取算子总结)——Matlab代码实现
边缘提取算子 一阶: Roberts算子.Sobel算子.Prewitt算子.Kirsch算子.Robinson算子 二阶: Laplacian算子.Canny算子.Marr-Hildreth(Lo ...
- Dijkstra算法和Floyd算法详解(MATLAB代码)
一.Dijkstra算法 1.算法简介 Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它应用了贪心算法模式,是目前公认的最好的求解最短路径的方法.算法解决的是有 ...
- 【路径规划-TSP问题】基于粒子群结合蚁群算法求解旅行商问题附matlab代码
1 内容介绍 一种基于粒子群优化的蚁群算法求解TSP问题的方法.该方法在求解TSP问题时,利用粒子群优化的思想,对蚁群算法的参数取值进行优化并选择.在粒子群算法中,将蚁群算法的5个参数(q,α,β,ρ ...
- 【图像分割】基于 K-means 聚类算法实现图像区域分割matlab代码
1 简介 对图像进行颜色区域分割.将图像转换到CIE L*a*b颜色空间,用K均值聚类分析算法对描述颜色的a*和b*通道进行聚类分析;通过提取各个颜色区域独立成为单色的新图像,对图像进行分割处理.实验 ...
- 【图像分割】基于模糊聚类算法FCM实现图像分割matlab代码
1 简介 图像分割是数字图象处理中关键技术之一,是重要的研究领域,也是计算机视觉中的一个经典问题.聚类分析是图像分割领域的重要分支之一,也是数据挖掘中进行数据处理的重要分析工具和方法,且应用广泛.近年 ...
- 蚁群算法小结及算法实例(附Matlab代码)
目录 1.基本蚁群算法 2.基本蚁群算法的流程 3.关键参数说明 3.1 信息素启发式因子 α 3.2 期望启发因子 β 3.3 信息素蒸发系数 ρ 3.4 蚂蚁数目 m 3.5 信息素强度 Q 对算 ...
- a*算法matlab代码_NSGAII多目标优化算法讲解(附MATLAB代码)
小编今天为大家讲解NSGA-II多目标优化算法,提到多目标优化,大家可能第一个就想到NSGA-II算法,今天小编就带领大家解开NSGA-II的神秘面纱. NSGA-II全称是快速非支配排序遗传算法,这 ...
最新文章
- php asort,PHP asort():对数组排序(升序),并保持索引关系
- logrotate 不轮询
- 怎么让div显示一行,其余的隐藏。
- 【C 语言】文件操作 ( 学生管理系统 | 命令行接收数据填充结构体 | 结构体写出到文件中 | 查询文件中的结构体数据 )
- Acwing第 14 场周赛【完结】
- Java进阶:CountDownLatch倒计时
- PHP_Mysql注入防护与绕过
- uni-app使用前的调研和开发心得
- Java防止Xss注入json_每日一题(java篇) 如何防止xss注入
- [bzoj 3594] [Scoi2014]方伯伯的玉米田
- 一文掌握Python集合的语法与应用
- 自定义 Yasnippet 模板
- python生成树状图_python 字典生成树状图
- 7z和winrar命令行压缩方法
- 电视直播(CCTV5)
- PostgreSQL JDBC 驱动程序版本和JDK关系及下载地址
- AUTOSAR MCAL CAN Driver 接口函数
- 【科普】Kubectl基本操作命令
- OpenWrt路由器macvlan单线多拨的方法
- 在Vf中如何将Excel数据导入(用Vf来导)?