您的位置:首页 > 其它

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

2015-07-07 13:33 253 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: