二分K均值bi-kmeans

Kmeans的缺点

对K个质心的初始选取比较敏感,如果初始质心选取得不好有可能陷入局部最小值,这个问题可以通过运行多次Kmeans来选取最优结果尽可能避免

二分Kmeans的思路

(1)将数据看成一个簇,对数据进行二分类Kmeans进行初始化

(2)找到最大SSE所在的簇,对该簇进行二分类Kmeans

(3)每次增加一个簇,直到达到所要求的簇数

Matlab代码

function [idx , C , SSE] = binary_kmeans(X , k)
% 二分kmeans算法
% X: 数据矩阵,维度是nxm,有n个数据点,m个特征
% k: 聚类的簇数
% idx: 每个数据点的标签,维度为nx1
% C: 聚类中心,维度为kxm

n = size(X, 1);     %计算数据矩阵有多少个数据点

%%%进行一次2分类kmeans初始化聚类中心和标签
[idx,C]= kmeans(X, 2, 'MaxIter', 500 , 'Replicate',100);        %使用kmeans对最大sse所在类的数据进行二分类

%初始化C有两个中心
%初始化idx有两种label

while size(C, 1) < k        %当簇数小于指定的簇数时,迭代
    
    %将SSE最大的簇使用kmeans进行2分类
    
    sse = zeros(size(C, 1), 1);     %初始化sse数组
    
    for i = 1:size(C, 1)
        sse(i) = sum(sum((X(idx == i, :) - C(i, :)).^2));       %计算每一类的sse
    end
    
    [~, max_idx] = max(sse);        %找到最大的sse所在的类

    if max_idx ~= 1     %将max_idx的标签换到1
        
        C_1 = C(1,:);       %交换最大标签和1标签的中心坐标
        C(1,:) = C(max_idx,:);
        C(max_idx,:) = C_1;
        
        idx(idx==1) = 0;        %交换最大标签和1标签的数据的label
        idx(idx==max_idx) = 1;
        idx(idx==0) = max_idx;
        
    end
    
    X_temp = X(idx == 1, :);      %提取标签为1的数据
   
    [idx_temp,C_temp]= kmeans(X_temp, 2, 'MaxIter', 500 , 'Replicate',100);        %使用kmeans对最大sse所在类的数据进行二分类
    
    C(1,:) = C_temp(1,:);     %更新C,用二分类第一类中心取代原有的中心
    C = [C;C_temp(2,:)];        %在C的最后加上二分类第二类中心
    
    idx(idx == 1) = size(C, 1);       %将进行二分的label置为C的行数(此时label中不存在C的行数的)
    
    idx_temp(idx_temp == 1) = 1;        %用原来的label取代二分类第一类的label
    idx_temp(idx_temp == 2) = size(C,1);      %用C的行数取代二分类第二类的label
    
    idx(idx == size(C, 1)) = idx_temp;      %将进行二分类的原label用新的两类label替代
    
end

for i = 1:size(C, 1)
    sse(i) = sum(sum((X(idx == i, :) - C(i, :)).^2));       %计算每一类的sse
end

SSE = sum(sse);     %计算总的sse

end

通过运行多次二分Kmeans,找到最优的结果

SSE = inf;
idx = zeros(n,1);

for itr = 1:100     %在100次bikmeans中找最优解
    
    [idx_temp,~,SSE_temp] = binary_kmeans(X,k);        %使用bikmeans
    
    if SSE_temp < SSE
        
        SSE = SSE_temp;  
        idx = idx_temp;
        
    end 
end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tizzy477

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值