3. 人工智能与机器学习
人工智能是研究开发用于模拟和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。
机器学习是基于大量数据而成,让计算机像人类一样学习和行动的科学,通过以观察和现实世界互动的形式向他们提供数据和信息,以自主的方式改善他们的学习。机器学习包括深度学习、强化学习、传统机器学习等。
深度学习是模拟人脑所构成的,支持从大量数据中学习,学习这些样本数据中的内在规律和表示层次。
强化学习是构建一个智能体,在一个复杂的环境下去最大可能获得奖励,通过感知环境所处的状态对动作的反应来指导获取更好的动作,从而获得最大的收益。
传统机器学习是从一些观测(训练)样本出发,使用统计学、线性代数、优化算法等数学方法,从已有数据中学习并构建预测模型,进而用于对未知数据的预测和分类。
1.1 机器学习
那么如何达到我们 定义中像人类学习和行动呢,下面以一个线性回归的例子讲解什么是机器学习。
在X-Y坐标上给定一些样点值,求解一条直线,求该直线可以表示样点值的趋势。这是最基础的线性回归问题,回归分析中,只用一个自变量和一个因变量,且两者的关系可以用一条直线近似表示。
该直线可以看成y=ax函数,其中a代表直线的斜率。如果是依靠我们大致绘制的直线,并测量其a,这样只需要提供x值即可推测出y值。
但这仅局限于数量很少的样点,如果大量的样点数据,依靠人脑是绘制的趋势直线是不准确的。
假设我们设计一个程序求解样点的趋势线,先定义趋势线公式为y=ax,然后如下操作:
-
先随机选取a的值,将样本点的x值代入求出y'值,差值e=(y'-y)^2。如此计算所有样本点的差值,所有差值相加得到总误差E_1 。
-
再将a的值增大或减小:a = a + delta,这个增大或减小的区间值称为步长值。重新计算总误差E_2。
-
对比 E_1和E_2 的值,如果 E_2小于 E_1 ,则代表总误差减小,步长方向正确。如果 E_2大于 E_1 ,则代表总误差增大,步长方向错误,需要修改步长方向: delta = - delta。
-
从步骤2继续循环,直到误差变化不再降低为止。
在这个循环过程中,如果误差比较大,可以加大delta值以减少循环次数;如果误差已经比较小了,可以减小delta值以提高精度。
例如:假设a_1=a_0+步长值,再将所有的样本点重新计算得出新的误差 E_2。对比 E_1和E_2 的值,如果 E_2小于 E_1 ,则代表总误差减小,步长方向正确。如果 E_2大于 E_1 ,则代表总误差增大,步长方向错误,需要修改步长方向。
例如:假设原来的步长值为-0.6,在下次迭代时将 ,
此时步长值=+1 ,使原始的a值增加,然后继续迭代。如果在新迭代后,总误差E值降低了,则证明步长方向修改正确。再按照一定的步长与刚刚a值的方向迭代下去,直到总误差值E不再降低为止,此时得到的a就是对所以已知样本点的最佳拟合函数f(x)=ax的参数。
根据误差的变化趋势决定参数的调整方向,力度(误差越大步长值越大,反之则越小)从而获取最低误差的方式就被称为梯度下降法。
**问:**为什么叫做梯度下降法呢?
**答:**我们在线性回归模型中我们需要根据误差来确定步长的调整,计算的方式是均方误差函数(损失函数),公式为:
那么我们肯定是想计算出该均方误差公式的最小值,那么想要求得函数最小值,在数学方法中,我们就会想到求导,并求二阶偏导函数的驻点。下面展示均方误差函数J(w)求偏导后的结果:
权重w的迭代过程是以负梯度的方向(减少误差的方向)来决定每次迭代时权重w的变化方向,从而使每次迭代后目标函数(误差函数)的值逐渐减小。
每次迭代都会修改权重w值,使其以α学习速率沿着偏导数的反方向进行移动。
均方误差函数是一个二次函数。它实际的函数图像可能是如图所示的一个抛物线。图中的损失值Cost就是误差值。假设我们在初始a值的点时,我们的损失值很大,我们想要降低损失值,需要沿着函数的梯度方向(函数的方向)往下走,直到找到损失值的最低点(即找到最低的误差值)。
如果是计算大量样本点的时候,可以知道整个迭代过程中运算量是很大,计算机需要不断的在大量样本点中运算、分析、试错、调整、重新计算,这个过程称为训练。线性回归求解训练过程如图所示:
如图所示的回归分析中,训练的目的就是在大量样本点中找出描述样本点之间规律的函数的参数。上述基本线性模型的整个过程称为机器学习。
1.2 模型和拟合
通过前面的线性回归学习我们知道,建立的模型需要与数据集对应,简单的数据集需要对应 简单的模型,复杂的数据集需要对应复杂的模型。以求回归问题为例,求下面两个数据集的回归线:
通过观察上面两个数据集可以发现,我们可以发现样本数据集1可以通过建立简单的y=ax+b的线性模型求得该样本的回归线;样本数据集2数据集较为复杂,如果直接使用简单的y=ax+b的线性模型,无法拟合出样本数据集2的回归线,我们称为不拟合,此时需要建立一个更为复杂的模型,如y=ax^2等,对样本数据集进行回归拟合。
从上图可以看出,模型的复杂度需要和数据集的复杂程序对应,如果复杂数据使用简单模型可能会出现不拟合的情况。
如果机器学习的结果拟合度不够高,结果相差很大,称为不拟合。可以加入高次项。但如果加入了过多的高次幂项,可能会导致正确率不升反降,此现象称为过度拟合。过拟合为得到高精度的拟合结果,而使模型变得过度复杂,导致模型参数不合理、表现力、预测力变差。
1.3 线性回归模型
1.3.1 实现简单线性回归
假设提供一些样本点数据,样本点数据为:[1, 3.5], [2, 4.7], [3, 5.3], [4, 7.1],[5, 9.6],[6, 13.5], [7, 16.2], [8, 19.4],[9, 23.2], [10, 33.8],该样本点在图像中的位置如下图所示:
预先构建一个直线函数y=wx,其中w为权重,不考虑偏置值。使用该直线绘制这样本点的线性回归直线,其中权重更新公式如下所示:
下面基于这些样本点我们来构建一个python程序实现,对样本点进行线性回归预测。下面展示代码的流程框图:
代码流程为:
-
导入numpy包,该包是数组处理包,提供了处理 n 维数组的工具,即提供矩阵运算能力。
-
导入matplotlib包,该包可支持Python 的 2D 可视化绘图库,可创建静态、动画和交互式可视化图像。
-
调用求解权重函数,计算直线函数y=wx中的w值。
- 判断是否达到迭代次数。
- 使用权重值w,代入x值计算预测值h
- 计算预测值h和真实值y的差值
- 求解梯度值
- 更新权重值w
- 计算损失值
- 当没有达到迭代次数,继续返回步骤2。当达到迭代次数,则返回权重值。
-
使用新权重值预测数据。
-
将样本点和回归直线绘制到坐标轴上。
1.3.2 简单线性回归代码解析
导入拓展包,支持矩阵运算和可视化
导入numpy包,该包数组处理包,提供了处理 n 维数组的工具,即提供矩阵运算能力。
导入matplotlib包,该包可支持Python 的 2D 可视化绘图库,可创建静态、动画和交互式可视化图像。
import numpy as np
import matplotlib.pyplot as plt
初始化样本点数据
使用多维数组存储样本点数据,并获得该数组的行数和列数
#样本点数据
x = np.array([[1, 3.5], [2, 4.7], [3, 5.3], [4, 7.1],[5, 9.6],
[6, 13.5], [7, 16.2], [8, 19.4],[9, 23.2], [10, 33.8]])
m, n = np.shape(x) #获得样本点数据的行数和列数 m:行数 10 n:列数 2
print("x样本点数据的行数m和列数n:",m,n)
获得样本点的x值和y值
创建一个10行2列的多维数组,并将其置为0。将每一行的第一列存储样本点数据的x值,存储结果保存在x_data中。
将样本点数据的y值,存储在y_data中。
x_data = np.zeros((m, n)) #新建10行2列矩阵,并将值都置为0
x_data[:, :-1] = x[:, :-1] #获取样本点数据中除最后一列之外的所有行和所有列,即样本点数据中的x
y_data = x[:, -1] #获取样本点数据中所有行和最后一列,-1代表最后一列,即样本点数据中的y
初始化权重值
创建一个权重矩阵,矩阵为[1,0]。
m, n = np.shape(x_data) # 获得样本点数据中的x行数和列数 m:行数 10 n:列数 2
theta = np.array([1,0]).reshape(2) #创建一个权重矩阵,初始化权重为[1,0]
定义权重函数
由于我们定义的直线的函数为y=wx,其中w为权重。该函数主要用于求解权重w值,其中实现了权 重更新公式和损失函数,如下所示的两个公式:
#求解权重函数
#iter:迭代次数 x:横坐标 y:纵坐标 w:权重 alpha:学习率
def gradientDescent(iter, x, y, w, alpha):
x_train = x.transpose() #交换矩阵的两个维度
for i in range(0, iter):
pre = np.dot(x, w) #矩阵乘法
loss = (pre - y) #预测值和真实值的差值
#权重更新公式
gradient = np.dot(x_train, loss) / m #求解梯度
w = w - alpha * gradient #更新权重
#使用损失函数求解损失值
cost = (1.0 / (2 * m)) * np.sum(np.square((np.dot(x, w)) - y))
print("第{}次梯度下降损失值为: {}".format(i,round(cost,2)))
return w
1.交换矩阵的两个维度
x_train = x.transpose()
2.计算预测值
pre = np.dot(x, w) #矩阵乘法
假设是第一次进行计算,那么x为样本点的x值,w权重为[1,1],计算方式为:
3.计算差值
差值等于预测值减真实值,计算权重更新公式中的h(x)-y部分。公式如下所示:
loss = (pre - y) #预测值和真实值的差值
计算过程如下所示:
4.权重更新
计算梯度值,即将差值 乘 样本点的x值,再除以样本点的个数,公式如下所示:
gradient = np.dot(x_train, loss) / m #求解梯度
计算过程如下所示: