机器学习—神经网络之感知器

sunmengqi    2018-03-21 15:45

    感知器算法基于单层神经网络的范畴,不仅是第一个以算法描述的学习算法,而且很直观,也较为容易实现。同时,它也是是最先进的机器学习算法之一——人工神经元网络(也可称作“深入学习”)的绝好切入点。

    感知器的最初概念可以追溯到Warren McCulloch和Walter Pitts在1943年的研究,他们将生物神经元类比成带有二值输出的简单逻辑门。以更直观的方式来看,神经元可被理解为生物大脑中神经网络的子节点。在这里,变量信号抵达树突。输入信号在神经细胞体内聚集,当聚集的信号强度超过一定的阈值,就会产生一个输出信号,并被树突传递下去。

    感知器属于监督学习算法类别,更具体地说是单层二值分类器。简而言之,分类器的任务就是基于一组输入变量,预测某个数据点在两个可能类别中的归属。

    感知器分类算法的适用范围:数据可以线性划分(即第一种)

   

    最初的感知器规则相当简单,可总结为下面两步:

  1.    将权值初始化为0或小随机数。

  2.    对每一个训练样本x^i:

                                         (1) 计算输出值。

                                         (2) 更新权值。

    感知器数据分类算法步骤如下:

    其步调函数与阈值设定如下:

    其权重更新和阈值更新过程:

    通过结合网络中一个花朵花瓣与花径长度的数据,使用python将感知器算法进行初步实现,使用部分数据对感知器进行训练。

    (注:这里笔者使用的是Anaconda平台中Jupyter Notebook的进行编码)

    

import numpy as np
class Perceptron(object):
    """
    eta:学习率
    n_iter:权重向量的训练次数
    w_:神经分叉权重向量
    errors_:记录神经元判断出错次数
    """
    def __init__(self,eta = 0.01,n_iter=10):
        self.eta=eta
        self.n_iter=n_iter
        pass
    def fit(self,x,y):
        """
        输入训练数据,训练神经元
        x为输入样本向量,y为样本分类
        x:shap[n_samples,n_features]
        例如:x:[[1,2,3],[4,5,6]]
                n_samples=2,n_features=3
            y:[1,-1]第一个样本分类为1,第二个分类为-1
       """
        """
        初始化权重向量为0
        加一是因为w0是步调函数(激活函数)的阈值
        """
        self.w_=np.zeros(1+x.shape[1])
        self.errors_=[]
        for _ in range(self.n_iter):
            errors=0
            """zip(x,y)=[[1,2,3,1],[4,5,6,-1]]"""
            for xi,target in zip(x,y):
                """
                阈值更新
                update = eta * (y-y')
                """
                update=self.eta * (target - self.predict(xi))
                """
                权重更新
                xi是一个向量
                w_忽略第一个元素,第一个元素w_[0]为阈值
                """
                self.w_[1:] += update*xi
                """更新阈值"""   
                self.w_[0] += update
                errors+=int(update !=0.0)
                self.errors_.append(errors)
                pass
            
            pass
    def net_input(self,x):
        """z=w0*1+w1*x1+...+wn*xn"""
        return np.dot(x,self.w_[1:])+self.w_[0]
        
    def predict(self,x):
        return np.where(self.net_input(x) >=0.0,1,-1)

    上述代码是感知器的实现部分,其中方法fit( )为核心部分。

    下面导入数据:

file="https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
import pandas as pd
"""没有文件头,即数据说明,所以header = None"""
df = pd.read_csv(file,header = None)
"""显示数据文件的前十行"""
df.head(10)

    显示前十行为例,可以清晰看出数据的内容:

     下面进行数据可视化,得到前100行数据的分布情况:

"""数据可视化"""
import matplotlib.pyplot as plt
import numpy as np
"""抽取数据的第四列赋值给y"""
y = df.loc[0:100, 4].values
y = np.where(y =='Iris-setosa',-1,1)
X = df.iloc[0:100,[0,2]].values

plt.scatter(X[:50,0],X[:50,1],color='red', marker='o',label='setosa')
plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='versicolor')
plt.xlabel('Petal length')
plt.ylabel('Length of flower diameter')
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('Error classification times')
from matplotlib.colors import ListedColormap
def plot_decision_regions(X,y,classifier, resolution=0.02):
    marker = ('s','x','c','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()
    x2_min, x2_max = X[:, 1].min() -1, X[:, 1].max()
    
    '''将二维向量扩展成为矩阵'''
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                          np.arange(x2_min, x2_max, resolution))
    '''变量z存储训练后的神经元进行判断的结果'''
    z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    z = z.reshape(xx1.shape)#将z重新按照xx1的格式排列
    plt.contourf(xx1, xx2, z, alpha=0.4, cmap=cmap)#绘制分界线
    plt.xlim(xx1.min(), xx1.max())#x轴的起始节点和结束节点
    plt.ylim(xx2.min(), xx2.max())#y轴的
    plt.scatter(X[:50,0],X[:50,1],color='red', marker='o',label='setosa')
    plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='versicolor')
    plt.xlabel('Petal length')
    plt.ylabel('Length of flower diameter')
    plt.legend(loc='upper left')
plot_decision_regions(X,y,ppn, resolution=0.02)

plt.show()

    最后得到结果:一条清晰的分界线

**该博客仅代表笔者在机器学习部分初步学习了解的内容,有错误和不清楚的地方在所难免,如有错误和不足请大家指正,我们可以一起探讨学习,共同进步!**

**感谢**

Views: 2.3K

[[total]] comments

Post your comment
  1. [[item.time]]
    [[item.user.username]] [[item.floor]]Floor
  2. Click to load more...
  3. Post your comment