机器学习近年来成为热门话题,每天都有新的应用和模型涌现。全球的研究人员不断公布新的实验成果,展示了机器学习领域的显著进步。
许多技术工作者通过参加各种课程和搜集资料,希望利用这些新技术改进他们的项目。然而,要真正理解和应用机器学习,往往需要深厚的数学背景,这使得那些虽具备良好算法技能但数学基础薄弱的程序员面临挑战。
本书第一章概述了机器学习的主要研究领域,并简要介绍了基本的统计学、概率论和微积分。书中还提供了示例代码,帮助读者通过实验理解和应用这些理论。
1.3 基本数学概念
本书主要面向希望掌握机器学习算法的开发人员。为了理解这些算法背后的原理和理论,我们需要重温并建立所有基本推理知识体系,包括统计学、概率论和微积分。
接下来,我们从一些基础的统计概念开始。
1.3.1 统计学——不确定性建模的关键支柱
统计学是一种通过数据样本提取结论的学科。考虑到机器学习是对数据属性和赋值进行研究的重要部分,本书将广泛运用统计概念来定义和验证不同的方法。
描述性统计学——主要操作
首先,我们将定义统计学的基本操作和方法,并介绍一些基本概念。
(1)平均值(Mean)
平均值是统计学中最直观、常用的概念之一。给定一组数字,该集合的平均值是所有元素之和除以元素数量。
平均值的公式如下:
$$text{平均值} = frac{sum x_i}{n}$$
尽管这是一个简单的概念,本书还是提供了一个Python代码示例。在这个示例中,我们将创建一个数据集,并用线图表示它,将整个集合的平均值标记为线,这条线应位于样本的加权中心。它既可用于介绍Python语法,也可作为Jupyter Notebook的实验。代码如下:
```python import matplotlib.pyplot as plt
def mean(sampleset): total = 0 for element in sampleset: total += element return total / len(sampleset)
myset = [2., 10., 3., 6., 4., 6., 10.] mymean = mean(myset) plt.plot(myset) plt.plot([mymean] * 7) ```
该程序将输入数据集元素的时间序列,然后在平均高度上绘制一条线。
如图所示,平均值是描述样本集趋势的一种简洁方式。
(2)方差(Variance)
平均值不足以描述非均匀或非常分散的样本数据。为了用一个独特的值来描述样本值的分散程度,我们需要引入方差的概念。方差需要以样本集的平均值为基点,然后计算样本值到平均值的距离的平均值。方差越大,样本集越分散。
方差的定义如下:
$$text{方差} = frac{sum (x_i - bar{x})^2}{n}$$
下面使用之前使用的库编写示例代码来解释这个概念。为了清晰起见,这里重复了mean函数的声明。代码如下:
```python import math
def mean(sampleset): total = 0 for element in sampleset: total += element return total / len(sampleset)
def variance(sampleset): total = 0 setmean = mean(sampleset) for element in sampleset: total += math.pow(element - setmean, 2) return total / len(sampleset)
myset1 = [2., 10., 3., 6., 4., 6., 10.] myset2 = [1., -100., 15., -100., 21.]
print("方差1: " + str(variance(myset1))) print("方差2: " + str(variance(myset2))) ```
后面的代码将输出以下结果:
方差1: 8.69387755102
方差2: 3070.64
如结果所示,当样本值非常分散时,第二组的方差要高得多。
(3)标准差(Standard Deviation)
标准差是对方差中使用的均方值的平方性质进行线性化的手段。这个方法可以用于其他更复杂的操作。
标准差的公式如下:
$$text{标准差} = sqrt{frac{sum (x_i - bar{x})^2}{n}}$$
1.3.2 概率与随机变量
概率论和随机变量对于理解本书中的概念至关重要。
概率(Probability)
概率是一门数学学科,其主要目标是研究随机事件。从实际角度看,概率试图从可能发生的事件中量化事件发生的确定性(或不确定性)。
1. 事件
为了理解概率,我们首先定义事件。在给定的实验中,执行确定的动作可能会出现不同的结果。事件是实验中所有可能结果的子集。
例如,掷骰子时出现的特定数字,或装配线上出现的产品缺陷。
(1)概率
按照定义,概率是事件发生的可能性。概率被量化为0到1之间的实数。当事件发生的可能性增加时,概率P也随之接近1。事件发生概率的数学表达式是P(E)。
(2)随机变量和分布
在分配事件概率时,我们可以尝试覆盖整个样本空间,并为样本空间中的每个可能事件分配一个概率值。
这个过程具有函数的所有特征。对于每一个随机变量,都会为其可能的事件结果赋值。这个函数称为随机函数。
这些变量有两种类型: - 离散(Discrete):结果的数量是有限的或可数无限的。 - 连续(Continuous):结果集属于连续区间。
这个概率函数也称为概率分布(Probability Distribution)。
1. 常见概率分布
在多种可能的概率分布中,有一些函数因其特殊性质或所代表问题的普遍性而被广泛研究和分析。
本书将描述那些常见的概率分布。它们对机器学习的发展具有特殊影响。
(1)伯努利分布(Bernoulli Distribution)
从一个简单的分布开始:像抛硬币一样,它具有二分类结果(binary outcome)。
这个分布表示单个事件。该事件中1(正面)的概率为p,0(反面)的概率为1-p。
为了可视化,可以使用np(NumPy库)生成大量伯努利分布的事件,并绘制该分布的趋势。代码如下:
```python import matplotlib.pyplot as plt import numpy as np
distro = np.random.binomial(1, 0.6, 10000) / 0.5 plt.hist(distro, 2, normed=1) ```
下面通过图1.8中的直方图显示二项分布(Binomial Distribution),可以看出结果概率的互补性质。
1.3.3 概率函数的统计度量
这一节将介绍概率中的常见统计度量。首先是均值和方差,它们的定义与统计学中的定义相同。
1. 偏度(Skewness)
偏度表示概率分布的横向偏向,即偏离中心的程度或对称性。一般来说,如果偏度为负,则表示向右偏离;如果为正,则表示向左偏离。
2. 峰度(Kurtosis)
峰度显示分布的中心聚集程度。它定义了中心区域的锐度,也可以反过来理解为函数尾部的分布方式。
峰度的表达式如下:
$$text{峰度} = frac{sum (xi - bar{x})^4}{(sum (xi - bar{x})^2)^2}$$
1.3.4 微分基础
为了涵盖机器学习的基础知识,特别是像梯度下降(Gradient Descent)这样的学习算法,本书将介绍微分学涉及的概念。
1.3.5 准备知识
介绍覆盖梯度下降理论所需的微积分术语需要许多章节,因此我们假设读者已经了解连续函数的概念,如线性、二次、对数和指数函数,以及极限的概念。
为了清楚起见,我们将从一元函数的概念开始,然后简单地触及多元函数。
1. 变化分析——导数
在前一节中介绍了函数的概念。除了在整个域中定义的常值函数外,所有函数的值都是动态的。这意味着在x确定的情况下,f(x1)与f(x2)的值是不同的。
微分学的目的是衡量变化。对于这个特定的任务,17世纪的许多数学家(莱布尼兹和牛顿是杰出的倡导者)努力寻找一个简单的模型来衡量和预测符号定义的函数如何随时间变化。
这项研究将引出一个巧妙的概念——在一定条件下,表示在某个点上函数变化的程度及方向。这就是导数的概念。
在斜线上滑动
如果想测量函数随时间的变化,首先要取一个函数值,在其后的点上测量函数。第一个值减去第二个值,就得到函数随时间变化的程度。代码如下:
```python import matplotlib.pyplot as plt import numpy as np
def quadratic(var): return 2 * var ** 2
x = np.arange(0, 0.5, 0.1) plt.plot(x, quadratic(x)) plt.plot([1, 4], [quadratic(1), quadratic(4)], linewidth=2.0) plt.plot([1, 4], [quadratic(1), quadratic(1)], linewidth=3.0, label="Change in x") plt.plot([4, 4], [quadratic(1), quadratic(4)], linewidth=3.0, label="Change in y") plt.legend() plt.plot(x, 10 * x - 8) plt.show() ```
上面的代码示例首先定义了一个二次方程(2x^2),然后定义了arange函数的域(0到0.5,步长0.1)。
定义一个区间,测量y随x的变化,并画出测量的直线,如图1.16所示。
随着Δx的逐渐减小,变化率将趋于稳定。这引出了极限的概念。在定义极限的过程中,使Δx无限小,得到的结果称之为f(x)的导数或f'(x),公式如下:
$$f'(x) = lim_{Delta x to 0} frac{f(x + Delta x) - f(x)}{Delta x}$$
数学家们没有停止繁复的计算。他们进行了大量的数值运算(大多是在17世纪手工完成的),并希望进一步简化这些操作。
现在构造一个函数,可以通过交换x的值来得到相应的导数。对于不同的函数族,从抛物线(y=x^2+b)开始,出现了更复杂的函数(见图1.17),这一巨大的提高发生在17世纪。
2. 链式法则
在函数导数符号确定后,一个非常重要的结果是链式法则。莱布尼茨在1676年的一篇论文中首次提到这个公式。它可以经过简单优雅的方式求解复合函数的导数,从而简化复杂函数的求解。
为了定义链式法则,假设有一个函数f,F=f(g(x)),那么导数可以定义如下:
$$F'(x) = f'(g(x)) cdot g'(x)$$
链式法则允许对输入值为另一个函数的方程求导。这与搜索函数之间关联的变化率是一样的。链式法则是神经网络训练阶段的主要理论概念之一。由于在这些分层结构中,第一层神经元的输入将是下一层的输入。在大多数情况下,复合函数包含了一层以上的嵌套。
偏导数(Partial Derivative)
到目前为止,本书一直使用单变量函数。但是从现在开始,我们将主要介绍多变量函数。因为数据集将不止包含一个列,并且它们中的每一列将代表不同的变量。
在许多情况下,需要知道函数在一个维度中的变化情况,这将涉及数据集的一列如何对函数的变化产生影响。
偏导数的计算包括将已知的推导规则应用于多变量函数,并将未被求导的变量视为常数导出。
以幂函数为例:
$$f(x, y) = 2x^3y$$
当这个函数对x求导时,y作为常量。可以将其重写为3 · 2yx^2,并将导数应用于变量x,得到以下结果:
$$frac{partial f(x, y)}{partial x} = 6yx^2$$
使用这些方法,可以处理更复杂的多变量函数。这些函数将是特征集的一部分,通常由两个以上的变量组成。
本文摘自:《机器学习开发者指南》
本书的目标读者是那些希望掌握机器学习相关知识、了解主要的基本概念、运用算法思想并掌握正式数学定义的开发人员。本书使用Python实现了代码概念,Python语言的简洁性和提供的便捷且丰富的工具将有助于我们处理这些代码,而具有其他编程语言经验的程序员也能理解书中的代码。
读者将学会使用不同类型算法解决自己的机器学习相关问题,并了解如何使用这些算法优化模型以获得最佳结果。如果想要了解当前的机器学习知识和一门友好的编程语言,并真正走进机器学习的世界,那么这本书一定能为您提供帮助。
本书主要关注机器学习相关概念,并使用Python语言(版本3)作为编码工具。本书通过Python 3和Jupyter Notebook构建工作环境,可以通过编辑和运行它们来更好地理解这些概念。我们专注于如何以最佳方式应用各种Python库来构建实际的应用程序。