先定义一个计算欧氏距离的函数:
function dist = dist(x,y)%计算欧氏距离的函数
dist = [x;y];
dist = pdist(dist); % 计算各行向量之间的欧式距离
end
再定义一个处理数据的函数:
% data=xlsread('sonar.xls');
% heart1=data(1,1:60);%创建两个簇心
% heart2=data(97,1:60);
%从这里创建一个函数t
function [heart1,heart2,heart1_lat,heart2_lat,rate]=deal(heart1,heart2,data)
cu1=zeros(208,60);%创建两个簇
cu2=zeros(208,60);
heart1_lat=zeros(1,60);%创建两个向量记录上一组簇心
heart2_lat=zeros(1,60);
m=1;
j=1;
k=1;%定义几个计数器,在循环中使用
true=0;%定义一个变量记录和原始数据归类相同的个数
for m = 1:208 %遍历原始数据
dist1 = dist(heart1,data(m,1:60));%计算每个点与初始簇心的欧氏距离
dist2 = dist(heart2,data(m,1:60));**向量的维数要相等很关键,很容易在这里出错导致bug**
if dist1>dist2%若距离第一个簇心比第二个簇心远
cu2(j,1:60)=data(m,1:60);%把数据归类到第二个簇
j=j+1;
if data(m,61)==2%判断是否和原始数据归类相同
true=true+1;%若相同,计数器+1
end
else%若距离第二个簇心比第一个簇心远
cu1(k,1:60)=data(m,1:60);%把数据归类到第一个簇
k=k+1;
if data(m,61)==1%判断是否和原始数据归类相同
true=true+1;%若相同,计数器+1
end
end
end
rate = true/208;%计算正确率
disp(rate);%打印正确率
heart1_lat=heart1;
heart2_lat=heart2;%记录上一组簇心
heart1=sum(cu1)/(k-1);%簇心的迭代
heart2=sum(cu2)/(j-1);
end
最后是迭代的函数
function [] = update()
rate_arr=[]%记录每次正确率的向量
count_arr=[]%记录迭代次数的向量
i=1;%计数器
data=xlsread('sonar.xls');
[m,n]=size(data);
heart1 = data(randi(m),1:60);
heart2 = data(randi(m),1:60);
[heart1,heart2,heart1_lat,heart2_lat,rate]=deal(heart1,heart2,data);%先调用一次
count_arr(i)=i;%记录迭代的次数
rate_arr(i)=rate;%将每次正确率写入向量
i=i+1;
%dist(heart1,data(m,1:60))
while abs(dist(heart1_lat,heart1))>0.01||(dist(heart2_lat,heart2))>0.01%判断停止迭代的条件,两组簇心的差都小于等于0.01
%heart1_lat = heart1;%更新之前的簇心
%heart2_lat = heart2;
[heart1,heart2,heart1_lat,heart2_lat,rate]=deal(heart1,heart2,data);%调用迭代的函数**调用函数的语法很关键,在这里卡了很久**
rate_arr=[rate_arr,rate];%将每次正确率写入向量
count_arr(i)=i;%记录迭代的次数
i=i+1;
end
x=count_arr;
y=rate_arr;
disp(x);
plot(x,y);
xlabel("count");
ylabel("rate");
end
画出的图表如下:x是迭代次数,y是正确率
最终的簇心1:0.0298100000000000 0.0391370000000000 0.0465860000000000 0.0596330000000000 0.0870720000000000 0.112131000000000 0.130231000000000 0.142735000000000 0.187697000000000 0.230250000000000 0.270971000000000 0.286980000000000 0.328828000000000 0.384763000000000 0.436913000000000 0.525922000000000 0.596668000000000 0.646531000000000 0.704988000000000 0.745164000000000 0.779566000000000 0.791817000000000 0.772622000000000 0.749588000000000 0.710495000000000 0.696587000000000 0.674022000000000 0.612461000000000 0.520294000000000 0.450693000000000 0.383035000000000 0.325591000000000 0.303155000000000 0.283178000000000 0.277422000000000 0.280659000000000 0.284431000000000 0.265589000000000 0.265190000000000 0.264457000000000 0.233336000000000 0.224428000000000 0.204611000000000 0.180895000000000 0.156837000000000 0.122404000000000 0.104799000000000 0.0788900000000000 0.0473500000000000 0.0197200000000000 0.0156660000000000 0.0130780000000000 0.0110860000000000 0.0116270000000000 0.00959400000000000 0.00875700000000000 0.00793000000000000 0.00838400000000000 0.00765900000000000 0.00615900000000000
簇心2:
0.0285657407407407 0.0377879629629630 0.0412824074074074 0.0485768518518518 0.0642120370370370 0.0975694444444444 0.113890740740741 0.127450925925926 0.169026851851852 0.187897222222222 0.203644444444444 0.216185185185185 0.221895370370370 0.214906481481481 0.212135185185185 0.241972222222222 0.248682407407407 0.272491666666667 0.319462962962963 0.394419444444444 0.451184259259259 0.469143518518518 0.530635185185185 0.601419444444445 0.642950000000000 0.702902777777778 0.728203703703704 0.769545370370371 0.754833333333334 0.701515740740741 0.616920370370370 0.544086111111111 0.522835185185185 0.514395370370370 0.499190740740741 0.481318518518519 0.437302777777778 0.408238888888889 0.381919444444445 0.354493518518519 0.341025925925926 0.328168518518519 0.285366666666667 0.244797222222222 0.234635185185185 0.196026851851852 0.138799074074074 0.103029629629630 0.0561685185185185 0.0210759259259259 0.0164416666666667 0.0137370370370370 0.0103601851851852 0.0103055555555556 0.00900925925925926 0.00772592592592593 0.00771851851851852 0.00754629629629630 0.00820277777777778 0.00682962962962963