自己设计一个感知机实现二分类算法

实现一个简单的神经网络,做一个简单的二分类算法。为了理解神经网络,我们应该先理解神经网络的组成单元——神经元。神经元也叫做感知器。感知器算法在上个世纪50-70年代很流行,也成功解决了很多问题。并且,感知器算法也是非常简单的。在人工神经网络领域中,感知器也被指为单层的人工神经网络,以区别于较复杂的多层感知器(Multilayer Perceptron)。 作为一种线性分类器,(单层)感知器可说是最简单的前向人工神经网络形式。尽管结构简单,感知器能够学习并解决相当复杂的问题。感知器主要的本质缺陷是它不能处理线性不可分问题。
感知器有如下组成部分:
输入权值 激活函数 输出
以下程序切实实现权值更新,根据误差结果更新迭代,并且观察每次迭代后误差变化,网络趋于收敛。并且对测试集结果进行二分类,并且用可视化图片展示。
其中,在处理过程中,对python类概念、以及多个第三方库有一定了解,比如numpy、matplotlib等。
1.创建一个类作为分类器,可处理更新权重信息、记录误差信息

class AdalineG(object):    
    """    
    eta:float    
    学习效率,处于0和1之间        
    n_iter:int    对训练数据进行学习改进次数        
    w_:一维向量    
    存储权重数值        
    error_:    存储每次迭代改进时,网络对数据进行错误判断的次数    
    """            
    def __init__(self,eta=0.01,n_iter=50):        
        self.eta = eta        
        self.n_iter = n_iter            
    def net_input(self, X):        
        return np.dot(X, self.w_[1:]) + self.w_[0]        
    def activation(self, X):        
        return self.net_input(X)       
    def predict(self, X):        
        return np.where(self.activation(X) >=0, 1, -1)        
    def fit(self, X, y):        
        """        
        X:二维数组[n_sampls, n_features]        
        n_samples 表示X中含有训练数据条目数        
        n_faetures 含有4个数据的一维向量,用于表示一条训练条目                
        y:一维向量        
        用于存储每一训练条目对应的正确分类        
        """     

        self.w_ = np.zeros(1 + X.shape[1])        
        self.cost_ = []                
        for i in range(self.n_iter):            
            output = self.net_input(X)            
            errors = (y-output)            
            self.w_[1:] += self.eta * X.T.dot(errors)            
            self.w_[0] += self.eta * errors.sum()            
            cost = (errors ** 2).sum() /2.0            
            self.cost_.append(cost)        
        return self

2.准备训练的数据集信息
https://pan.baidu.com/s/17dK9fdGHzGY1SfI-s1pt6w(有小哥哥提供数据信息xlsx格式)

file="iris1.xlsx"
import pandas as pd
#header为none目的表示第一行并不是头文件信息,并且读入
df=pd.read_excel(file,header=None)
import matplotlib.pyplot as plt
import numpy as np
y=df.loc[0:99,4].values
#对第四列数据信息进行处理,并且将其结果作为真实分类结果。
y=np.where(y=="Iris-setosa",-1,1)
#只需要第0列和第2列数据作为数据集
X=df.iloc[0:100,[0,2]].values

3.更新权重,渐进下降。

ada = AdalineG(eta=0.0001, n_iter=50)
ada.fit(X, y)
#以上用来更新权重,获取一个最新的权重值,作为分类器

4.准备测试集数据进行测试、展示二分类测试结果

from matplotlib.colors import ListedColormap
#resolution划分数据的步长
def plot_decision_regions(X, y, classifier, resolution=0.02):   
    #数据描点的形状,具体可见画图方法 
    marker = ('s', 'x', 'o', 'v')    
    #数据点的颜色
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')  
    #根据数据种类选择形状和颜色,例如我们只有两类-1和1,只选择前两个红色和蓝色  
    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()    
    #将x1、x2最大最小值通过arange函数得到的向量,扩展成两个二维矩阵    
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))    
    #预测(y=-1/1) 
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T) #ravel还原成单维向量    
    #绘制    
    Z= Z.reshape(xx1.shape) #将Z转换成与xx1一样的二维数组    
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap) #在两组分类结果中间画分割线-->必须线性可分    
    #x,y轴信息结果
    plt.xlim(xx1.min(), xx1.max())    
    plt.ylim(xx2.min(), xx2.max())    
    #plot和scatter本质上没有区别画图2d
    #按照分类最终结果绘图
    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=marker[idx], label=cl)

5.输入数据、进行测试,可视化展示结果

plot_decision_regions(X, y, classifier=ada)
#数据的填充,增加数据,进行测试
plt.title('Adaline-Gradient descent')
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('花茎长度')
plt.ylabel('花瓣长度')
plt.legend(loc='upper left')
plt.show()

结果如图所示:
这里写图片描述
6.打印模型对数据判断的错误次数(逐渐迭代网络收敛过程)
在之前训练过程中,错误结果已保存

plt.plot(range(1, len(ada.cost_)+1), ada.cost_, marker='o')
plt.xlabel('Epochs(迭代次数)')
plt.ylabel('sum-squard-error')
plt.show()

结果如图所示:
这里写图片描述
整个过程,自己手敲一遍,即深刻了印象,也了解了基本原理,一步一步往前走啦。

猜你喜欢

转载自blog.csdn.net/ll_master/article/details/81662295
今日推荐