通过Rossenblatt感知器算法可以由花瓣长度和萼片长度数据集对两种鸢尾花进行分类。
其分类方法为若输入为矩阵
x
x
x,另设一权重矩阵
w
w
w,则净输入定义为:
z
=
w
T
x
z=w^Tx
z=wTx
激励函数定义为:
ϕ
(
z
)
=
{
1
z
≥
θ
−
1
o
t
h
e
r
w
i
s
e
\phi(z)=\left\{\begin{array}{c} &1&z\ge\theta\\ &-1&otherwise \end{array} \right.
ϕ(z)={1−1z≥θotherwise
此处
θ
\theta
θ为阈值,1与-1为所分成的两个类。
代码引自《Python机器学习》,如下所示:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
class Perceptron(object):
def __init__(self, eta = 0.01, n_iter=10): #eta:学习率 ,n_iter迭代次数
self.eta=eta;
self.n_iter=n_iter
def predict(self,X):# X:电信号向量(输入样本向量)
return np.where(self.net_input(X) >= 0.0 , 1,-1)
def net_input(self,X):
return np.dot(X,self.w_[1:])+self.w_[0]
def fit(self,X,y):
self.w_=np.zeros(1+X.shape[1])
self.errors_=[]
for _ in range(self.n_iter):
errors=0
for xi,target in zip(X,y):
update = self.eta * (target - self.predict(xi)) #update=eta*(y-y')
self.w_[1:] += update * xi #把原来的权重分量全部加上增加的分量,随迭代次数增加,权重更加准确
self.w_[0] += update; #更新检验值w_[0]
errors += int(update !=0.0) #记录神经元判断出错次数(若update值不等于零,即预测值不等于实际值)
self.errors_.append(errors) #append()方法用于在列表结尾添加新的对象
return self
df=pd.read_csv('https://archive.ics.uci.edu/ml/' 'machine-learning-databases/iris/iris.data',header=None) #读入原始数据
y=df.iloc[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('sepal length')
plt.legend(loc='upper left')
plt.show() #绘出未用算法进行分类时的petal length(花瓣长度)和sepal length(萼片长度)值,可观察到较为明显的分界
#绘制错误次数随迭代次数的增加的变化
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('Number of missclassifications')
plt.show()
#绘制决策区域
def plot_decision_regions(X,y,classifier,resolution=0.02):
markers=('s','x','o','^','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()+1
x2_min,x2_max=X[:,1].min()-1,X[:,1].max()+1
xx1,xx2=np.meshgrid(np.arange(x1_min,x1_max,resolution),np.arange(x2_min,x2_max,resolution)) #np.arange返回一个有起点和终点的排列,参数顺序:起点,终点,步长
Z=classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T) #ravel()将数组拉成一维数组
Z=Z.reshape(xx1.shape)
plt.contourf(xx1,xx2,Z,alpha=0.4,cmap=cmap)
plt.xlim(xx1.min(),xx1.max())
plt.ylim=(xx2.min(),xx2.max())
for idx, cl in enumerate(np.unique(y)): #np.unique:去除重复数据
plt.scatter(x=X[y==cl,0],y=X[y==cl,1],alpha=0.8,c=cmap(idx),marker=markers[idx],label=cl)
plot_decision_regions(X,y,classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()
初始数据绘图如下:
随迭代次数增加错误分类的次数逐渐减少:
最终的分类划分图: