统计学习笔记
感知机
感知机适用于二分类是对线性的向量集合进行分类,是一种判别模型,将极小化误分点到超平面距离,把误分点到超平面距离作为学习的损失函数,利用梯度下降算法进行寻优。
其算法流程图如下:
matlab实现
其matlab程序如下:
clear;clc;
%% 载入数据
data = [1 2 1 ; 2 3 1 ;3 5 1 ; 4 7 1 ; 4 2 -1; 5 1 -1; 9 5 -1; 8 6 -1]; % 测试数据
%% 绘制数据点
n=size(data,2)-1;% 输入变量的维度
sample = data(:,1:n); % 每一行代表一个数据点
label = data(:,end);% 样本判别结果
draw(sample, label)% 绘制散点图(由于例子给定二维因此可以可视化)
hold on
%% 初始化w,b,alpha
w = [-1,-2];
b = 2;
alpha = 1; % 学习因子
%% 更新 w,b
while 1
[idx_misclass, counter] = class(sample, label, w, b);
if (counter~=0)
R = unidrnd(counter);% 随机选择
% 更新w,b
w = w + alpha * sample(idx_misclass(R),:) * label(idx_misclass(R));
b = b + alpha * label(idx_misclass(R));
else
break
end
end
%% 绘制线性分类器
x1 = 1:0.01:10;
x2 = (-b-w(1).*x1)./w(2);
plot(x1, x2)
%% 做分类处理,找到误判及其个数
function [idx_misclass, counter] = class(sample, label, w, b)
counter = 0;
idx_misclass = [];
for i=1:length(label)
if (label(i)*(w*sample(i,:)'+b)<=0)
idx_misclass = [idx_misclass i];
counter = counter + 1;
end
end
end
function draw(sample, label)% 用于区分点的类型
idx_pos = find(label==1);
idx_neg = find(label~=1);
plot(sample(idx_pos, 1), sample(idx_pos, 2),'ro','LineWidth',1.5)
hold on
plot(sample(idx_neg, 1), sample(idx_neg, 2),'b*','LineWidth',1.5)
% axis([0 10 0 10])
grid on
end
测试结果如图:
R语言实现
percept = function(data = data,eta = eta ){
x = data[,-dim(data)[2]] ## 样本输入数据点
y = data[,dim(data)[2]] ## 样本输出数据
w = c(0,0) ## 初始化w,b
b = 0
len = length(y)
i = 1
while(i <= len){
if(y[i] * (x[i,] %*% w + b) <= 0){
## 更新 w and b
w = w + eta * y[i] * x[i,] ## 在存在误判的点处进行梯度下降
b = b + eta * y[i]
i = 1 ## 保证遍历每个样本点
}
else{
i = i + 1
}
}
return(list(w=w,b=b))
}
## 主函数,eta学习率
## 载入数据
data = matrix(c(3,3,1,4,3,1,1,1,-1),nr=3,byrow=T)
perceptron = percept(data = data,eta = 1)
## 可视化,针对二维
dat1 = data[,1:2]
dat1 = as.data.frame(dat1)
names(dat1) = c("x1","x2")
## 分别计算系数
a = perceptron[["w"]][1]
b = perceptron[["w"]][2]
c = perceptron[["b"]]
plot(x2~x1,data = dat1,col = ifelse(a*x1 +b*x2 + c<= 0,"red","blue"),pch = 17,bty = "l")
if(b){
abline(-c/b,-a/b,lwd=2,lty=2,col="red")
}
Python实现