Python 实现感知机算法,用 iriis 数据子集训练一个感知器模型

感知机算法,代码如下:

import numpy as np

class Perceptron():
    """感知机分类器
    
    参数
    ==========
    eta: 学习速率,区间 [0.0, 1.0] 上的浮点数
    n_iter: 迭代次数
    
    属性
    ==========
    w_: 权重,1维数组
    errors_: 以列表形式存储每一次迭代过程中分类错误的样本数
    """
    
    def __init__(self, eta=0.01, n_iter=10): # 设置默认参数
        self.eta= eta
        self.n_iter = n_iter
    
    def fit(self, X, y):
        """学习训练数据
        
        参数
        ==========
        X:训练集的特征数据
        y: 训练集的类标号数据        
        """
        self.w_ = np.zeros(1 + X.shape[1]) # 初始化权重
        self.errors_ = []
    
        for _ in range(self.n_iter):
            errors = 0
            for xi, yi in zip(X, y):
                delta = self.eta * (yi - self.predict(xi))
                self.w_[0] += delta
                self.w_[1:] += delta * xi
                errors += int(delta != 0.0)
            self.errors_.append(errors)
        return self
    
    def net_input(self, X):
        """计算净输入"""
        z = np.dot(X, self.w_[1:]) + self.w_[0]
        return z
    
    def predict(self, X):
        """用 sign 函数预测类标号"""
        yHat = np.where(self.net_input(X) > 0.0, 1, -1)
        return yHat
View Code

利用 iries 的前 100 个样本的的 第 2 特征,第4 特征和类标号, 训练一个感知机分类器:

1、数据准备与可视化,代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

df = pd.read_csv('D:\\pySpace\\iris.data', header=None)
y = df.iloc[:100, 4].values
y = np.where( y == 'Iris-setosa', -1, 1) # 用 if(con, T_v, F_v)的思想编码
X = df.iloc[:100, [1, 3]].values

plt.figure(figsize=(9,7)) # 调整图片大小
plt.scatter(X[:50, 0], X[:50, 1], c='r', marker='o', label='山鸢尾')
plt.scatter(X[50:, 0], X[50:, 1], c='b', marker='x', label='变色鸢尾')
plt.xlabel('花瓣长度(cm)', fontsize=17)
plt.ylabel('萼片长度(cm)', fontsize=17)
plt.yticks(fontproperties='Times New Roman', size=13, alpha=0.6)
plt.xticks(fontproperties='Times New Roman', size=13, alpha=0.6)
plt.legend(loc=1)

图形如下:

 

 2、训练模型,绘制每次迭代的错误分类数量的折线图,代码如下:

ppn = Perceptron(eta=0.1, n_iter=10)
ppn.fit(X, y) # 训练模型

plt.figure(figsize=(8, 6))
plt.plot(range(1, len(ppn.errors_) +1), ppn.errors_, marker='o')
plt.xlabel('迭代次数', fontsize=17)
plt.ylabel('错误分类的样本数量', fontsize=17)
plt.yticks(fontproperties='Times New Roman', size=13, alpha=0.6)
plt.xticks(fontproperties='Times New Roman', size=13, alpha=0.6)

 

 由图可知,分类器在在第3次迭代后就已经收敛,而且具备对训练样本正确分类的能力。

posted @ 2019-11-09 16:39  赏尔  阅读(254)  评论(0编辑  收藏  举报