思想
感知器无法处理线性不可分的情况,对其进行变形,使用贪心策略可以解决这个问题。具体思想见台大机器学习基石第二周笔记4
Matlab代码
perceptron.m
n=1; %学习速率
p=[-9,1,-12,-4,0,7,5,-2;15,8,4,5,11,8,9,8]; %输入向量x1,x2
p=[ones(1,size(p,2));p];%加上x0=1后的输入向量
y=[-1,1,-1,-1,-1,1,1,1];%期望的分类结果,即真实的分类结果,正样本+1,负样本-1
%初始点的分类情况图像
figure;
plot([-9,-12,-4,0],[15,4,5,11],'o')%第一类用o表示,负类
hold on;
plot([1,5,7,-2],[8,9,8,8],'*')%第二类用*表示,正类
axis([-13,10,-10,16])
legend('第一类','第二类')%图例
w0=[0,0,0];%初始权值向量
%由于[0,0,0]不代表任何直线
%用[0,0,0]加上第一个点的标签*第一个点的向量,代表w1
w1=w0+n*(y(1)*p(:,1))'; %'
w=w1;
num=0; %分错的数目
for j=1:size(p,2)
if y(j)~=sign_p(temp*p(:,j));
num=num+1;
end
end
max_iter=200;%最大迭代次数
iter=0;
min_mis_w=w;
while(iter<max_iter)
iter=iter+1;%当前迭代次数
num2=0;%当前分错的数目
for i=1:size(p,2)
%如果实际预测值和真实值不同,就修正w
if y(i)~=sign_p(w*p(:,i));
temp=w+n*(y(i)*p(:,i))'; %'
%计算分错的数目
for j=1:size(p,2)
if y(j)~=sign_p(temp*p(:,j));
num2=num2+1;
end
end
%如果当前分错数目小于等于历史最小分错数目
%则保留当前的w,
if num2<=num
min_mis_w=temp;%保留当前w
num=num2%更新历史最小分错数目
end
w=temp;%修正w
num2=0;%重置当前分错数目
%每次修正画个图(如果w(3)=0,该条分隔线画图会出错,
%但不影响以后的分隔线,只要最终结果的w(3)不为0,就没事)
x1=-13:0.2:10;
x2=(-w(2)*x1)/w(3)-w(1)/w(3);
b=plot(x1,x2);%保存为图形句柄,以后可以删除
%pause;
delete(b);%删除前面一条分隔线的图形句柄
end
end
end
w=min_mis_w;%w的取值为历史最小分错数目时的w
%画出最终的分隔线
x1=-13:0.2:10;
%由w(1)*1+w(2)*x1+w(3)*x2=0解出x2
x2=(-w(2)*x1)/w(3)-w(1)/w(3);
plot(x1,x2)
sign_p.m
%sign函数的实现:
%输入大于0 y=1,输入小于等于0,y=-1
function y=sign_p(x)
if(x>0)
y=1;
else
y=-1;
end