机器学习-1-导论
什么是人工智能(Artificial Intelligence, AI)?
这一名词并没有一个全世界通用的定义,在大多数的文件与标准中,分别从学科和技术系统两个角度进行定义:
-
中国国家标准:利用数字计算机或由其控制的机器,模拟、延伸和扩展人的智能,感知环境、获取知识并使用知识获得最佳结果的理论、方法、技术及应用系统。
-
国务院《新一代人工智能发展规划》:人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。
-
法律操作性定义(OECD/欧盟《人工智能法案》):是一种基于机器的系统,能够在不同程度的自主性下运行,部署后可展现出适应性,并针对明示或隐含的目标,从接收的输入中推断出如何生成可影响物理或虚拟环境的输出,如预测、内容、建议或决策。
从上述这些官方定义中可以看到一些共同处:AI是一个系统,并且能感知外部环境并输出结果。 进一步抽象AI的定义,我们可以简化为一个函数:y=ax+b,其中x就是感知到的外部环境信息,y就是输出的结果,而a与b就是训练出来的AI参数。
初中方程配上高中导数=简单的小AI
举个例子
房价计算
- (x):面积;
- (a):面积对房价的影响程度;
- (b):即使面积为 0 时,模型给出的基础偏移;
- (y):预测房价。
目前这个AI只能考虑面积这一个因素,现实世界要考虑的东西非常复杂,比如地段、楼层、交通情况、装修费用等,于是现在的AI模型变成了:
现在这个AI可以帮我快速算出一个房子合理的价格了。
现在出现了一个新的问题,这个公式里面的 a1, a2, a3, a4, b都是从哪里来的?总不能直接拍脑门定下下这些参数。此时我们就要“从已有的数据中进行学习”,我们需要教会AI,给定面积、楼层、房龄、公交距离时,他的房价是多少,因此我们会获得这样一个表格:
| 编号 | 面积 x₁/㎡ | 楼层 x₂ | 房龄 x₃/年 | 公交距离 x₄/米 | 房价 y/万元 |
|---|---|---|---|---|---|
| 1 | 55 | 3 | 18 | 950 | 92 |
| 2 | 60 | 5 | 15 | 800 | 105 |
| 3 | 65 | 6 | 12 | 700 | 119 |
| 4 | 70 | 8 | 10 | 650 | 135 |
| 5 | 75 | 10 | 8 | 600 | 151 |
| 6 | 80 | 12 | 6 | 500 | 170 |
| 7 | 85 | 15 | 5 | 450 | 185 |
| 8 | 90 | 16 | 4 | 400 | 202 |
| 9 | 95 | 18 | 3 | 350 | 220 |
| 10 | 100 | 20 | 2 | 300 | 238 |
| 11 | 72 | 4 | 20 | 1100 | 123 |
| 12 | 78 | 7 | 16 | 900 | 142 |
| 13 | 88 | 9 | 12 | 750 | 175 |
| 14 | 92 | 11 | 10 | 600 | 196 |
| 15 | 105 | 14 | 8 | 500 | 232 |
| 16 | 110 | 17 | 6 | 450 | 254 |
| 17 | 115 | 19 | 5 | 350 | 273 |
| 18 | 120 | 22 | 3 | 250 | 298 |
理论上,对于表中的任意一行,将x1-x4带入y的表达式中,我们会得到一个预测的价格:,以及他的真实值,这两个值之间的差距应该越小越好(真实世界几乎无法做到百分百线性,只要误差在一定范围内即可)。
此时出现一个问题,我们并不知道a1-a4以及b具体是多少,如果直接赋予一个随机的初始值,那么整个表达式计算出来的结果与真实值会有非常大的偏差,具体可以写(第一行为例):
那么,我们是不是可以找一组参数,让这个误差最小?不过我们不能只顾第一行数据,我们要让已有的这18条都能最小的一组参数,即:
但是这个方程还有些问题,如果一个房价预测比真实值高10w,另一个低了10w,那么求和之后就是0,总的误差成0了!无法起到监督的效果,所以我们对原先的加上一个平方,保证每一项的误差都是一个正值,不会出现抵消,而且二次项会把误差放大,更利于收敛。
当然这是一个总误差,数据量如果比较大,那这个误差会非常大,一个好的方法它应该不挑数据量大小,应该在每一条数据上反应他的误差,所以在此基础上我们还要再加一个平均,同时,考虑到求最小化一般都要求导,二次项求导会产生一个2倍系数,我们再凑一个1/2用于后续抵消求导,最终的损失函数为:
而这个形式就是日后常见的损失:MSE均方误差。
怎么求解?
对于一元二次方程通过求导并令导函数为0,可以求出极值点,例如:,导函数为,令导函数为0可以得到,此时函数获得极小值。
为什么可以这么做?直观的说,导数表示的是函数在某点的变化趋势,大于0说明上升,小于0说明下降,等于0说明为极值点。
回到我们的模型,如果是最开始单变量问题,,是一个关于a的函数,损失函数为,一般也会写成:
此时求导并令导函数为0,可以求出令损失函数最小的a。
但是,现在的模型并不是一个单变量的模型,而是多个参数,损失函数也是一个多变量的函数:
此时需要分别计算偏导数,计算各个分量对损失的影响:
将所有偏导数放置在一起,形成一个向量:
该向量称为梯度,梯度可理解为:在当前参数位置,损失函数上升最快的方向。既然梯度指示了损失函数上升的方向,那么如果想要损失最小,就要往负方向走,也即:梯度下降。我们随机给参数赋予初始值,并不断计算梯度,不断往下移动,更新参数,最终实现损失函数的最小化,更新方式如下:
参数新值 = 参数旧值 - 学习率 x 梯度
对于参数,可写成:。其中 表示学习率,用来控制每次更新参数时走多大一步。
同理,所有参数都可以按照类似方式更新:
不过,上面的写法仍然比较繁琐。既然我们已经知道这些参数本质上是一组数,那么就可以把它们写成向量形式。
令参数向量为:
第 (i) 条样本的特征向量为:
那么第 (i) 条样本的预测结果可以写成:
如果把 18 条样本全部放在一起,可以得到特征矩阵:
真实房价向量为:
预测房价向量为:
于是,损失函数也可以写成更简洁的向量形式:
因此,参数更新可以写成:
代码实现
1 | import numpy as np |


