zoukankan      html  css  js  c++  java
  • 半监督模糊聚类算法FCM,SFCM,SSFCM理论和代码

    参考学习:https://blog.csdn.net/weixin_42663919/article/details/89525967#commentBox
    FCM

    function [center, U, obj_fcn] = FCMClust(data, cluster_n)
    data_n = size(data, 1); % 求出data的第一维(rows)数,即样本个数 [center, U, obj_fcn]
    = FCMClust(data, cluster_n)
    in_n = size(data, 2);   % 求出data的第二维(columns)数,即特征值长度
    % 默认操作参数
    options = [2; % 隶属度矩阵U的指数
        1000;                % 最大迭代次数
        1e-5;               % 隶属度最小变化量,迭代终止条件
        1];                 % 每次迭代是否输出信息标志
      
    %将options 中的分量分别赋值给四个变量;
    expo = options(1);          % 隶属度矩阵U的指数
    max_iter = options(2);  % 最大迭代次数
    min_impro = options(3);  % 隶属度最小变化量,迭代终止条件
    display = options(4);  % 每次迭代是否输出信息标志
     
    obj_fcn = zeros(max_iter, 1); % 初始化输出参数obj_fcn
     
    U = initfcm(cluster_n, data_n);     % 初始化模糊分配矩阵,使U满足列上相加为1,cluster_n=2,用户填上去的种类数c=cluster_n
    % Main loop  主要循环
    for i = 1:max_iter,
        %在第k步循环中改变聚类中心ceneter,和分配函数U的隶属度值;
        [U, center, obj_fcn(i)] = stepfcm(data, U, cluster_n, expo);
        if display,
           fprintf('FCM:Iteration count = %d, obj. fcn = %f
    ', i, obj_fcn(i));
        end
     % 终止条件判别
        if i>1
          if abs(obj_fcn(i) - obj_fcn(i-1)) < min_impro
                break;
          end
        end
    end
     
    iter_n = i; % 实际迭代次数
    %obj_fcn(iter_n+1:max_iter) = [];
    end
    
     
    % 子函数
    function U = initfcm(cluster_n, data_n)
    % 初始化fcm的隶属度函数矩阵
    % 输入:
    %   cluster_n   ---- 聚类中心个数
    %   data_n      ---- 样本点数
    % 输出:
    %   U           ---- 初始化的隶属度矩阵
    U = rand(cluster_n, data_n);
    col_sum = sum(U);
    U = U./col_sum(ones(cluster_n, 1), :);%归一化
    end
     
     
    % 子函数
    function [U_new, center, obj_fcn] = stepfcm(data, U, cluster_n, expo)
    % 模糊C均值聚类时迭代的一步
    % 输入:
    %   data        ---- nxm矩阵,表示n个样本,每个样本具有m的维特征值
    %   U           ---- 隶属度矩阵
    %   cluster_n   ---- 标量,表示聚合中心数目,即类别数
    %   expo        ---- 隶属度矩阵U的指数                     
    % 输出:
    %   U_new       ---- 迭代计算出的新的隶属度矩阵
    %   center      ---- 迭代计算出的新的聚类中心
    %   obj_fcn     ---- 目标函数值
    mf = U.^expo;       % 隶属度矩阵进行指数运算结果
    center = mf*data./((ones(size(data, 2), 1)*sum(mf'))'); % 新聚类中心(5.4)式
    dist = distfcm(center, data);       % 计算距离矩阵
    obj_fcn = sum(sum((dist.^2).*mf));  % 计算目标函数值 (5.1)式
    tmp = dist.^(-2/(expo-1));    
    U_new = tmp./(ones(cluster_n, 1)*sum(tmp));  % 计算新的隶属度矩阵 (5.3)式
     
    end
     
     
    % 子函数
    function out = distfcm(center, data)
    % 计算样本点距离聚类中心的距离
    % 输入:
    %   center     ---- 聚类中心
    %   data       ---- 样本点
    % 输出:
    %   out        ---- 距离
    out = zeros(size(center, 1), size(data, 1));
      for k = 1:size(center, 1), % 对每一个聚类中心
        % 每一次循环求得所有样本点到一个聚类中心的距离
        out(k, :) = sqrt(sum(((data-ones(size(data,1),1)*center(k,:)).^2)',1));
      end
    end
    

    SFCM

    function [center, U, obj_fcn] = SFCMClust(data, cluster_n,data_label)%data_label是30*14维,包括标签,data是30*13维,不包括标签
    data_n = size(data, 1); % 求出data的第一维(rows)数,即样本个数
    in_n = size(data, 2);   % 求出data的第二维(columns)数,即特征值长度
    % 默认操作参数
    options = [2; % 隶属度矩阵U的指数
       1000;                % 最大迭代次数
       1e-5;               % 隶属度最小变化量,迭代终止条件
       1];                 % 每次迭代是否输出信息标志
    
    %将options 中的分量分别赋值给四个变量;
    expo = options(1);          % 隶属度矩阵U的指数
    max_iter = options(2);  % 最大迭代次数
    min_impro = options(3);  % 隶属度最小变化量,迭代终止条件
    display = options(4);  % 每次迭代是否输出信息标志
    
    obj_fcn = zeros(max_iter, 1); % 初始化输出参数obj_fcn
    %初始化center,F
    [center0,F] = initcenter(data_label,data,cluster_n);
    %[center_useless,F_fcm,obj_fcn_useless] = fcm(data_label0,cluster_n,options); 
    %F=[F_fcm,F(:,31:178)];
    % 初始化模糊分配矩阵,使U满足列上相加为1,cluster_n=2,用户填上去的种类数c=cluster_n
    a=5;%5比6好
    U = initfcm(cluster_n, data,center0,F,a,expo); 
    % Main loop  主要循环
    for i = 1:max_iter,
       if i==1
           dist = distfcm(center0, data); 
           mf = U.^expo; 
           obj_fcn(1)=sum(sum((dist.^2).*mf))+a*sum(sum((dist.^2).*((U-F).^expo)));
       %在第k步循环中改变聚类中心ceneter,和分配函数U的隶属度值;
       else
           [U, center, obj_fcn(i)] = stepfcm(data, U, cluster_n, expo,a,F);
       end
       if display,
          fprintf('SFCM:Iteration count = %d, obj. fcn = %f
    ', i, obj_fcn(i));
       end
    % 终止条件判别
       if i>1
         if abs(obj_fcn(i) - obj_fcn(i-1)) < min_impro
               break;
         end
       end
    end
    
    iter_n = i; % 实际迭代次数
    %obj_fcn(iter_n+1:max_iter) = [];
    end
    
    
    function [center,F] = initcenter(data_label,data,cluster_n)%默认为分3类
    center=zeros(cluster_n,size(data, 2));%可能要改
    F=zeros(cluster_n,size(data, 1));%可能要改
    for k=1:cluster_n
     for i=1:size(data_label,1)%center第一行,第一类
       if data_label(i,1)==k
           F(k,i)=1;
           for j=2:size(data_label,2)-1
              center(k,j)=(data_label(i,j)+center(k,j))/i;
           end
       end
     end
    end
    
    % for i=1:size(data_label,1)%center第2行,第2类
    %     if data_label(i,1)==2
    %         F(2,i)=1;
    %         for j=2:size(data_label,2)-1
    %            center(2,j)=(data_label(i,j)+center(2,j))/i;
    %         end
    %     end
    % end
    %    
    % for i=1:size(data_label,1)%center第3行,第3类
    %     if data_label(i,1)==3
    %         F(3,i)=1;
    %         for j=2:size(data_label,2)-1
    %            center(3,j)=(data_label(i,j)+center(3,j))/i;
    %         end
    %     end
    % end
      
    end
    
    
    % 子函数
    function U = initfcm(cluster_n,data,center0,F,a,expo)%a=6
    % 初始化fcm的隶属度函数矩阵
    % 输入:
    %   cluster_n   ---- 聚类中心个数
    %   data_n      ---- 样本点数
    % 输出:
    %   U           ---- 初始化的隶属度矩阵
    % U = rand(cluster_n, data_n);
    % col_sum = sum(U);                      
    % U = U./col_sum(ones(cluster_n, 1), :);%归一化
    dist = distfcm(center0, data); 
    tmp = dist.^(-2/(expo-1)); 
    %U= tmp./(ones(cluster_n, 1)*sum(tmp));
    U_fcm= tmp./(ones(cluster_n, 1)*sum(tmp));
    U_3 =(a/(1+a))* U_fcm.*(ones(cluster_n,1)*sum(F));
    U=U_fcm+(a/(1+a))*F-U_3;
    end
    
    
    % 子函数
    function [U_new, center, obj_fcn] = stepfcm(data,U,cluster_n, expo,a,F)
    % 模糊C均值聚类时迭代的一步
    % 输入:
    %   data        ---- nxm矩阵,表示n个样本,每个样本具有m的维特征值
    %   U           ---- 隶属度矩阵
    %   cluster_n   ---- 标量,表示聚合中心数目,即类别数
    %   expo        ---- 隶属度矩阵U的指数                     
    % 输出:
    %   U_new       ---- 迭代计算出的新的隶属度矩阵
    %   center      ---- 迭代计算出的新的聚类中心
    %   obj_fcn     ---- 目标函数值
    mf = U.^expo;       % 隶属度矩阵进行指数运算结果
    center = mf*data./((ones(size(data, 2), 1)*sum(mf'))'); % 新聚类中心(7)式
         % 计算距离矩阵
    dist = distfcm(center, data);
    tmp = dist.^(-2/(expo-1));    
    U_fcm= tmp./(ones(cluster_n, 1)*sum(tmp));
    U_3 =(a/(1+a))* U_fcm.*((ones(cluster_n,1)*sum(F)));
    U_new=U_fcm+(a/(1+a))*F-U_3;
    obj_fcn =sum(sum((dist.^2).*mf))+a*sum(sum((dist.^2).*((U-F).^expo)));  % 计算目标函数值 (4)式
    
    end
    
    
    % 子函数
    function out = distfcm(center, data)
    % 计算样本点距离聚类中心的距离
    % 输入:
    %   center     ---- 聚类中心
    %   data       ---- 样本点
    % 输出:
    %   out        ---- 距离
    out = zeros(size(center, 1), size(data, 1));
     for k = 1:size(center, 1), % 对每一个聚类中心
       % 每一次循环求得所有样本点到一个聚类中心的距离
       out(k, :) = sqrt(sum(((data-ones(size(data,1),1)*center(k,:)).^2)',1));
     end
    end`
    
    

    SSFCM

    
    function [center, U] = SSFCMClust(data, cluster_n,data_label)%data_label是30*14维,包括标签,data_label0是30*13维,不包括标签
    data_n = size(data, 1); % 求出data的第一维(rows)数,即样本个数
    in_n = size(data, 2);   % 求出data的第二维(columns)数,即特征值长度
    % 默认操作参数
    options = [2; % 隶属度矩阵U的指数
       1000;                % 最大迭代次数
       1e-5;               % 隶属度最小变化量,迭代终止条件
       1];                 % 每次迭代是否输出信息标志
    
    %将options 中的分量分别赋值给四个变量;
    expo = options(1);          % 隶属度矩阵U的指数
    max_iter = options(2);  % 最大迭代次数
    min_impro = options(3);  % 隶属度最小变化量,迭代终止条件
    display = options(4);  % 每次迭代是否输出信息标志
    
    center_count = zeros(max_iter, 1); % 初始化输出参数obj_fcn
    %初始化center,F
    [center0,F] = initcenter(data_label,data,cluster_n);
    % 初始化模糊分配矩阵,使U满足列上相加为1,cluster_n=2,用户填上去的种类数c=cluster_n
    a=5;%5比6好
    U = initfcm(cluster_n, data,center0,F,a,expo); %首个U,center0不用于判断
    label_number=size(data_label,1);
    label_number
    % Main loop  主要循环
    for i = 1:max_iter,
           [U, center] = stepfcm(data, U, cluster_n, expo,a,F,label_number);
           center_count(i)=norm(center);%求模norm
       if display,
          fprintf('SSFCM:Iteration count = %d
    ', i);
       end
    % 终止条件判别
       if i>1
         if abs(center_count(i) - center_count(i-1)) < min_impro
               break;
         end
       end
    end
    
    iter_n = i; % 实际迭代次数
    %obj_fcn(iter_n+1:max_iter) = [];
    end
    
    
    function [center,F] = initcenter(data_label,data,cluster_n)%默认为分3类
    center=zeros(cluster_n,size(data, 2));%可能要改
    F=zeros(cluster_n,size(data, 1));%可能要改
    for k=1:cluster_n
     for i=1:size(data_label,1)%center第一行,第一类
       if data_label(i,1)==k
           F(k,i)=1;
           for j=2:size(data_label,2)-1
              center(k,j)=(data_label(i,j)+center(k,j))/i;
           end
       end
     end
    end
      
    end
    
    
    % 子函数
    function U = initfcm(cluster_n,data,center0,F,a,expo)%a=6
    % 初始化fcm的隶属度函数矩阵
    % 输入:
    %   cluster_n   ---- 聚类中心个数
    %   data_n      ---- 样本点数
    % 输出:
    %   U           ---- 初始化的隶属度矩阵
    % U = rand(cluster_n, data_n);
    % col_sum = sum(U);                      
    % U = U./col_sum(ones(cluster_n, 1), :);%归一化
    dist = distfcm(center0, data); 
    tmp = dist.^(-2/(expo-1)); 
    %U= tmp./(ones(cluster_n, 1)*sum(tmp));
    U_fcm= tmp./(ones(cluster_n, 1)*sum(tmp));
    U_3 =(a/(1+a))* U_fcm.*(ones(cluster_n,1)*sum(F));
    U=U_fcm+(a/(1+a))*F-U_3;
    end
    
    
    % 子函数
    function [U_new, center] = stepfcm(data,U,cluster_n, expo,a,F,label_number)
    % 模糊C均值聚类时迭代的一步
    % 输入:
    %   data        ---- nxm矩阵,表示n个样本,每个样本具有m的维特征值
    %   U           ---- 隶属度矩阵
    %   cluster_n   ---- 标量,表示聚合中心数目,即类别数
    %   expo        ---- 隶属度矩阵U的指数                     
    % 输出:
    %   U_new       ---- 迭代计算出的新的隶属度矩阵
    %   center      ---- 迭代计算出的新的聚类中心
    %   obj_fcn     ---- 目标函数值
    mf = U.^expo; % 隶属度矩阵进行指数运算结果
    %计算center改变U
    mf_ss=[mf(:,1:label_number)*a^expo,mf(:,(label_number+1):size(data, 1))];%使U前30列乘上a
    center = mf_ss*data./((ones(size(data, 2), 1)*sum(mf_ss'))'); % 新聚类中心(7)式
         % 计算距离矩阵
    dist = distfcm(center, data);
    tmp = dist.^(-2/(expo-1));    
    U_fcm= tmp./(ones(cluster_n, 1)*sum(tmp));
    U_3 =(a/(1+a))* U_fcm.*((ones(cluster_n,1)*sum(F)));
    U_new=U_fcm+(a/(1+a))*F-U_3;
    
    end
    
    
    % 子函数
    function out = distfcm(center, data)
    % 计算样本点距离聚类中心的距离
    % 输入:
    %   center     ---- 聚类中心
    %   data       ---- 样本点
    % 输出:
    %   out        ---- 距离
    out = zeros(size(center, 1), size(data, 1));
     for k = 1:size(center, 1), % 对每一个聚类中心
       % 每一次循环求得所有样本点到一个聚类中心的距离
       out(k, :) = sqrt(sum(((data-ones(size(data,1),1)*center(k,:)).^2)',1));
     end
    end
    
    

    测试代码

    
    function []=test(cluster_n,label_number,method)
    %function [center, U, obj_fcn] = SFCMClust(data, cluster_n,data_label)%data_label是30*14维,包括标签
    [data1,data2,data3,data4,data5,data6,data7,data8,data9,data10,data11,data12,data13,data14]=textread('.avila9.txt','%f%f%f%f%f%f%f%f%f%f%f%f%f%f','delimiter', ',');
    data=[data2,data3,data4,data5,data6,data7,data8,data9,data10,data11,data12,data13,data14];
    data_label=[data1(1:label_number),data(1:label_number,:)];
    %[center, U] = SSFCMClust2(data,3,data_label);
    tic
    check=ones(1,size(data,1));
    count_error=0;
    switch method
      case 'fcm'
          [center, U, obj_fcn] = FCMClust(data, cluster_n);
      case 'sfcm'
         [center, U, obj_fcn] = SFCMClust(data,cluster_n,data_label);
      case 'ssfcm'
          [center, U] = SSFCMClust(data,cluster_n,data_label);
      case 'kmeans'
          Idx=kmeans(data,cluster_n);
          for j=1:size(Idx,1)
            if data1(j,1)~=Idx(j,1);%若类别分不对
             check(1,j)=0;
             %disp(['error',num2str(Idx(j,1))]);
             %disp(['origin',num2str(data1(j,1))]);%disp(data1(index1(i)));
             %disp(j);
             count_error=count_error+1;
            end
         end
          
    end
    
    %[center,U,obj_fcn] = fcm(data, cluster_n);
    if (~strcmp(method,'kmeans'))%method~='kmeans'
    maxU = max(U);
    for p=1:cluster_n
     index = find(U(p,:) == maxU);%位置对应 
      for j=1:size(index,2)%有几个属于l类
         if data1(index(j),1)~=p
             check(1,index(j))=0;
             %disp(['error',num2str(p)]);
             %disp(['origin',num2str(data1(index(j)))]);%disp(data1(index1(i)));
             %disp(index(j));
             count_error=count_error+1;
         end
      end
    end
    end
    toc
    disp(['运行时间: ',num2str(toc)]);
    disp(['error number',num2str(count_error)]);
    disp(['error rate',num2str(count_error/size(data,1)*100),'%']);
    disp(['accuracy rate',num2str((1-count_error/size(data,1))*100),'%']);
    end
    
    
  • 相关阅读:
    [C/C++] 指针数组和数组指针
    [计算机网络] DNS劫持和DNS污染
    [计算机网络-数据链路层] CSMA、CSMA/CA、CSMA/CD详解
    [BinaryTree] 二叉树常考知识点
    NODE-windows 下安装nodejs及其配置环境
    MATLAB/Excel-如何将Excel数据导入MATLAB中
    Excel-怎样实现行列转置
    一篇文章学懂Shell脚本
    SQL-MySQL使用教程-对MySQL的初步尝试
    资源贴-在线编译环境推荐
  • 原文地址:https://www.cnblogs.com/princeness/p/11664899.html
Copyright © 2011-2022 走看看