感知器算法基于单层神经网络的范畴,不仅是第一个以算法描述的学习算法,而且很直观,也较为容易实现。同时,它也是是最先进的机器学习算法之一——人工神经元网络(也可称作“深入学习”)的绝好切入点。
感知器的最初概念可以追溯到Warren McCulloch和Walter Pitts在1943年的研究,他们将生物神经元类比成带有二值输出的简单逻辑门。以更直观的方式来看,神经元可被理解为生物大脑中神经网络的子节点。在这里,变量信号抵达树突。输入信号在神经细胞体内聚集,当聚集的信号强度超过一定的阈值,就会产生一个输出信号,并被树突传递下去。
感知器属于监督学习算法类别,更具体地说是单层二值分类器。简而言之,分类器的任务就是基于一组输入变量,预测某个数据点在两个可能类别中的归属。
感知器分类算法的适用范围:数据可以线性划分(即第一种)
最初的感知器规则相当简单,可总结为下面两步:
-
将权值初始化为0或小随机数。
-
对每一个训练样本x^i:
(1) 计算输出值。
(2) 更新权值。
感知器数据分类算法步骤如下:
其步调函数与阈值设定如下:
其权重更新和阈值更新过程:
通过结合网络中一个花朵花瓣与花径长度的数据,使用python将感知器算法进行初步实现,使用部分数据对感知器进行训练。
(注:这里笔者使用的是Anaconda平台中Jupyter Notebook的进行编码)
import numpy as np
class Perceptron(object):
"""
eta:学习率
n_iter:权重向量的训练次数
w_:神经分叉权重向量
errors_:记录神经元判断出错次数
"""
def __init__(self,eta = 0.01,n_iter=10):
self.eta=eta
self.n_iter=n_iter
pass
def fit(self,x,y):
"""
输入训练数据,训练神经元
x为输入样本向量,y为样本分类
x:shap[n_samples,n_features]
例如:x:[[1,2,3],[4,5,6]]
n_samples=2,n_features=3
y:[1,-1]第一个样本分类为1,第二个分类为-1
"""
"""
初始化权重向量为0
加一是因为w0是步调函数(激活函数)的阈值
"""
self.w_=np.zeros(1+x.shape[1])
self.errors_=[]
for _ in range(self.n_iter):
errors=0
"""zip(x,y)=[[1,2,3,1],[4,5,6,-1]]"""
for xi,target in zip(x,y):
"""
阈值更新
update = eta * (y-y')
"""
update=self.eta * (target - self.predict(xi))
"""
权重更新
xi是一个向量
w_忽略第一个元素,第一个元素w_[0]为阈值
"""
self.w_[1:] += update*xi
"""更新阈值"""
self.w_[0] += update
errors+=int(update !=0.0)
self.errors_.append(errors)
pass
pass
def net_input(self,x):
"""z=w0*1+w1*x1+...+wn*xn"""
return np.dot(x,self.w_[1:])+self.w_[0]
def predict(self,x):
return np.where(self.net_input(x) >=0.0,1,-1)
上述代码是感知器的实现部分,其中方法fit( )为核心部分。
下面导入数据:
file="https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
import pandas as pd
"""没有文件头,即数据说明,所以header = None"""
df = pd.read_csv(file,header = None)
"""显示数据文件的前十行"""
df.head(10)
显示前十行为例,可以清晰看出数据的内容:
下面进行数据可视化,得到前100行数据的分布情况:
"""数据可视化"""
import matplotlib.pyplot as plt
import numpy as np
"""抽取数据的第四列赋值给y"""
y = df.loc[0:100, 4].values
y = np.where(y =='Iris-setosa',-1,1)
X = df.iloc[0:100,[0,2]].values
plt.scatter(X[:50,0],X[:50,1],color='red', marker='o',label='setosa')
plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='versicolor')
plt.xlabel('Petal length')
plt.ylabel('Length of flower diameter')
plt.legend(loc='upper left')
plt.show()
得到下图结果:
接下来进行判断得到初步判断结果:
ppn = Perceptron(eta =0.1,n_iter=10)
ppn.fit(X,y)
plt.plot(range(1,len(ppn.errors_) + 1), ppn.errors_,marker='o')
plt.xlabel('Epochs')
plt.ylabel('Error classification times')
from matplotlib.colors import ListedColormap
def plot_decision_regions(X,y,classifier, resolution=0.02):
marker = ('s','x','c','v')
colors = ('red','blue','lightgreen','gray','cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
x1_min, x1_max = X[:, 0].min() -1, X[:, 0].max()
x2_min, x2_max = X[:, 1].min() -1, X[:, 1].max()
'''将二维向量扩展成为矩阵'''
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
'''变量z存储训练后的神经元进行判断的结果'''
z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
z = z.reshape(xx1.shape)#将z重新按照xx1的格式排列
plt.contourf(xx1, xx2, z, alpha=0.4, cmap=cmap)#绘制分界线
plt.xlim(xx1.min(), xx1.max())#x轴的起始节点和结束节点
plt.ylim(xx2.min(), xx2.max())#y轴的
plt.scatter(X[:50,0],X[:50,1],color='red', marker='o',label='setosa')
plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='versicolor')
plt.xlabel('Petal length')
plt.ylabel('Length of flower diameter')
plt.legend(loc='upper left')
plot_decision_regions(X,y,ppn, resolution=0.02)
plt.show()
最后得到结果:一条清晰的分界线
**该博客仅代表笔者在机器学习部分初步学习了解的内容,有错误和不清楚的地方在所难免,如有错误和不足请大家指正,我们可以一起探讨学习,共同进步!**
**感谢**