教程 | 初学者入门:如何用Python和SciKit Learn 0.18实现神经网络?

选自Springboard

作者:Jose Portilla

机器之心编译

参与:Jane W、吴攀

本教程的代码和数据来自于 Springboard 的博客教程。本文的作者为 Jose Portilla,他是网络教育平台 Udemy 一门数据科学类课程的讲师。

GitHub 链接:https://github.com/Rogerh91/Springboard-Blog-Tutorials/blob/master/Neural%20Networks%20/JMPortilla_SpringBoard_Blog_Neural_Network.ipynb

最受欢迎的 Python 机器学习库是 SciKit Learn。最新版本(0.18)支持神经网络模型。在本文中,我们将了解神经网络的工作方式以及如何使用 Python 编程语言和最新版本的 SciKit-Learn 来实现它们。了解这篇文章需要 Python 基础知识,而且它也有助于积累 SciKit Learn 的经验。

本文的代码及结果用 Jupyter Notebook 编写,In [*]: 代表输入的代码,Out[*]: 代表程序输出的结果。

神经网络

人工神经网络是一种模仿生物神经网络学习模式的机器学习框架:可以将它们粗略地近似为人类在学习中的思维活动。生物神经网络具有相互连接的神经元,神经元的树突结构接收输入,并基于这些输入产生输出信号,通过轴突传输到另一个神经元。我们将尝试通过人工神经网络(ANN,简称神经网络)来模拟这个过程。神经网络是深度学习的基础,它属于机器学习范畴,是当今最令人兴奋的技术进步之一。在利用 Python 创建神经网络之前,让我们先从最基本形式——单个感知器(perceptron)开始。下面是感知器的介绍。

感知器

一个感知器完整的结构包括一个或多个输入、偏置、激活函数和一个输出。感知器接收输入,并将它们与权重相乘,然后传递到激活函数以产生输出。有许多可能的激活函数可供选择,如 logistic 函数、三角函数、阶跃函数(step function)等。我们需要确保向感知器模型添加偏置(用来调整激活函数的位置),它是不受输入影响的常数型权重,能使预测模型的拟合效果达到最佳。下面的图表展示了感知器的结构:

一旦得到输出,我们可以将其与一个已知的标签进行比较,并相应地调整权重(开始时通常用随机数初始化权重值)。重复此过程,直到达到允许的最大迭代次数或可接受的错误率。

为了创建一个神经网络,我们可以从叠加多层感知器开始,创建一个神经网络的多层感知器模型。它包含了传入数据的输入层和产生结果的输出层。输入层和输出层之间的任何层都被称为隐藏层,因为它们不能直接「看到」数据的特征输入或输出。下图直观地反映了输入层、隐藏层和输出层的关系(来源:维基百科)。

由于神经网络的特点,神经网络在 GPU 上的表现往往比 CPU 好。可惜的是,SciKit-learn 框架不支持 GPU 加速优化。如果你想使用 GPU 和分布式模型,请参考其它框架,例如谷歌的开源框架 TensorFlow。

让我们继续用 Python 和 SciKit-learn 创建神经网络。

SciKit-Learn

本教程使用了最新版本的 SciKit-Learn(> 0.18),它可以通过 pip 或 conda 来轻松安装,也可以参考官方安装文档(http://scikit-learn.org/stable/install.html)获取完整的详细信息。

Anaconda 和 iPython Notebook

Anaconda 的 iPython Notebook(Jupyter Notebook)软件可以轻松地帮助你安装 SciKit-Learn 以及所需的所有工具。下面的链接中有如何安装这些软件的教程(https://www.safaribooksonline.com/blog/2013/12/12/start-ipython-notebook/),以便你快速在 Python 中构建神经网络。

数据

本文的分析主题为葡萄酒。葡萄酒伪劣品是一件非常现实的事情,让我们来看看 Python 的神经网络是否可以帮助解决这个问题。我们将使用 UCI 机器学习库中的葡萄酒数据集。它具有不同葡萄酒的各种化学特征,均在意大利同一地区生长,但数据标签分类为三种不同的品种。我们将尝试建立一个可以根据其化学特征对葡萄酒品种进行分类的神经网络模型。

数据集链接:https://archive.ics.uci.edu/ml/datasets/Wine

第一步,先导入数据

import pandas as pd
wine = pd.read_csv('wine_data.csv', names = ["Cultivator", "Alchol", "Malic_Acid", "Ash", "Alcalinity_of_Ash", "Magnesium", "Total_phenols", "Falvanoids", "Nonflavanoid_phenols", "Proanthocyanins", "Color_intensity", "Hue", "OD280", "Proline"])

查看数据结构:

In [9]:

wine.head()

Out[9] 为了符合本文的格式,我们截取了部分列(实际数据有更多列):

In [12]:

wine.describe().transpose()

Out[12]为了符合本文的格式,从输出中去掉了标准偏差(std)和计数列:

In [13]:

# 178 data points with 13 features and 1 label columnwine.shape

Out[13]:

(178, 14)

将数据的标签设置为 y: In [14]:

X = wine.drop('Cultivator',axis=1)
y = wine['Cultivator']

准备训练集和测试集

下面将数据分成训练集和测试集,这可以通过使用 SciKit-Learn 的 model_selection 中的 train_test_split 函数轻松完成: In [15]:

from sklearn.model_selection import train_test_split

In [16]:

X_train, X_test, y_train, y_test = train_test_split(X, y)

数据预处理

如果数据没有经过标准化,则神经网络可能在达到允许的最大迭代次数时仍未收敛。多层感知器对特征尺度(scale)敏感,因此强烈建议归一化数据。请注意,测试集采用相同的尺度变换才有意义。有很多不同的数据标准化方法,我们将使用内置的 StandardScaler 进行标准化。

In [17]:

from sklearn.preprocessing import StandardScaler

In [18]:

scaler = StandardScaler()

In [19]:

# Fit only to the training data
scaler.fit(X_train)

Out[19]:

StandardScaler(copy=True, with_mean=True, with_std=True)

In [20]:

# Now apply the transformations to the data:
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

训练模型

现在我们来训练模型。SciKit-learn 使用 estimator(估计量)对象。我们将从 SciKit-Learn 的 neural_network 库导入我们的估计量(多层感知器分类器模型/MLP)。

In [21]:

from sklearn.neural_network import MLPClassifier

接下来我们创建一个模型的实例,可以自定义很多参数,我们将只定义 hidden_layer_sizes 参数。此参数传入的是一个元组,表示计划在每个层的神经元数量,其中元组中的第 n 个元素表示 MLP 模型第 n 层中的神经元数量。有很多参数可供选择,但是为了简单起见,我们将选择具有相同数量神经元的 3 层神经网络,每层的神经元数量与数据的特征数相同(13),并将最大迭代次数设置为 500 次。

In [24]:

mlp = MLPClassifier(hidden_layer_sizes=(13,13,13),max_iter=500)

现在我们已经建立好模型,可以用训练集来拟合我们的模型,记住这些数据已被预处理和标准化:

In [25]:

mlp.fit(X_train,y_train)

Out[25]:

MLPClassifier(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9,
       beta_2=0.999, early_stopping=False, epsilon=1e-08,
       hidden_layer_sizes=(13, 13, 13), learning_rate='constant',
       learning_rate_init=0.001, max_iter=500, momentum=0.9,
       nesterovs_momentum=True, power_t=0.5, random_state=None,
       shuffle=True, solver='adam', tol=0.0001, validation_fraction=0.1,
       verbose=False, warm_start=False)

输出结果中给出了模型的其它参数的默认值。我鼓励你尝试这些参数的不同取值,看看它们对 Python 神经网络有什么影响。

In [26]:

predictions = mlp.predict(X_test)

现在我们可以用 SciKit-Learn 自带的评价指标,如分类报告(classification report)和混淆矩阵(confusion matrix)来评估模型的性能:

In [27]:

from sklearn.metrics import classification_report,confusion_matrix

In [28]:

print(confusion_matrix(y_test,predictions))
[[17  0  0]
 [ 0 14  1]
 [ 0  0 13]]

In [29]:

print(classification_report(y_test,predictions))
             precision    recall  f1-score   support

          1       1.00      1.00      1.00        17
          2       1.00      0.93      0.97        15
          3       0.93      1.00      0.96        13

avg / total       0.98      0.98      0.98        45

结果不错!看来测试集中我们只错误分类了 1 瓶葡萄酒!考虑到我们的 Python 神经网络的代码行很少,这个效果是非常好的。然而,多层感知器模型的缺点在于解释模型本身。例如,模型的权重和偏差与数据特征的关系以及哪些特征最重要将不容易解释。

如果想查看 MLP 训练模型得到的权重和偏差,使用 public 属性 coefs_ 和 intercepts_。

coefs_ 是权重矩阵的列表,其中索引 i 处的权重矩阵表示层 i 和层 i+1 之间的权重。

intercepts_ 是偏差向量的列表,其中索引 i 处的向量表示添加到层 i+1 的偏差值。

In [30]:

len(mlp.coefs_)

Out[30]:

4

In [31]:

len(mlp.coefs_[0])

Out[31]:

13

In [32]:

len(mlp.intercepts_[0])

Out[32]:

13

原文链接:https://www.springboard.com/blog/beginners-guide-neural-network-in-python-scikit-learn-0-18/

原文发布于微信公众号 - 机器之心(almosthuman2014)

原文发表时间:2017-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Coding迪斯尼

详解神经网络中的神经元和激活函数

1203
来自专栏机器之心

学界 | 谷歌论文新突破:通过辅助损失提升RNN学习长期依赖关系的能力

选自arXiv 机器之心编译 参与:李诗萌、黄小天 本文提出了一种简单的方法,通过在原始函数中加入辅助损失改善 RNN 捕捉长期依赖关系的能力,并在各种设置下评...

3685
来自专栏机器之心

自创数据集,使用TensorFlow预测股票入门

3947
来自专栏数据科学学习手札

(数据科学学习手札35)tensorflow初体验

  TensorFlow时谷歌于2015年11月宣布在Github上开源的第二代分布式机器学习系统,目前仍处于快速开发迭代中,有大量的新功能新特性在陆续研发中;

4166
来自专栏AI研习社

CS231n 课后作业第二讲 : Assignment 2(含代码实现)| 分享总结

CS231n 是斯坦福大学开设的计算机视觉与深度学习的入门课程,授课内容在国内外颇受好评。其配套的课后作业质量也颇高,因此雷锋网 AI 研习社在近期的线上公开...

48010
来自专栏深度学习自然语言处理

基于汉语短文本对话的立场检测系统理论与实践

汉语短文本对话立场检测的主要任务就是通过以对话的一个人的立场为主要立场,而判断另一个人针对该人的回话的立场。立场包括支持,反对,中立三种立场。基于对话的立场检测...

1561
来自专栏有趣的Python

2- 深度学习之神经网络核心原理与算法-提高神经网络学习效率

上一章我们介绍了基本的前馈神经网络的实现。 本节我们来介绍一些可以提高神经网络学习效率的方法。 并行计算 加快神经网络训练最直接的方式。我们需要得到的是一个网络...

63113
来自专栏H2Cloud

隐马尔科夫-维特比算法

概念介绍:   继上篇贝叶斯(https://cloud.tencent.com/developer/article/1056640)后,一直想完成隐马尔科夫这...

3506
来自专栏杨熹的专栏

Machine Learning Notes-Linear Regression-Udacity

什么是 Regression? Regression 就是想找到因变量和自变量之间的关系,用一个函数来表示,并且可用这个函数来预测任意一个新的 x 会有怎样的 ...

3554
来自专栏数据结构与算法

P1038 神经网络

题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域...

3418

扫码关注云+社区

领取腾讯云代金券