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