关闭

模式识别几何分类算法实现(一)

标签: 模式识别
380人阅读 评论(0) 收藏 举报
分类:

1.感知器算法:

% 感知器算法的实现
function [W,b] = new_perceptron(dataset,classf,MaxIter)
%% 功能说明
%  求解两类的线性可分问题
%% 参数说明
%input:
%dataset :  训练样本集
%classf  :  对应样本的类别集
%MaxIter :  最大迭代次数
%output:
%W       :  感知器的权值向量
%b       :  感知器的阈值

%% 样本
T=size(dataset,1);      %样本总数
x=dataset(:,1:end-1);
x = x';

class_unique = unique(classf);

d = zeros(T,1);
d(classf == class_unique(1)) = 1;
d(classf == class_unique(2)) = -1;

W=[0 1];  %初始化权值矩阵
b=1;      %初始化阈值
yita=1;   %学习步长

jingdu=0.01;    %最大误差容限
E=1;

%最大迭代次数
if (nargin < 3)
   M = 2000;    %默认的迭代次数
else
   M = MaxIter;
end

N=0;
while (E>jingdu && N<M)
    N=N+1;
    E=0;
    for t=1:T
        a=sgn(W*x(:,t)+b);
        e=d(t)-a;
        if e~=0          %与期望值不同时修改权值和阈值
            p=x(:,t);
            W=W+yita*e*p';   %修正权值向量
            b=b+yita*e;
        end
        E=E+e^2/2;    
    end
end

end

%符号函数sgn
function a=sgn(b)
     if b>=0
         a=1;
     else
         a=-1;
     end
end

2.K-近邻算法:

% K-近邻算法实现
function ox_class = KNN(dataset,classf,k,ox)
%% 参数说明
%input : 
%dataset : 样本数据集
%classf  : 样本对应的类别集  
%k       : K-近邻
%ox      : 待分类的样本向量
%output  : 待分类样本向量的类别

    [row,~] = size(dataset);
    distance = zeros(row,1);
    for i = 1:row
        distance(i) = sqrt(sum((dataset(i,:) - ox).^2));   %利用欧式距离计算相似度
    end
    [~,class_idx] = sort(distance);
    knn_class = class_idx(1:k);
    class_all = unique(classf);  %获取种类的类别总数
    len = length(class_all);
    count_K_class = zeros(len,1);
    for i = 1:len
        for j = 1:k
            if (class_all(i) == classf(knn_class(j)))
                count_K_class(i) = count_K_class(i) + 1;
            end
        end
    end

[~,ox_class_max_idx] = max(count_K_class);
ox_class = class_all(ox_class_max_idx);
end

3.H-K算法的实现:

% H-K算法的实现
function [W,b,isLinearCluster] = HK(dataset,classf)
%input:
%dataset           : 训练样本数据集
%classf            :  对应的样本类别集
%output:
%W                 :  权值向量
%b                 :  阈值向量
%isLinearCluster   :  判断是否是线性可分的
%% 有点小问题,可能陷入死循环!!!
%  可能需要设置一个最大跌代次数限制程序的运行

%% 由训练样本集构建增广矩阵X
[row ,col] = size(dataset);
X = zeros(row,col+1);
class_all = unique(classf);
if (length(class_all)~=2)                 %只考虑两类问题
    return;
else
    for i = 1:row
        if(classf(i) == class_all(1))
            X(i,:) = [dataset(i,:),1];
        else
            X(i,:) = [-dataset(i,:),-1];  %之前忘了在数据集前加个负号,所以一直出错!!!!
        end
    end

   %% H-K算法的流程
    PX = (X'*X)\X';         % == inv(X'*X)*X' 计算X的伪逆
    r = 0.6;                %学习步长
    b = ones(row,1)/10;     %初始化一个正的余向量
    W = PX*b;               %初始化权值向量
    stop = 1;
    while(stop)
       e = X * W - b;
       switch(checkValueofE(e))
           case 1                   %终止算法,是线性可分的
                 stop = 0;
                 isLinearCluster = 1;
           case 2                   %终止算法,不是线性可分的
                 stop = 0;
                 isLinearCluster = 0;
           case 3                   %继续迭代
                 W = W + r * PX * (e + abs(e));
                 b = b + r * (e + abs(e));
        end
    end
end
end

%% 百度上提供的方法,好像更加合理
function flag = checkValueofE(e)

    max_e = max(e);
    min_e = min(e);

    if( min_e > -1e-4 && min_e < 0)
        min_e = 0;
    end

    if min_e > 1e-3
        flag = 3;
    else   
        if min_e >= 0 && max_e < 1e-4  %线性可分
            flag = 1;
        else
            if max_e < 0               %都小于零,线性不可分
                 flag = 2;
            else                       %继续迭代
                 flag = 3;
            end
        end
    end
end

% checkValueofE
%% 我写的方法,好像有问题
% function flag = checkValueofE(e)
%     tol = 1e-6;
%     if (sum(e.^2) < tol) %e的每个分量为0(接近于0),则停止算法
%         flag = 1;
%     else if (sum(e >= 0) == length(e))
%             flag = 1;
%     else if((sum(e <= 0.0001) == length(e)) 
              && (sum( e == 0) ~= length(e)))  % e的每个分量均小于等于0,  但不是全为0,则停止算法
%             flag = 2;
%             else           % e的分量中既有正值也有负值,则继续迭代
%                 flag = 3;
%             end
%         end
%     end
% end


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:74121次
    • 积分:1250
    • 等级:
    • 排名:千里之外
    • 原创:45篇
    • 转载:49篇
    • 译文:0篇
    • 评论:5条
    最新评论