摘要:本系列学习笔记将会详细记录 《Python Machine Learning Second Edition》学习过程。
神经网络概述
参考章节: Chapter 2: Artificial neurons – a brief glimpse into the early history of machine learning (P18
这里我们通俗的解释一下神经网络过程的直观原理:
目标:实际上神经网络的目标很简单,我们给定一组训练样本,每个训练样本有若干的特征,然后每个样本有实际的分类类别。我们的目标找出一个方程式,通过输入每个样本的特征值,最后得到分类结果和实际分类结果一致。
有点像解方程组,但是样本数量巨大,也就是多元方程组,很难求出解析解。
这里通过另外一种途径来实现,首先初始化一个方程,在没有样本的情况下,我们就认为这个方程是最后的目标,实际上如果没有样本,也就是没有任何信息的情况下,任意的方程都可以被认为是目标函数。
然后依次出入样本来检验我们的初始化函数,如果样本碰巧符合,那就继续下一个样本,如果样本结果不符合,我们就需要修正我们当前的目标函数,怎么修正,这个实际上是不确定的,这里给出一种方案,通过学习速率控制修正的尺度,修正的目标是让当前样本的结果符合实际,但是不能过激。
我们可以看出,这种方法可行的两个条件:
- 样本集合可以近似线性分类的,否则我们会发现需要不停的来回调整权值
- 学习速率尽可能小,否则同样会出现来回摇摆的情况。
神经网络感知机学习实现
Implementing a perceptron learning algorithm
算法实现
首先我们需要理解,算法实现中的约定,我们将下划线(_
)附加到属性,这些属性不是在对象初始化时创建的,而是通过调用对象的其他方法创建的,例如 self.w_
。
其次算法中语法的参考:
• NumPy: https://sebastianraschka.com/pdf/books/dlb/appendix_f_numpy-intro.pdf
• Pandas: https://pandas.pydata.org/pandas-docs/stable/10min.html
• Matplotlib: http://matplotlib.org/users/beginner.html
理解算法,我们先从其使用方法开始:
1 | df = pd.read_csv('https://archive.ics.uci.edu/ml/' 'machine-learning-databases/iris/iris.data', header=None) |
这里主要有两个步骤:
- 初始化:
ppn = Perceptron(eta=0.1, n_iter=10)
- 调用
fit
方法:ppn.fit(X, y)
输入的数据
首先我们看一下输入的数据:
X
:这是一个二维数组,其中使用了两个 feature,参考书第9页,也就是这里矩阵下标所表示的范围。一共有100个样本,也就是矩阵上标的范围, 矩阵可以表示为:
y
:是一个一维数组,表示样本的实际分类。
初始权值
算法的开始是初始化一组数据
1 | rgen = np.random.RandomState(self.random_state) |
这里 numpy.random.RandomState
是一个伪随机生成器,用于生成符合各种分布的随机数。通过这个生成器,我们初始化了 self.w_
权值数组。
Via the fit method, we initialize the weights in self.w to a vector »
m+1
, where m stands for the number of dimensions (features) in the dataset, where we add 1 for the first element in this vector that represents the bias unit. Remember that the first element in this vector, `self.w[0]`, represents the so-called bias unit that we discussed earlier.
rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
生成正态分布的随机数,loc
表示是分布的中心位置,scale
标准方差,用于描述分布的集中程度。最后一个参数表示输出的形态:X.shape[1]
是2, 这里生成了3个数,其中下标为0的数是 bias unit
。
什么是 bias unit
?
参考原书的第 19 页,这里详细介绍了 bias unit
的概念。书中描述的解释十分简单,一开始定义了预测的阈值,通过 阈值来进行分类,为了简单起见,在原来的决定方程中加入一项 $w_0x_0$,然后最后将阈值调整为 0,方便比较。其中加入的这一项就是偏置单元。在实现的时候,我们初始化 $w_0$ 的时候,多初始化了一个值,这个值就是这里的偏置单元。
根据这篇文章 神经网络中的偏置项b到底是什么? 我们知道这样做的还有另外一个原因就是,这个配置项也可以根据样本进行更新,从而在不同维度上更新。
使用样本修正权值
有了初始化的权值,下面就需要根据训练数据集来修正权值。
1 | for _ in range(self.n_iter): |
这段代码是算法的核心,对应的理论基础就是第21页的感知学习规则(perceptron learning rule)。感知学习规则的原理非常简单,只需要遵循两个规则:
- 初始化权值为 0 或者是一个很小的随机值
- 然后根据训练的样本 $x^{(i)}$,和代价函数,计算预测的分类,然后根据实际的分类和学习速率更新权值
通过第二个规则和大量的样本不断的迭代,从而获取到一组权值可以很好的对已知的样本进行正确的分类。
代码中为了保证所有 feature 的权值同时更新,首先定义了一个 update
: update = self.eta * (target - self.predict(xi))
,然后根据这个 update
来更新所有的权值 w_[]
。self.w_[1:]
表示是一个数组。也就是每个 feature
的权值都要使用 update
乘以 feature
值。然后还要更新 bias unit
。最后的 errors
为了统计每次迭代后预测值是否错误的结果,比如我们迭代10后,这个数组为 [1, 3, 3, 2, 1, 0, 0, 0, 0, 0]
,表明从第6次迭代就没有错误了,实际上当没有错误的时候,权值也就不会再更新了。
综合上面的分析,我们可以发现感知学习规则是非常简单的,其实现代码也很短,核心代码不超过30行。
数据处理 Pandas
下面我们根据这个具体的算法实现,再详细介绍一下,在实现算法是所涉及到的数据处理的技术,为以后学习奠定一定的基础。
从 CSV 中读取数据:
df = pd.read_csv('https://archive.ics.uci.edu/ml/' 'machine-learning-databases/iris/iris.data', header=None)
数据选择
1 | df = pd.read_csv('https://archive.ics.uci.edu/ml/' 'machine-learning-databases/iris/iris.data', header=None) |
X
从读取的数据集中截取需要的数据,0-100 行,0和2列。这样得到的 X
是一个2x100 的矩阵。