n=50;
x=[randn(1,n/2)-15 randn(1,n/2)-5; randn(1,n)]';
y=[ones(n/2,1);-ones(n/2,1)];
x(1:2,1)=x(1:2,1)+10;
x(:,3)=1;
p=randperm(n);
x=x(p,:);
y=y(p);
mu=zeros(3,1);
S=eye(3);
C=1;
for i=1:length(x)
xi=x(i,:)';
yi=y(i);
z=S*xi;
b=xi'*z+C;
m=yi*mu'*xi;
if m<1, mu=mu+yi*(1-m)*z/b;
S=S-z*z'/b;
end
end
figure(1);
clf;
hold on;
axis([-20 0 -2 2]);
plot(x(y==1,1),x(y==1,2),'bo');
plot(x(y==-1,1),x(y==-1,2),'rx');
plot([-20 0],-(mu(3)+[-20 0]*mu(1))/mu(2),'k-');
这段代码是一个适应正则化分类的算法,下面逐行解释每一行的作用:
n=50; - 定义了样本数量为50。
x=[randn(1,n/2)-15 randn(1,n/2)-5; randn(1,n)]'; - 生成了一个n行3列的特征矩阵x。前n/2行的第一列取自服从标准正态分布的随机数减去15,第二列取自服从标准正态分布的随机数减去5;后n/2行的第一列取自服从标准正态分布的随机数,第二列取自服从标准正态分布的随机数。最后通过转置操作将矩阵变为3行n列。
y=[ones(n/2,1);-ones(n/2,1)]; - 生成了一个n行1列的标签向量y,前n/2行的元素为1,后n/2行的元素为-1。
x(1:2,1)=x(1:2,1)+10; - 将x矩阵的前两行、第一列的元素都加上10。
x(:,3)=1; - 在x矩阵的第三列添加全1的列,用于表示偏置项。
p=randperm(n); - 生成一个长度为n的随机排列。
x=x(p,:); - 根据随机排列p对特征矩阵x进行行重排。
y=y(p); - 根据随机排列p对标签向量y进行元素重排。
mu=zeros(3,1); - 初始化一个3行1列的零向量mu。
S=eye(3); - 生成一个3x3的单位矩阵S。
C=1; - 设置正则化参数C为1。
for i=1:length(x) - 循环遍历x矩阵的每一行。
xi=x(i,:)'; - 提取x矩阵的第i行作为列向量xi。
yi=y(i); - 提取y向量的第i个元素作为标签yi。
z=S*xi; - 计算矩阵S与向量xi的乘积,得到向量z。
b=xi'*z+C; - 计算xi的转置与z的内积,再加上正则化参数C,得到标量b。
m=yi*mu'*xi; - 计算标签yi、mu的转置与xi的内积,得到标量m。
if m<1, mu=mu+yi*(1-m)*z/b; - 如果m小于1,执行更新mu的操作。
S=S-z*z'/b; - 更新矩阵S。
figure(1); - 创建一个新的图形窗口。
clf; - 清空当前图形窗口。
hold on; - 设置保持绘图,用于绘制多个图形。
axis([-20 0 -2 2]); - 设置坐标轴范围。
plot(x(y==1,1),x(y==1,2),'bo'); - 绘制标签为1的样本点,用蓝色圆圈表示。
plot(x(y==-1,1),x(y==-1,2),'rx'); - 绘制标签为-1的样本点,用红色叉号表示。
plot([-20 0],-(mu(3)+[-20 0]*mu(1))/mu(2),'k-'); - 绘制分离超平面,其中mu(1)、mu(2)、mu(3)分别表示超平面的系数,用黑色直线表示。