今天把感知机的算法用Python实现了一下。
主要依据的算法流程是《统计学习方法》中关于感知机的算法过程,具体如下。
# -*- coding: utf-8 -*- """ Created on Sat Oct 13 11:09:02 2018 @author: Administrator """ import numpy as np class MLP: def generate_data(self, m, n): ''' 随机生成训练数据,测试数据也可同样方法生成 m:样本的个数 n:每个样本具有的特征维数 y: ±1 ''' x = np.random.random((m,n)) #x2 = np.random.random((m,n)) y1 = np.ones(m) #y2 = np.ones(m)*(-1) start = int(m / 2) y1 [start:] = y1[start:] * (-1) return x, y1 def judge_func(self, x, y, w, b): ''' 来判断是否对参数进行更新的函数 x: xi y: yi w: wi b: bi ''' value = y * (np.dot(w, x) + b) #print(value) return value def mlp_train(self, x, y, w, b, yita): ''' 感知机 x: 输入数据矩阵 y:输入标签矩阵 ''' error_sample = [] error_label = [] for i in range(len(x)): if self.judge_func(x[i], y[i], w, b) <= 0: w = w + yita * y[i] *x[i] b = b + yita * y[i] error_sample.append(x[i]) error_label.append(y[i]) if len(error_sample) > 0: self.mlp_train(error_sample,error_label, w, b, yita) return w, b def test(self, x_test, w, b): y_pre = [] for i in range(len(x_test)): value = np.dot(w, x_test[i].T) + b y_temp = np.sign(value) y_pre.append(y_temp) return y_pre def cal_accuracy(self, y_pre, y_test): num = 0 for i in range(len(y_pre)): if y_pre[i] == y_test[i]: num += 1 accuracy = num / len(y_test) return accuracy if __name__ == '__main__': m, n = 1000, 3 #输入生成样本的数量和维度 train = MLP() x_train, y_train = train.generate_data(m, n) #m, n = np.shape(x) #print(y_train.shape) #print((np.transpose(x_train[1])).shape) w = np.zeros((1, n)) b = 0 yita = 0.1 w, b = train.mlp_train(x_train, y_train,w,b,yita) x_test, y_test = train.generate_data(m, n) y_pre = train.test(x_test, w, b) print('感知机的准确率为: ', train.cal_accuracy(y_pre, y_test))
在实现的过程中其实有很长的时间在纠结关于参数w和b的维数的问题,因为不太清楚怎么确定。 后来想明白了,w的维数应该和每一个样本的维度是一样的,这样才能保证样本的在每一个特征上都有一个权重参数,而最终的目标也是对这些权重参数拟合,其实有点像多项式的系数。