机器学习番外篇-------感知器学习法则

获取测试样例数据集 以鸢尾花为例html

import pandas as pd算法

import matplotlib.pyplot as plt数组

from matplotlib.colors import ListedColormapapp

import numpy as np函数

 

>>> source_addr='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'学习

>>> df = pd.read_csv(source_addr, header=None)测试

>>> df.tail() # 查看鸢尾花 数据集是否正确加载优化

       0    1    2     3    4spa

145 6.7 3.0 5.2 2.3 Iris-virginica.net

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

>>> y = df.iloc[0:100, 4].values # pandas.DataFrame.iloc 取前100个值 且只去每行样本的第四列 (Iris-virginica)

>>> y = np.where(y == 'Iris-setosa', -1, 1)

numpy的where(condition, T, F)意思即为

if condition条件成立

          取 T

else

           取 F

>>> X = df.iloc[0:100, [0,2]].values  # 取 前100元素 只保留每一个样本的(每行) 第 1 和第 2 个特征

df.iloc[0:100, [0,2]]

    0    2

0 5.1 1.4

1 4.9 1.4

2 4.7 1.3

3 4.6 1.5

4 5.0 1.4

5 5.4 1.7

...

>>> df.iloc[0:100, [0,2]].values

array([[5.1, 1.4],

[4.9, 1.4],

[4.7, 1.3],

[4.6, 1.5],

[5. , 1.4],

[5.4, 1.7],

[4.6, 1.4],

...

>>> plt.scatter(x[:50, 0], x[:50, 1],color='red', marker='o', label='setosa') # 绘制散点图

举个栗子:

In [75]:X1 = [1,2,3,4,5,6]

In [76]: Y1 = [1,2,3,4,5,6]

In [77]: plt.scatter(X1,Y1,color='yellow', marker='o',label='he')

Out[77]: <matplotlib.collections.PathCollection at 0x7fca65dd9278>

In [78]: plt.show()

散点图:

                                          

折线图:

                                                   

X1,Y1别表明 X轴和Y轴上的点 color显示颜色, marker标记种类, label标记提示

>>> plt.scatter(x[50:100, 0], x[50:100, 1],color='blue', marker='x', label='versicolor')

>>> plt.xlabel('petal length')     # x轴标签

>>> plt.ylabel('sepal length')    # y轴标签

>>> plt.legend(loc='upper left')     # 绘制图像坐落位置

>>> plt.show()

绘图结果:

                            

上面是获取的部分鸢尾花的数据散点分布图

下面利用抽取出的鸢尾花数据子集进行训练感知器。

首先要讲下 感知器模型的 相关知识。

感知器模型是一种线性分类器,

在感知器法则中,罗森布拉特提出了一个自学习算法,此算法能够经过优化获得权重系数,此系数与输入值的乘积决定了神经元是否被激活。定义一个激励函数:,其中z称为净输入

罗森布拉特最初的感知器模型很是简单,

1) 将权重初始化为 0 或一个极小的随机数。

2) 迭代全部训练样本x^(i), 执行以下操做:

(1)计算输出值y^。

(2)更新权重

这里的输出值是指经过前面定义的单位阶跃函数预测得出的类标,而每次对权重向量中每一权重w的更新方式为:

对于用于更新的权重W_j的值,可经过感知器学习规则计算得到:其中,,为学习速率(0.0~1.0之间的常数),为第i个样本的真是类标,为预测获得的类标。须要注意:权重向量中的全部权重是同时更新的,这意味着在全部的权重更新前,咱们没法从新计算。具体而言,对于一个二维数据集,可经过下式进行更新:

                                                                

举个简单的栗子进行验证一下,若感知器类标预测准确,可经过以下式子进行更新:

                                                               

有趣的是,在类标预测错误的状况下,权重的值会分别趋向于正类(+1)或者负类(-1)的方向:

                                                       

另外,须要注意的是:感知器瘦脸有两个前提 一是类个类别必须是线性可分的 二是学习速率足够小。

                            

 

下面使用Python实现感知器算法:

# -*- coding:utf-8 -*-

"""

感知器学习算法

"""

import numpy as np

class Perceptron(object):

'''

eta :float

             表示学习速率

n_iter:int

             迭代次数

errors_:list

             每轮迭代中错误分类样本的数量

'''

def __init__(self, eta = 0.01, n_iter=10):

self.eta = eta

self.n_iter = n_iter

def fit(self, X, y):

"""

            拟合数据集 进行参照公式的计算

"""

self.w_ = np.zeros(1 + X.shape[1])        # X 的列数 即权重参考值 +1则是 考虑w_0

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

# 上面两步就是计算权重w的值 w_1~w_i

self.w_[0] += update

# 计算w_0的值

errors += int(update != 0.0)

# 用于收集每轮迭代中错误分类样本的数量 以便后续对感知器在训练集中表现的好坏作出断定

self.errors_.append(errors)

 

def net_input(self, X):

"""计算Z = W^T * X"""

return np.dot(X, self.w_[1:]) + self.w_[0]

 

def predict(self, X):

"""返回类标签转换成二值输出 巧妙地用np.where搞定"""

return np.where(self.net_input(X) >= 0, 1, -1)

 

 

“”“

补充关于zip

In [85]:X1

Out[85]: [1, 2, 3, 4, 5, 6]

In [86]: Y1

Out[86]: [1, 2, 3, 4, 5, 6]

In [87]: for i in zip(X1,Y1):

...: print(i)

...:

(1, 1)

(2, 2)

(3, 3)

(4, 4)

(5, 5)

(6, 6)

”“”

使用鸢尾数据测试感知器算法,利用抽取的鸢尾花数据来训练感知器,同时,绘制每次迭代的错误分类数量的折线图,以验证算法是否收敛并分开两种类型鸢尾花的决策边界:

>>> import pandas as pd

>>> import matplotlib.pyplot as plt

>>> from matplotlib.colors import ListedColormap

>>> import numpy as np

>>> 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 minclassifications')

>>> plt.show()

每次迭代对应的错误分类数量,以下图:

 

“”“

补充: plot

x = [1,2,3,4,5,6,7,8,9,10] y = [2,2,3,2,1,0,0,0,0,0]

plt.plot(x,y, marker='o') # 画折线图

”“”

能够看出分类器在第6次迭代后就已经收敛,而且具有对训练样本进行正确分类的能力。而后在实现对二维数据集决策边界的可视化:

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))

# 传入一维数组 更改成坐标矩阵 meshgrid https:// www.cnblogs.com/sunshinewang/p/6897966.html

Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T) # 分类器 感知器模型进行计算

Z= Z.reshape(xx1.shape) # 重塑 新的形状 但不改变数据

plt.contourf(xx1, xx2, Z, alpha=0.4, cmap = cmap) # 画三维等高线图 并对区域进行颜色填充

plt.xlim(xx1.min(), xx1.max()) # Get or set the x limits of the current axes.

plt.ylim(xx2.min(), xx2.max())

# 绘制分类样本

for idx, cl in enumerate(np.unique(y)):

# 画出散点图

plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1], alpha=0.8, c = cmap(idx), marker=markers[idx], label=cl)

 

“”“

np.meshgrid

Z.reshape

 

In [121]: xx1

Out[121]:

array([[3.3 , 3.32, 3.34, ..., 7.94, 7.96, 7.98],

[3.3 , 3.32, 3.34, ..., 7.94, 7.96, 7.98],

[3.3 , 3.32, 3.34, ..., 7.94, 7.96, 7.98],

...,

[3.3 , 3.32, 3.34, ..., 7.94, 7.96, 7.98],

[3.3 , 3.32, 3.34, ..., 7.94, 7.96, 7.98],

[3.3 , 3.32, 3.34, ..., 7.94, 7.96, 7.98]])

 

In [122]: xx2

Out[122]:

array([[0. , 0. , 0. , ..., 0. , 0. , 0. ],

[0.02, 0.02, 0.02, ..., 0.02, 0.02, 0.02],

[0.04, 0.04, 0.04, ..., 0.04, 0.04, 0.04],

...,

[6.04, 6.04, 6.04, ..., 6.04, 6.04, 6.04],

[6.06, 6.06, 6.06, ..., 6.06, 6.06, 6.06],

[6.08, 6.08, 6.08, ..., 6.08, 6.08, 6.08]])

In [125]: Z.shape

Out[125]: (305, 235)

In [126]: Z

Out[126]:

array([[-1, -1, -1, ..., -1, -1, -1],

[-1, -1, -1, ..., -1, -1, -1],

[-1, -1, -1, ..., -1, -1, -1],

...,

[ 1, 1, 1, ..., 1, 1, 1],

[ 1, 1, 1, ..., 1, 1, 1],

[ 1, 1, 1, ..., 1, 1, 1]])

”“”

>>> plot_decision_regions(X, y, classifier=ppn)

>>> plt.xlabel('sepal length [cm]')

>>> plt.ylabel('petal length [cm]')

>>> plt.legend(loc='upper left')

>>> plt.show()