感知器通常可分为单层感知器、单隐层感知器、双隐层感知器。其中单隐层感知器非常简单,易实现,此次将重点介绍其主要原理及其R语言的实现。
感知器对应的数学公式为:
y=sum(xi*wi)+theta
其中xi为输入,wi为权向量,theta为阈值参数,激活函数为纯线性(purelinear)函数,对应为多元线性回归表达式。感知器的学习是监督型学习,基本原理来源于Hebb学习律,其基本思想是:逐步地将样本集中输入到网络中,根据输出结果和理想输出之间的差别来调整网络中的权矩阵。SLP算法的基本步骤为:
step1:归一化输入向量,如果是标准化可能会引起算法无法收敛;
step2:用适当小的随机数初始化权向量W,并初始化精度控制参数epsilon、学习效率alpha,精度控制变量d,可用d=epsilon+1进行初始化;
step3:当d>epsilon时,进入循环,再次初始化d=0,并依次输入样本xj,计算输出y的估计和估计误差delta,并更新权向量:
w(k+1)=w(k)-alpha*delta*xj
其中k为迭代次数,并计算累计误差:
d = d+delta^2
step4:当d<epsilon时,退出循环,结束算法。
【实例】以iris数据集为例,代码如下:
######### 单层感知器 ##############
# 准备基础数据
source.Data <- iris[,1:4]
colnames(source.Data) <- c('x1','x2','x3','y')
# 归一化数据,只标准化连续变量可能会引起训练无法收敛,标准化函数为scale
max.min <- function(x){
(x-min(x))/(max(x)-min(x))
}
source.Data[,1:3] <- apply(source.Data[,1:3],2,max.min)
# 标准化数据
# source.Data[,1:3] <- scale(source.Data[,1:3])
# 合并数据,并增加列theta为阈值
ModelData = cbind(theta = 1,source.Data)
# 初始化精度控制参数
epsilon = 5.5;
# 初始化学习效率
alpha = 0.05;
# 精度控制变量
d = epsilon + 1;
# 用适当小的随机数初始化权向量
w <- runif((ncol(ModelData)-1),0,1);
while(d>=epsilon)
{
# 初始化精度
d=0
for(i in 1:nrow(ModelData))
{
xi = ModelData[i,1:(ncol(ModelData)-1)]
# 误差计算
delta = sum(xi*w) - ModelData[i,ncol(ModelData)]
# 权重及精度更新更新
w = w - alpha*delta*xi
d = d + delta^2
}
print(d)
}
# 输出结果
# [1] 19.03164
# [1] 12.94279
# [1] 10.03571
# [1] 8.649075
# [1] 7.972343
# ...
# [1] 5.50216
# [1] 5.501191
# [1] 5.500309
# [1] 5.499507
# 估计值
y.hat <- as.matrix(ModelData[,1:4])%*%t(w)
sum.error <- sum((y.hat-ModelData[,5])^2)
sum.error
# 输出结果
# [1] 8.243479
该模型的累计误差从19.03164逐渐降低至5.499507,小于设定的精度阈值5.5,跳出循环,此时该模型的残差平方和为8.243479。进一步我们查看模型的权向量如下:
w
# 权向量估计
# theta x1 x2 x3
# -0.06913457 -0.5872714 0.4052546 3.138048
我们建立线性回归模型进行比较,如下:
lm.iris <- lm(y~x1+x2+x3,data = source.Data)
lm.iris
# Call:
# lm(formula = y ~ x1 + x2 + x3, data = source.Data)
#
# Coefficients:
# (Intercept) x1 x2 x3
# -0.1618 -0.7462 0.5348 3.0921
显然该线性回归模型的参数估计与单层感知器的权向量很接近。
参考:《R语言预测实战》-游皓麟