单层神经网络线性分类山鸢尾和杂色鸢尾

选择花萼长度 花瓣长度作为特征,使用梯度下降,求取和方差的最小值,使得误差最小

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
from matplotlib.colors import ListedColormap

#显示训练数据
def plot_decision_regions(x,y,classifier,resolution=0.02):
    marker = ('s','x','o','v')
    colors = ('red','blue','lightgreen','gray','cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])#np.unique 去除重复的数据

    #获取花萼长度 花瓣长度的最小值和最大值
    x1_min,x1_max = x[:,0].min()-1,x[:,0].max()
    x2_min,x2_max = x[:,1].min()-1,x[:,1].max()

    #向量转二维矩阵                矩阵行                              矩阵列
    # 输入的x,y,就是网格点的横纵坐标列向量(非矩阵)   -----》 x,y组合成网格点
    # 输出的X,Y,就是坐标矩阵
    xx1,xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),np.arange(x2_min,x2_max,resolution))#返回list,有两个元素,第一个元素是X轴的取值,第二个元素是Y轴的取值
    z = classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T) #ravel()矩阵转数组

    z = z.reshape(xx1.shape)
    plt.contourf(xx1,xx2,z,alpha=0.4,cmap=cmap)    #等高图

    print(len(np.arange(x1_min,x1_max,resolution)))#185
    print(len(np.arange(x2_min,x2_max,resolution)))#255
    print('xx1shape:',xx1.shape)                   #(255, 185)
    print('xx2shape:',xx2.shape)                   #(255, 185)
    print('zshape:', z.shape)                      #(255, 185)    [(x10,x20),(x11,x20),(x13,x20)...]
    print(xx2)
    print('z:',z)
    plt.xlim(xx1.min(),xx1.max())
    plt.ylim(xx2.min(),xx2.max())

    print(np.unique(y))            #[-1,1]
    #绘制训练数据的散点图
    for idx,label in enumerate(np.unique(y)):
        print(idx,label)
        print(x)
        plt.scatter(x=x[y == label,0],y = x[y == label,1],alpha=0.8,c=cmap(idx),marker=marker[idx],label=label)#x:特征1  y:特征2

class AdalineGD(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 fit(self,X,y):
        '''
        X 二维数组 【n_sample,n_features】
        n_sample  X 中含有训练数据的条目
        features  含有4个数据的一维向量,表示一条训练条目
        y:一维向量 用于存贮每一训练条目对应的正确分类
        y = w1*x1+w2*x2+W0*1
        '''
        self.w_ = np.zeros(1+X.shape[1])
        self.const = []   #训练的次数
        self.cost_ = []   #损失
        for i in range(self.n_iter):
            output = self.net_input(X)  #输入数据加权 , 加w0
            #output = w0 + w1*x1 + ... +wmxm
            # print(output.shape)
            # print(y.shape)
            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)
            if cost > 5:                   #误差平方和的均值 >5,累计加一
                if len(self.const) == 0:
                    self.const.append(1)
                else:
                    self.const.append(self.const[-1]+1)
            else:
                if len(self.const) == 0:
                    self.const.append(1)
                else:
                    self.const.append(self.const[-1])

    #加权求和
    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):
        print('predict:',x)
        return np.where(self.activation(x) >= 0 ,1,-1)

if __name__ == '__main__':
    # 数据集  http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data
    # 花萼长度 花萼宽度 花瓣长度 花瓣宽度 类别(Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾)、Iris Virginica(维吉尼亚鸢尾))

    #加载数据
    file = './datasets/iris.data.txt'
    df = pd.read_csv(file, header=None)      # 第一行不是数据说明,是真实数据
    df.head()

    #提取特征数据,标签
    y = df.loc[0:99, 4].values               # 前100行的第5列
    print('y:',y.shape)
    print(y)
    y = np.where(y == 'Iris-setosa', 1, -1)  # np.where(条件, x, y)  条件为True,输出x,不满足输出y
    x = df.iloc[0:100, [0, 2]].values        # 获取花萼长度 花瓣长度特征
    plt.scatter(x[:100, 0], x[:100, 1], color='red', marker='o', label='setosa')  # marker形状  花萼长度为横轴,花瓣长度为纵轴
    plt.xlabel('x1')
    plt.ylabel('x2')
    plt.xticks(rotation=45)#倾斜45
    plt.title('训练数据')
    plt.legend(loc='upper left')
    #系统字体
    # matplotlib.matplotlib_fname()  # 将会获得matplotlib包所在文件夹
    # 指定默认字体
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']
    matplotlib.rcParams['font.family'] = 'sans-serif'
    # 解决负号'-'显示为方块的问题
    matplotlib.rcParams['axes.unicode_minus'] = False
    plt.show()

    #训练
    ada = AdalineGD(eta=0.0001,n_iter=1000)
    ada.fit(x,y)                              #训练
    plot_decision_regions(x,y,classifier=ada) #classifier 分类器
    plt.show()

    # 错误的次数
    plt.title('错误的次数')
    plt.plot(range(1,len(ada.const)+1),ada.const,marker='o')
    plt.show()

    #误差平方和
    plt.title('误差')
    plt.plot(range(1,len(ada.cost_)+1),ada.cost_,marker='o')
    plt.show()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值