持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情
感知机算法
是一种迭代算法,在训练集上运行多个迭代,每次读入一个样本,执行预测,将结果与正确答案进行对比。根据误差更新模型参数。
- 读入训练样本,执行预测
- 如果则更新参数
训练集上每个样本执行以上步骤称作一次在线学习,完整学习一边训练集称为一次迭代,指定的迭代次数称为超参数
/**
* 朴素感知机训练算法
* @param instanceList 训练实例
* @param featureMap 特征函数
* @param maxIteration 训练迭代次数
*/
private static LinearModel trainNaivePerceptron(Instance[] instanceList, FeatureMap featureMap, int maxIteration){
LinearModel model = new LinearModel(featureMap, new float[featureMap.size()]);
for (int it = 0; it < maxIteration; ++it){
Utility.shuffleArray(instanceList);
for (Instance instance : instanceList){
int y = model.decode(instance.x);
if (y != instance.y) // 误差反馈
model.update(instance.x, instance.y);
}
}
return model;
}
/**
* 参数更新
*
* @param x 特征向量
* @param y 正确答案
*/
public void update(Collection<Integer> x, int y) {
assert y == 1 || y == -1 : "感知机的标签y必须是±1";
for (Integer f : x)
parameter[f] += y;
}
从仿生学角度,一个感知机就是一个神经元,是刺激的强度,如果刺激足够强烈,则神经元激活输出1;否则保持抑制,用-1表示。
二进制特征向量中某个元素代表第d个突出被激活了,权重向量中的表示突出对刺激程度的正负影响。
损失函数与梯度随机下降
从数值优化的角度来讲,迭代式机器学习算法都在优化一个损失函数,损失函数用来衡量模型在训练集上的错误程度,自变量是模型参数,因变量是一个标量,表示模型在训练集上的损失的大小。
给定样本,其特征向量知识常数,对求导,得到一个梯度向量,它的反方向一定是当前位置损失函数减小速度最快的方向。
参数点反方向移动就会使损失函数减小,即,,称为学习率
如果算法每次迭代随机选取部分样本,计算损失函数的梯度,让参数反向移动,则称作随机梯度下降
如果我们希望最大化一个目标函数,此时参数更新方向就是梯度方向,让参数加上梯度,目标函数就会增加,称作随机梯度上升
上图分别是单变量损失函数的梯度下降和多变量损失函数的梯度下降
具体到线性模型,感知机的损失函数就是误分类点到超平面的居里,即所谓的感知机准则函数
感知机算法其实是随机梯度下降算法的特例,其更新量就是负梯度。
加入数据本身线性不可分,感知机算法不收敛,每次迭代分离超平面都会剧烈震荡。假设有10000个实例,模型在9999个实例学习中都得到正确答案,可最后一个实例是噪声,朴素感知机模型预测错误后直接修改了模型,导致前功尽弃。对于这种情况,需要对感知机算法打补丁,即投票感知机或平均感知机。