美文网首页
菜鸟笔记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