感知机是二分类的线性分类模型,由Rosenblatt于1957年提出,是支持向量机和神经网络的基础。感知机将学习到一个线性划分的分离超平面,属于判别模型。
输入空间为
损失函数使用的是错分类点到分类超平面S的总距离,任意一点x到超平面的距离使用如下公式计算:
使用的是同样的一个垃圾邮件分类的数据,与另一篇博客KNN分类算法使用的是一个数据集。使用python实现了上述算法,并绘制了不同步长下训练集的错分率和测试集的正确率。
由于该实际数据集并不是线性可分的,因此使用了折中办法,寻找训练集错分率最小的步长和对应的模型,并对测试集进行测试找出正确率最大的步长和模型,二者综合获取最终的模型,同时还加入了最大迭代次数的限制,默认设置为500次。
def normalize(ds):
minVals = ds.min(0)
###get an array of minimum element of each column
maxVals = ds.max(0)
ranges = maxVals - minVals
normDS = zeros(shape(ds))
n = ds.shape[0]
normDS = ds - tile(minVals, (n, 1))
##tile an array in to a n*1 matrix
normDS = normDS / tile(ranges, (n, 1))
return normDS
def percepTrain(ds, labels, stepLen = 1, maxSteps=500, err=5):
‘‘‘Don‘t use the completely linear seperation
but a maximum steps and error control‘‘‘
i = 0
minErrDotLen = TRAINSET_NUM + 1
params = []
w = zeros(ds.shape[1]); b = 0
while i < maxSteps:
model = labels * (dot(ds, w) + b)
iLess = model[model <= 0]
if len(iLess) < minErrDotLen:
minErrDotLen = len(iLess)
params = [w, b]
if len(iLess) <= int(TRAINSET_NUM*err/100):
### When the error classification ratio is less than err, break
break
x = ds[int(iLess[0]), :]
y = labels[int(iLess[0])]
w = w + stepLen * y * x
b = b + stepLen * y
i += 1
return params, minErrDotLen, i
def percepClassify(model, predict):
w,b = model
py = zeros(predict.shape[0])
py[dot(predict, w) + b > 0] += 1
return py*2 - 1
从图中可以看出当迭代步长为5时,虽然训练集的错分率不是最低,有20%多,但是测试集的准确率确是最好的,因此应该选择步长为5的对应的模型。
原文地址:http://blog.csdn.net/u010487568/article/details/45210027