python机器学习分类算法--感知器

  1. 感知器基本原理
  2. 代码实现

感知器基本原理

定义输入向量x,权值向量w,z是x与w的线性组合,z称作为净输入。

$$
x=\begin{bmatrix}x_{0}
\\ x_{1}
\\ …
\\ x_{m}
\end{bmatrix},x_{0}=1,w = \begin{bmatrix}w_{0}
\\ w_{1}
\\ …
\\ w_{m}
\end{bmatrix},z = x_{0}w_{0} + x_{1}w_{1} + … + x_{m}w_{m} = x^{T}w,
$$

定义激励函数h(z),激励函数是一个分段函数,简单来说,当净输入z大于0时,将其划分到1类,否则为 -1类。

$$
h(z) = \begin{cases}
1 & \text{ if } z\geq 0 \\
-1 & \text{ if } z= else
\end{cases}
$$

感知器将输入值乘以权值得到净输入,通过激励函数将样本分为正负两类,感知器的工作过程如下:

  1. 将权重初始化为零或一个极小的随机数。
  2. 迭代所有的训练样本x(i),执行以下操作:

​ (1)计算输出值$\hat{y} $

​ (2)更新权重$w_{j} $
$$
w_{j}:=w_{j}+\Delta w_{j}\\ \Delta w_{j}=\eta(y^{(i)}-\hat{y}^{(i)})x_{j}^{(i)}
$$
$\eta$为学习率,0~1之间的数。

通过给每一个特征$x_i$分配对应权重$w_i$,将对应特征和权重相乘后求和得到$z$,然后根据激励函数将z划分为两类,若通过激励函数后所得的输出值(即预测值)与训练数据对应$y_i$相符合,则不改变权重w,若不相符,则改变权重w,使得重新分配的权重在下次分类更接近或者达到真实值。

需要注意的是,若样本线性不可分,权重w会不断更新,在实际代码实现的时候需要设定一个最大迭代次数。

代码实现

定义类Perceptron,创建对象时可选参数有eta即学习率$\eta$,n_iter为迭代次数,可调用fit方法训练模型,调用predict方法测试模型。

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=50, random_state=1):        
        self.eta = eta        
        self.n_iter = n_iter        
        self.random_state = random_state

    def fit(self, X, y):
        rgen = np.random.RandomState(self.random_state)        
        self.w_ = rgen.normal(loc=0.0, scale=0.01,size=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))                
                self.w_[1:] += update * xi                
                self.w_[0] += update                
                errors += int(update != 0.0)            
            self.errors_.append(errors)        
        return self

    def net_input(self, X):        
        """Calculate net input"""        
        return np.dot(X, self.w_[1:]) + self.w_[0]

    def predict(self, X):        
        """Return class label after unit step"""        
        return np.where(self.net_input(X) >= 0.0, 1, -1)

从pd库中调用数据集,下表为数据集的最后5条数据。

df = pd.read_csv('https://archive.ics.uci.edu/ml/' 
...              'machine-learning-databases/iris/iris.data', 
...               header=None) 
df.tail()

0 1 2 3 4
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica

使用matplotlib库将数据可视化。

import matplotlib.pyplot as plt
# select setosa and versicolor 
y = df.iloc[0:100, 4].values 
y = np.where(y == 'Iris-setosa', -1, 1)

# extract sepal length and petal length 
X = df.iloc[0:100, [0, 2]].values
# plot data 
plt.scatter(X[:50, 0], X[:50, 1], label='setosa') 
plt.scatter(X[50:100, 0], X[50:100, 1],marker='x',label='versicolor')  
plt.xlabel('sepal length [cm]') 
plt.ylabel('petal length [cm]')
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('Number of updates')
plt.show()

折线图

def plot_decision_regions(X, y, classifier, resolution=0.02):

    # setup marker generator and color map    
    markers = ('s', 'x', 'o', '^', 'v')    
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')    
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot the decision surface    
    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))    
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)    
    Z = Z.reshape(xx1.shape)    
    plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)    
    plt.xlim(xx1.min(), xx1.max())    
    plt.ylim(xx2.min(), xx2.max())

    # plot class samples    
    for idx, cl in enumerate(np.unique(y)):        
        plt.scatter(x=X[y == cl, 0],                    
                    y=X[y == cl, 1],                    
                    alpha=0.8,                    
                    c=colors[idx],                    
                    marker=markers[idx],                    
                    label=cl,                    
                    edgecolor='black')

plot_decision_regions(X, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

分类图


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 572108581@qq.com

文章标题:python机器学习分类算法--感知器

文章字数:1.1k

本文作者:ZSH

发布时间:2019-10-03, 16:56:21

最后更新:2019-10-06, 11:11:19

原始链接:https://zhongshanhao.github.io/2019/10/03/ganzhiji/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录