美文网首页
菜鸟笔记Python3——机器学习(一) :感知机模型

菜鸟笔记Python3——机器学习(一) :感知机模型

作者: 灵玉真人 | 来源:发表于2017-06-08 09:13 被阅读0次

参考资料

<PYTHON_MACHINE_LEARNING> chapter2
Training Machine Learning Algorithms for Classifcation

引言:

在第一章初步介绍了三种类型的机器学习以及他们的各自的特点后,在本章,我们将学习第一类神经网络(监督式学习),并用Python搭建出一个简单的二元分类的神经网络单元,用于在鸢尾花的数据集Iris dataset中分类出花的种类,在本章的学习中我们需要做到以下三点
**
• Building an intuition for machine learning algorithms
• Using pandas, NumPy, and matplotlib to read in, process, and visualize data
• Implementing linear classifcation algorithms in Python**

友情提示:需要现行接触一下 numpu pandas 的基本函数
本人就是没有接触过所以为了看懂代码花了很久_(:3」∠)

section 1: 人工神经单元以及二分类线性模型

感知机的Novikofff定理


神经元模型

人工神经单元参考了神经元的设计
输入信号
![](http://latex.codecogs.com/png.latex?x~=[x_1,x_2,x_3......x_n] ~is ~the input signal\ \ ~~\omega=[\omega_1,\omega_2,\omega_3......\omega_n] ~is ~the weight function)
![](http://latex.codecogs.com/png.latex?z ~~ =\sum_{i=1}^n\omega_i*x_i)
激励函数(输出)
激励函数(activation function)中,对输进行了加权求和之后的net_input,如果大于指定的阈值θ,则输出为1,否则为-1

稍微修改一下 令


这样我们输入一组信号x,输出的信号被分成了两类,这就是分类算法的原理


权值的更新法则如下



举个例子



现在,基本的原理已经交代完毕,我们可以用Python实现了

section 2: Python 实现

step 1: Perceptron 类

首先,我们建立一个二元划分的类,方便以后调用,这个类应该包含一个更新权值并统计误差的方法,一个计算加权求和net_input的方法,以及一个用激励函数判断输出的方法,包含一个属性权值属性,一个误差属性,我们在一个文件中单独编写这个类
书上的代码写得很详细,我加入了一些额外的注释

__author__ = 'Administrator'
#! /usr/bin/python <br> # -*- coding:utf8 -*-
import numpy as np
class Perceptron(object):
    """
    Perceptron classifier.
    Parameters(参数)
    ------------
    eta : float
    Learning rate (between 0.0 and 1.0) 学习效率
    n_iter : int
    Passes over the training dataset(数据集).
    Attributes(属性)
    -----------
    w_ : 1d-array
    Weights after fitting.
    errors_ : list
    Number of misclassifications in every epoch(时间起点).
    """

    def __init__(self, eta=0.01, n_iter=10):
        self.eta = eta
        self.n_iter = n_iter
    def fit(self, X, y):
        '''
    Fit training data.
    Parameters
    ----------
    X : {array-like}, shape = [n_samples, n_features] X的形式是列矩阵
    Training vectors, where n_samples is the number of samples
    and n_features is the number of features.
    y : array-like, shape = [n_samples]
    Target values.
    Returns
    -------
    self : object
'''
        self.w_ = np.zeros(1 + X.shape[1])
        # zeros()创建了一个 长度为 1+X.shape[1] = 1+n_features 的 0数组
        #初始化权值为0
        # self.w_ 权向量
        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 #更新权值,x0 =1
                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)

step 2: 读取数据集,调用类,绘图

我们在主文件中编写下面的代码

__author__ = 'Administrator'
#! /usr/bin/python <br> # -*- coding: utf8 -*-
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from perceptron import Perceptron
from PDC import plot_decision_regions
import requests

#从url下载文件
filename = 'Iris.csv'
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
# urllib.request.urlretrieve(url, filename)

df = pd.read_csv(filename,header=None)# 返回一种DataFrame结构文件,DataFrame,pandas中的一种数据结构
print(df.tail())                    # 验证是否读取正确

#.iloc[0:100,4] 读取前100行的序号为4(第5列数据)
y = df.iloc[0:100, 4].values # .values将dataframe中的值存进一个list中
y = np.where(y=='Iris-setosa',-1,1) #如果是 Iris-setosa y=-1否则就是1 (二元分类)

X = df.iloc[0:100,[0,2]].values

#.iloc[0:100,[0:2]] 读取前100行的 前两列的数据

plt.scatter(X[:50,0],X[:50,1],c='red',marker='o',label='setosa')
plt.scatter(X[50:100,0],X[50:100,1],c='blue',marker='x',label='versicolor')
plt.xlabel('sepal length')
plt.ylabel('petal length')
plt.legend(loc='upper left')
plt.show()

可以看出 数据十分鲜明的被分成了两类


step 3: 调用Perceptron类 进行学习

我们在主文件中继续追加如下代码

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('Epoches')
plt.ylabel('Number of misclassification')
plt.xlim(1,10)
plt.savefig('Number of misclassification-Epoches.png',bbox_inches='tight')
plt.show()

可以看到,误差收敛到0了,说明学习的效果很好

step 4 :可视化

我们在一个文件中单独编写一个函数,把数据可视化

__author__ = 'Administrator'
#! usr/bin/python <br> # -*- coding:utf8 -*-

from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import numpy as np
from perceptron import Perceptron
def plot_decision_regions(X, y, classifier, resolution=0.02):
    #setup marker generator and colormap
    markers = ('o','x','s','^','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
    # X[:,k] 冒号左边表示行范围,读取所有行,冒号右边表示列范围,读取第K列
    xx1, xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),
                           np.arange(x2_min,x2_max,resolution))
    #arange(start,end,step) 返回一个一维数组
    #meshgrid(x,y)产生一个以x为行,y为列的矩阵
    #xx1是一个(305*235)大小的矩阵 xx1.ravel()是将所有的行放在一个行里面的长度71675的一维数组
    #xx2同理
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T) #我们其实调用predict()方法预测了grid矩阵当中的每一个点
    #np.array([xx1.ravel(), xx2.ravel()]) 生成了一个 (2*71675)的矩阵
    # xx1.ravel() = (1,71675)
    #xx1.shape = (305,205) 将Z重新调整为(305,205)的格式
    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())

    # plot class samples
    print(np.unique(y))
    # idx = 0,1 cl = -1 1
    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)

在主程序中调用它

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

应用

书中的训练集包含Iris.csv文件中两种花所有的样本,为了让我们这个神经网络模型的分类效果更明显,我们选取一部分样本作为训练集,另一部分样本作为预测的数据
在主程序中,我们做出这样的更改

#更改训练集
#更改训练集
y1 = df.iloc[0:30, 4].values # .values将dataframe中的值存进一个list中
x1 = df.iloc[0:30,[0,2]]
y2 = df.iloc[80:100, 4].values
x2 = df.iloc[80:100,[0,2]]
y = np.hstack((y1,y2)) # 水平追加
X = np.vstack((x1,x2)) #竖直追加
y = np.where(y=='Iris-setosa',-1,1) #如果是 Iris-setosa y=-1否则就是1 (二元分类)
X2 = df.iloc[30:60,[0,2]].values

抓取20个第一类花的样本以及10个第二类花的样本组成训练集
训练

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

预测

#预测
print(ppn.predict(X2))
plot_decision_regions(X,y,classifier=ppn)
plt.scatter(X2[0:20:,0], X2[0:20,1],c='g')
plt.scatter(X2[21:30:,0], X2[21:30,1],c='w')
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc = 'upper left')

# plt.savefig(' decision_regions.png')
plt.show()

这里用到了矩阵的切片

X2[0:20:,0]

表示 X2 的第0到第20行,所有列 中的第0列
我们看一看预测的结果



跟预计的相同,说明神经网络分类的效果很好

相关文章

网友评论

      本文标题:菜鸟笔记Python3——机器学习(一) :感知机模型

      本文链接:https://www.haomeiwen.com/subject/pwjzfxtx.html