isodata自适应聚类算法——2017年F题(matlab)(待完成)
[Type Sheet Format]=xlsfinfo('现状OD数据及其他数据.xls'); OD=xlsread('现状OD数据及其他数据.xls',Sheet{1}); center_area=xlsread('现状OD数据及其他数据.xls',Sheet{2}); x_pos=center_area(:,4); %数据第四列为x坐标(米) y_pos=center_area(:,5); %数据第五列为y坐标(米) x=[x_pos,y_pos]; [node_num,feature_num]=size(x); %z1=x1; clusterNumber=10; %初始设置聚类中心个数为3个=>10 leastNumber=5; %每个聚类中心最少有一个样本 stdvar=1; %初始标准差设置为1 minmumDistance=10000; %根据具体问题设置=> 10000,后续修改 maximumCluster=1; %每次迭代中聚类中心最多合一对 opCount=5; %设置迭代次数阈值,达到阈值停止算法,后续修改 number=feature_num; % X特征数 n=node_num; % x中样本数
%ISODATA算法的Matlab程序 Design by shuijian (shuijian1122@gmail.com) %相关函数说明见函数定义 %x=样本特征空间 %clusterNumber=预期聚类中心数目 %leastNumber=最小聚类中的样本数,少于此数将不能作为独立的样本 %stdvar=样本距离分布的标准差,随着迭代中结果逐渐优化,标准差应该越来越小才合理。 %minmumDistance=两聚类中心的最小距离,小于此数将两个聚类合并 %maximumCluster=一次运算中可以合并的聚类中心的最大对数 %opCount=迭代运算次数 %n=,x中元素个数 %number=x中元素特征数目 %s=聚类结果 %clusterCenter=聚类中心 %clusterCount = 聚类中心元素数目 function [s,clusterCenter,clusterCount] = isodata1(x,n,number,clusterNumber,leastNumber,stdvar,minmumDistance,maximumCluster,opCount) K = clusterNumber; % K=10; 预期聚类中心数目 qn = leastNumber; % qn=5; 每个聚类中至少有一个样本;否则不构成一个聚类 qs = stdvar; % qs=1; 与对应聚类中最大标准差分量maxQs(i)对比;如果maxQs(i)>qs,则进行分裂处理 qc = minmumDistance; % qc=10000; 小于这个最小距离即进行聚类中心的合并 L = maximumCluster; % L=1; 一次运算中可以合并的最大对数 I = opCount; % I=20; 统计iteration迭代次数 num = number; % number=114; n=2; factor = 0.5; %分裂计算时标准差的乘积因子 %z = [x(2,:);x(floor(n/3),:);x(n,:)]; %初始聚类中心,随机选择,z=聚类中心 z = x(2,:); %初始给定聚类中心,只有一个x2 nc = 1; %初始聚类数目 opTimes = 1; %迭代运算次数计数器 while(opTimes <= I) %加%查看一次循环结果:控制迭代次数来结束聚类 count = zeros(1,nc); %聚类元素数目,[1];[5,5;[3,5,2] disTocenter = zeros(n,nc); %创建数组,储存全部样本对各个聚类中心的距离 [n*1];[2*1];[3*1] ss = zeros(nc,n); %所有样本分类 [1*n];[1*n];[1*n] %依据欧氏距离聚类 for m = 1:n %n为总样本个数 for p = 1:nc disTocenter(m,p) = distance(x(m,:),z(p,:),num); %计算各个元素距离各聚类中心之间的距离(第一列为各元素z1的距离,第二列为各元素与z2的距离) end [minValue,index] = min(disTocenter(m,:)); %依据距离归类 count(index) = count(index) + 1; %累计每个类的元素个数 ss(index,m) = m; %存储每个类的元素,ss每行为一个类 end %修正聚类中心,计算元素到中心的平均距离 for i = 1:nc [aveD(i),z(i,:)] = avTocenter(x(find(ss(i,:)),:),count(i),num); end %计算全部模式样本对应聚类中心的总的平均距离。 aveAllD = allAvDis(aveD,count); bool = step_judge(opTimes,nc,I,K); %bool = step_judge(opTimes,nc,I,L); %判断是进行分裂还是合并运算 nct = nc; if (bool == 1) %分裂计算(正确) for i = 1:nc stdcluster(i,:) = clusterStd(x(find(ss(i,:)),:),z(i,:),count(i),num); %计算每个聚类中样本距离的标准差 向量 [maxQs(i),ind] = max(stdcluster(i,:)); %求每聚类中标准差最大分量 if(maxQs(i) > qs && (((aveD(i) > aveAllD) && count(i) > 2 * (qn+1)) || nc <= K/2)) %满足条件,分裂聚类中心 lqs = z(i,ind) + factor * maxQs(i); %% 新的聚类中心与旧的聚类中心对比;只有标准差分量最大的特征的值变化; hqs = z(i,ind) - factor * maxQs(i); temp=[z;z(i,:)]; temp(nc+1,ind) = lqs; temp(i,ind) = hqs; z = temp; % z1,z2是新的聚类中心 nct = nct + 1; % 聚类中心数目 end end nc = nct; elseif (bool == 0) %合并 centerD = centerDistance(z,nc,num); %两个聚类中心的距离 Zij = centerD < qc; %查找小于设定最小中心距离的中心 [indrow,indcol] = find(Zij); %查找两个中心点 %indrowcol = [indrow indcol]; for icount = 1:ceil(numel(indrow)/2) %对称矩阵,只计算一半即可,numel返回矩阵元素总个数;ceil向上取整 if(indrow(icount) == indcol(icount)) %去掉自身距离(为0) continue; % 跳出一次循环 else newCenter = count(indrow(icount))*z(indrow(icount),:) + count(indcol(icount))*z(indcol(icount),:); newCenter = newCenter ./(count(indrow(icount))+count(indcol(icount))); %计算合并后的新的中心 for zcount = 1:nc centerTemp(zcount,:) = z(zcount,:); %缓存聚类中心 end z = zeros(nc-1,num); for zcount = 1:nc-1 if(zcount == indrow(icount) || zcount == indcol(icount)) z(zcount,:) = newCenter; else z(zcount,:) = centerTemp(zcount,:); end end nc = nc - 1; %合并,减少聚类中心数目 end end else qc = 0; end opTimes = opTimes + 1; s = ss; clusterCenter = z; clusterCount = count; end
% 假设只有三个聚类中心,可画图如下(待修改)
function [fig1,fig2] = DrawISODATA(s,clusterCenter,x) % s1~sp:p = length(clusterCount); s1 = find(s(1,:)); s2 = find(s(2,:)); s3 = find(s(3,:)); fig1 = figure; x_loc = x(1:10,:); plot(x_loc(:,1),x_loc(:,2),'kx','MarkerSize',8,'LineWidth',2); square = 10; %方形区域的边长 axis([0,square,0,square]); set(gcf, 'Color', 'w'); %白色 fig2 =figure; s1_loc = x(s1,:); %节点坐标 s2_loc = x(s2,:); s3_loc = x(s3,:); cc_loc = clusterCenter(1:3,:); plot(s1_loc(:,1),s1_loc(:,2),'mx','MarkerSize',8,'LineWidth',2); hold on; plot(s2_loc(:,1),s2_loc(:,2),'rx','MarkerSize',8,'LineWidth',2); hold on; plot(s3_loc(:,1),s3_loc(:,2),'bx','MarkerSize',8,'LineWidth',2); hold on; plot(cc_loc(:,1),cc_loc(:,2),'ko','MarkerSize',8,'LineWidth',2); square = 10; %方形区域的边长 axis([0,square,0,square]); set(gcf, 'Color', 'w'); %白色
参考资料:
1.代码参考:https://www.cnblogs.com/huadongw/p/4101422.html