function [center, U, obj_fcn] = KFCMClust(data, cluster_n, kernel_b,options)
% FCMClust.m? ?采用模糊C均值對數據集data聚為cluster_n類
%
% 用法:
%? ?1.??[center,U,obj_fcn] = KFCMClust(Data,N_cluster,kernel_b,options);
%? ?2.??[center,U,obj_fcn] = KFCMClust(Data,N_cluster,kernel_b);
%? ?3.??[center,U,obj_fcn] = KFCMClust(Data,N_cluster);
%
% 輸入:
%? ?data? ?? ???---- nxm矩陣,表示n個樣本,每個樣本具有m的維特征值
%? ?N_cluster? ?---- 標量,表示聚合中心數目,即類別數
%? ?kernel_b? ? ---- 高斯核參數b? ?? ?? ?? ?? ?? ?? ?? ?? ?(缺省值:150)
%? ?options? ???---- 4x1矩陣,其中
%? ?? ? options(1):??隸屬度矩陣U的指數,>1? ?? ?? ?? ?? ?? ?(缺省值: 2.0)
%? ?? ? options(2):??最大迭代次數? ?? ?? ?? ?? ?? ?? ?? ?? ?(缺省值: 100)
%? ?? ? options(3):??隸屬度最小變化量,迭代終止條件? ?? ?? ???(缺省值: 1e-5)
%? ?? ? options(4):??每次迭代是否輸出信息標志? ?? ?? ?? ?? ? (缺省值: 1)
% 輸出:
%? ?center? ?? ?---- 聚類中心
%? ?U? ?? ?? ???---- 隸屬度矩陣
%? ?obj_fcn? ???---- 目標函數值
%? ?Example:
%? ?? ? data = rand(100,2);
%? ?? ? [center,U,obj_fcn] = KFCMClust(data,2);
%? ?? ? plot(data(:,1), data(:,2),'o');
%? ?? ? hold on;
%? ?? ? maxU = max(U);
%? ?? ? index1 = find(U(1,:) == maxU);
%? ?? ? index2 = find(U(2,:) == maxU);
%? ?? ? line(data(index1,1),data(index1,2),'marker','*','color','g');
%? ?? ? line(data(index2,1),data(index2,2),'marker','*','color','r');
%? ?? ? plot([center([1 2],1)],[center([1 2],2)],'*','color','k')
%? ?? ? hold off;
%? ?Author: Genial
%? ?Date:? ?2005.5
%??一副圖中顯示多方圖片:montage
error(nargchk(2,4,nargin));? ? % 檢查輸入參數個數
data_n = size(data, 1); % 求出data的第一維(rows)數,即樣本個數
in_n = size(data, 2);? ?% 求出data的第二維(columns)數,即特征值長度,目前沒有用
% 默認操作參數
default_b = 150;? ?? ?? ?% 高斯核函數參數
default_options = [2;? ? ? ? % 隸屬度矩陣U的指數
100;? ?? ?? ?? ?? ? % 最大迭代次數
1e-5;? ?? ?? ?? ?? ?% 隸屬度最小變化量,迭代終止條件
1];? ?? ?? ?? ?? ???% 每次迭代是否輸出信息標志
if nargin == 2,
kernel_b = default_b;
options = default_options;
elseif nargin == 3,
options = default_options;
else? ? % 分析有options做參數時候的情況
% 如果輸入參數個數是3那么就調用默認的option;
% 如果用戶給的opition數少于4個那么就將剩余的默認option加上;
if length(options) < 4,
tmp = default_options;
tmp(1:length(options)) = options;
options = tmp;
end
% 返回options中是數的值為0(如NaN),不是數時為1
nan_index = find(isnan(options)==1);
% 將denfault_options中對應位置的參數賦值給options中不是數的位置.
options(nan_index) = default_options(nan_index);
if options(1) <= 1,
% 如果options中的指數m不超過1報錯
error('The exponent should be greater than 1!');
end
end
% 將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 = initkfcm(cluster_n, data_n);? ? ? ? % 初始化模糊分配矩陣,使U滿足列上相加為1
% 初始化聚類中心:從樣本數據點中任意選取cluster_n個樣本作為聚類中心。當然,
% 如果采用某些先驗知識選取中心或許能夠達到加快穩定的效果,但目前不具備這功能
index = randperm(data_n);? ?% 對樣本序數隨機排列
center_old = data(index(1:cluster_n),:);??% 選取隨機排列的序數的前cluster_n個
% Main loop??主要循環
for i = 1:max_iter,
% 在第k步循環中改變聚類中心ceneter,和分配函數U的隸屬度值;
[U, center, obj_fcn(i)] = stepkfcm(data,U,center_old, expo, kernel_b);
if display,
fprintf('KFCM:Iteration count = % d, obj. fcn = % f \n', i, obj_fcn(i));
end
center_old = center;? ? % 用新的聚類中心代替老的聚類中心
% 終止條件判別
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) = [];
% 子函數
function U = initkfcm(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), :);