#-*- coding:utf-8 -*-
'''
Purpose: implement perceptron algorithm; the perceptron algorithm is a binary classification algorithm, and is used to handle data sets that are linearly seperable.
Author: hittlle
QQ: 519234757
Email: hittlle@163.com
'''
importnumpy
classPerceptron:
def__init__(self, training_set = [], iterations =5, learning_rate =0.5):
self._training_set = training_set
self._iterations = iterations
self._learning_rate = learning_rate
self._setup()
def_setup(self):
iflen(self._training_set) >:
self._weight = numpy.zeros(len(self._training_set[][:-1]))
self._bias =0.0
self._alpha = numpy.zeros(len(self._training_set))
else:
self._weight =None
self._bias =None
self._alpha =None
#感知机原始形式training
defraw_training(self):
self._setup()
ifself._weightisNone:
return
foriterinxrange(self._iterations):
forsampleinself._training_set:
prediction = numpy.dot(self._weight, sample[:-1]) +self._bias
ifsample[-1] * prediction
self._weight =self._weight + numpy.multiply(self._learning_rate * sample[-1], sample[:-1])
self._bias =self._bias +self._learning_rate * sample[-1]
print("[+] Raw Perceptron - Stochatic Gradient Descent")
print("[+] weight ",self._weight)
print("[+] bias ",self._bias)
print("[+] learning rate ",self._learning_rate)
print("[+] iterations ",self._iterations)
#Gram矩阵计算
defcalculate_gram_matrix(self):
dim =len(self._training_set)
self._gram = numpy.zeros((dim,dim))
shape = numpy.shape(self._gram)
forrowinrange(shape[]):
forcolinrange(shape[1]):
self._gram[row][col] = numpy.dot(self._training_set[row][:-1],self._training_set[col][:-1])
print("[+] Gram matrix for duality training:")
print(self._gram)
#感知机对偶形式training
defduality_training(self):
self._setup()
ifself._weightisNone:
return
# calculate Gram Matrix
self.calculate_gram_matrix()
dim =len(self._training_set)
foriterinxrange(self._iterations):
sample_idx =
forsampleinself._training_set:
prediction =0.0
alpha_idx=
foridxinxrange(dim):
prediction +=self._alpha[idx] *self._training_set[idx][-1] *self._gram[sample_idx][idx]
prediction = sample[-1] * (prediction +self._bias)
ifprediction
self._alpha[sample_idx] =self._alpha[sample_idx] +self._learning_rate
self._bias =self._bias +self._learning_rate * sample[-1]
sample_idx +=1
#calculate weight
idx =
#_weight是training sample的线性组合
foriterinxrange(dim):
self._weight = numpy.add(numpy.multiply(self._alpha[idx] *self._training_set[iter][-1],self._training_set[iter][:-1]),self._weight)
idx+=1
print("[+] Duality Perceptron - Stochatic Gradient Descent")
print("[+] weight ",self._weight)
print("[+] bias ",self._bias)
print("[+] learning rate ",self._learning_rate)
print("[+] iterations ",self._iterations)
if__name__ =='__main__':
#test
training_set = [[3,3,1],[4,3,1],[1,1, -1]]
perceptron = Perceptron(training_set=training_set,iterations=5,learning_rate=1.0)
perceptron.raw_training()
perceptron.duality_training()
del(perceptron)
del(training_set)
training_set = [[12,32,11,12,10,1], [10,23,10,1,100, -1], [30,30,21,12,21,1], [11,10,12,13,12, -1]]
perceptron = Perceptron(training_set=training_set,iterations=100,learning_rate=0.0005)
perceptron.raw_training()
perceptron.duality_training()
上篇中的代码有一个小错误,虽无大的影响,但也不够严谨,这儿修正一下。下面是运行结果。
可以看到,对同一个数据集,原始形式和对偶形式算法得出的结果一样。笔者认为,对偶形式在训练样本比较少的时候有用,在训练样本比较多,而且维度比较高的情况下,计算Gram矩阵的开销就会比较大;而原始形式没有这样的问题。
领取专属 10元无门槛券
私享最新 技术干货