神经网络在多分类上的应用——数据预处理

神经网络在多分类上的应用——数据预处理部分

标签: 神经网络 多分类


  • 首先建立思路,然后在实行过程中根据需求找方法和工具。
  • 本文以用三层神经网络识别给定的图片是人,猫还是狗项目为例,记录实现过程中的思路,遇到的难点和多次的调整。


数据预处理

主要工具:pandas matplotlib seaborn numpy sklearn

  • 项目已给定经过预处理后较小的数据集data.csv,数据集中仅含提取的图像的特征结果。数据集部分如下面表格形式:
feature1 feature2 feature3 feature4 class
5.1 1400 1.4 2 0
4.9 1200 1.4 2 0
4.7 1280 1.3 2 0

[数据集描述]

数据集含有4个特征每个输入的x向量有4个坐标;每行代表一个图像;class代表图像的类别:有三种情况——0代表是人,1代表是猫,2代表是狗

[加载数据]

使用pandas包读取data文件为DataFrame格式。

dataset = pd.read_csv('data.csv')

[数据集随机化]

由表格可以看出,数据集仍需要进一步处理:
数据集是按类别分类后按顺序依次排列的,需要将其打乱。
已知python自带有shuffle方法,这里dataset为DataFrame格式,可以使用pandas中设定抽取比例为1时的sample方法。

# 打乱后索引仍按照正常的排序
dataset = dataset.sample(frac=1).reset_index(drop=True)   

[数据分析——数据可视化]

使用matplotlib包和seaborn工具绘制数据图,直观分析它们之间的关系和数据的特点。

matplotlib

  1. 选取feature1和feature2作为二维图像的横纵坐标;
  2. 分别取出类别为人,猫和狗时的二维特征数组;
  3. 分别绘制不同颜色的散点图,注意这三种类别的数据点应该体现在一张二维图像上。

代码如下:

def plot_points(dataset):
    X = np.array(dataset[["feature1", "feature2"]])  # X保存特征,先绘制二维图(选取feature1和feature2)
    y = np.array(dataset["class"])  # y保存类别

    people = X[np.argwhere(y == 0)]  # 取出图片为人时的特征值数组
    cat = X[np.argwhere(y == 1)]  # 取出图片为猫时的特征值数组
    dog = X[np.argwhere(y == 2)]  # 取出图片为狗时的特征值数组

    # 对于类别为人,猫,狗,分别绘制不同颜色的数据点——对应于同一张二维坐标图
    plt.scatter([s[0][0] for s in people], [s[0][1] for s in people], s=25, color='red', edgecolor='k')
    plt.scatter([s[0][0] for s in cat], [s[0][1] for s in cat], s=25, color='cyan', edgecolor='k')
    plt.scatter([s[0][0] for s in dog], [s[0][1] for s in dog], s=25, color='yellow', edgecolor='k')

    plt.xlabel('Feature_1')
    plt.ylabel('Feature_2')


plot_points(dataset)
plt.show()  # 绘制散点图

绘制图像如下:

matplotlib绘制二维特征散点图

  • 由上图可以看出仅依据两个特征并不能很好地分离图片类别。

seaborn

  1. 使用seaborn中的pairplot函数绘制多变量图——如本项目中特征有四个维度;
  2. 若pairplot的变量参数有n个,则会绘制n*n的方格。当i=j时,为直方图;i≠j时,为散点图;
  3. 仍然使用matplotlib的显示函数来显示图像。

代码如下:

import seaborn as sns  # seaborn作为matplotlib的补充,导入后会覆盖matplotlib的默认作图风格

sns.pairplot(dataset, hue='class', vars=["feature1", "feature2", "feature3", "feature4"])  # hue : 使用指定变量为分类变量画图;vars : 与data使用,否则使用data的全部变量
plt.show()  # 仍然使用matplotlib的显示函数

绘制图像如下:

seaborn绘制四维特征散点图

  • 根据四个特征维度,图像的类别得到了很好地分离

[数据分离——将数据集拆分为输入和标签]

在训练神经网络时,训练集的数据要分开使用:输入每个数据的n维特征,得到神经网络的输出结果,并将该结果与训练集中的类别[标签]来对比,构造误差函数等,从而利用梯度下降算法对神经网络的模型进行优化。

可以使用pandas包中的ilocloc属性,其中

  1. loc是根据DataFrame的行、列标签名来进行选取,可以选取单个元素,也可以选取一个区域
  1. iloc是根据DataFrame的行、列索引来进行选取,可以选取单个元素,也可以选取一个区域

代码如下:

data = dataset.iloc[0: 150, 0: 4]  # 输入
# print(data)
label = dataset.iloc[0: 150, 4]  # 标签
# print(label)

[数据标准化]

有时输入数据的几个特征(维度)所在的数值范围是不一致的,这意味着数据存在偏差,不利于神经网络的处理,需要将所有特征的值规划到同一数值范围内。

处理方法:一般将大的特征值缩小,可使用(x-min)/(max-min)规划到[0,1]的范围内。

本例代码:

data['feature2'] = (data['feature2'] - data['feature2'].min()) / (data['feature2'].max() - data['feature2'].min())
data['feature4'] = (data['feature4'] - data['feature4'].min()) / (data['feature4'].max() - data['feature4'].min())

[将类别(标签)进行One-hot编码]

  1. 原始训练集的类别为0,1,2,不容易进行神经网络的训练,需要对标签进行One-hot编码;即有n种类别便将每个图像的标签转化为n维向量,只有其对应正确类别的索引下的值为1,其余为0。
  1. 本项目是一个三分类问题,类别(离散特征)的取值之间没有大小关系,可以使用One-hot编码。[若有大小关系则采用数值映射的方式]
  2. 将标签进行One-hot编码后,可以对应softmax函数概率分布意义,得到神经网络的预测结果并进行误差分析。

使用pandas库中的get_dummies方法进行One-hot编码:

one_hot_label = pd.get_dummies(label)

得到编码后的部分标签如下:

One-hot编码后的标签

训练数据集和测试数据集的划分

  • 为防止过拟合,需要将给定的数据集按一定的比例划分为训练集和测试集:训练集用于得到优秀的神经网络模型,测试集用于测试神经网络的泛化能力。
  • 数据集划分的比例和组成不同也会对神经网络模型产生一定的影响

有很多方式可以进行数据集的随机划分:

  1. 使用numpy.random.choice
  2. 使用sklearn.model_selection.train_test_splitsklearn.cross_validation.train_test_split,其中cross_validation指交叉验证

这里使用第2种方式:

from sklearn.cross_validation import train_test_split

# 使用sklearn.cross_validation.train_test_split方法,暂取随机数种子为1,以在重复试验时,得到相同的随机数组
train_data, test_data, train_label, test_label = train_test_split(data, label, test_size=0.3, random_state=1)
posted @ 2019-01-24 21:54  Sandrammm  Views(6972)  Comments(0Edit  收藏  举报