机器学习导论
监督学习
监督学习(Supervised Learning)是机器学习的一种方法,它是指在训练数据中,每个样本都有一个标签(即为正确答案),即我们知道样本的输入和输出之间的关系。监督学习的目标是学习一个模型,使得对于一个新的输入,我们可以预测其输出。
例如我们要实现猫和狗的分类问题,我们需要一个数据集,其中包含了很多猫和狗的图片,每张图片都有一个标签,即为猫或者狗。我们可以使用这个数据集来训练一个模型,使得对于一个新的图片,我们可以预测其是猫还是狗。
监督学习的主要任务有:回归(Regression)和分类(Classification)。
- 回归:回归是指预测一个连续的数值,例如房价预测。
- 分类:分类是指预测一个离散的标签,例如猫和狗的分类。
无监督学习
无监督学习(Unsupervised Learning)是机器学习的一种方法,它是指在训练数据中,每个样本都没有标签,即我们不知道样本的输入和输出之间的关系。无监督学习的目标是学习一个模型,使得对于一个新的输入,我们可以找到其内在的结构。
无监督学习常常用于聚类(Clustering)和降维(Dimensionality Reduction)。
聚类
聚类(Clustering)是指将数据集中的样本分成若干个组,使得每个组内的样本之间的相似度尽可能的高,而不同组之间的相似度尽可能的低。
例如有一些蔬菜和水果,我们可以使用聚类算法将它们分成若干个组,使得每个组内的蔬菜和水果尽可能的相似。这些相似可能是指它们的颜色、形状、大小等。
聚类的方法分为层次聚类(Hierarchical Clustering)和非层次聚类(Non-hierarchical Clustering)。
- 层次聚类:将特性相似的样本逐渐合并成一个组,直到所有的样本都合并成一个组。
- 非层次聚类:先设定聚类数目,然后将样本分成若干个组。常见的非层次聚类算法有 K-means 算法。
降维
聚类之后,我们可以得到若干个组,每个组内的样本之间的相似度尽可能的高,而不同组之间的相似度尽可能的低。但是我们如何将这些组可视化呢?这时候就需要降维(Dimensionality Reduction)。
一个中学生的数据,如果有语文、数学、理综、社会、英语这五门成绩,那么就是一个五维的数据,我们可以使用降维算法将这个五维的数据降到二维,使得我们可以在二维平面上可视化这个数据。我们可以将理科成绩(数学、理综)和文科成绩(语文、社会、英语)分别合并,然后在二维平面上可视化这个数据。这样实现了降维。
强化学习
强化学习(Reinforcement Learning)是机器学习的一种方法,它是指智能体(Agent)在与环境(Environment)交互的过程中,通过试错的方式学习到一个最优的策略。强化学习和无监督学习不同,后者是学习数据本身,而强化学习是学习如何做出决策。
我们会定义一个奖励函数,当智能体做出一个正确的决策时,我们会给予一个正的奖励,当智能体做出一个错误的决策时,我们会给予一个负的奖励。智能体的目标是最大化累积奖励。为了达到这个目标,智能体需要学习到一个最优的策略。
强化学习的常用术语
以下黑白棋为例,介绍强化学习的常用术语。
术语 | 说明 |
---|---|
行动(Action) | 在空格上放置黑子或白子 |
代理人(Agent) | 类似于黑白棋玩家的角色 |
报酬(Reward) | 代理人在环境中采取行动后获得的奖励,在黑白棋中放置棋子将对方棋子吃掉,获得正奖励;被对方棋子吃掉,获得负奖励 |
策略(Policy) | 代理人在环境中采取行动的方式,例如在黑白棋中,代理人的策略是如何放置棋子 |
收益(Return) | 未来能够获得的奖励的总和,即累积奖励 |
Q 值(Q-value) | 代理人在状态 s 采取行动 a 的价值,即在状态 s 采取行动 a 能够获得的累积奖励 |
V 值(V-value) | 代理人在当前这种情况下采取行动的价值,即在当前情况下能够获得的累积奖励 |
剧本(Episode) | 代理人与环境交互的一次完整过程,例如一局黑白棋的过程 |
强化学习旨在获取更多报酬。
机器学习的工作流程
基本步骤
主要分为整体设计、机器学习设计、使用三个步骤。
整体设计
-
确定问题:明确要解决的问题,如 “提高用户满意度”。将问题公式化,如 “想要推荐商品” = “预测用户购买这个商品的概率”。
-
系统设计: 设计整个系统的架构,如 “推荐系统” = “用户画像” + “商品画像” + “推荐算法”。以及决定从哪里获取数据,怎样利用数据。
-
数据获取:从数据库、API、爬虫等方式获取数据。
机器学习设计
-
机器学习算法选择:根据问题的性质,选择合适的机器学习算法。从监督学习、无监督学习、强化学习等各种算法中选择合适的算法。
-
数据预处理(整形和特征工程):对数据进行清洗、整形、特征工程等操作。
特征工程是指将原始数据转换成特征,以便于机器学习算法的输入。特征工程是机器学习中最重要的一步,它直接影响到模型的性能。
例如,我们可以消除多余的特征, 在预测明天天气中加入数据有气温、天气、活动、星期几等特征,但是我们可以消除活动特征,因为活动特征对于预测明天天气没有帮助。
又例如我们要预测一个学生考上大学的概率,我们可以把理科成绩和文科成绩合并成一个特征为“学习能力”,因为学习能力对于预测学生考上大学的概率有帮助。
-
模型训练:使用训练数据训练模型。
-
模型评估:使用测试数据评估模型的性能。如果想要进一步提高模型的性能,可以回到第 5 步,重新进行数据预处理。
-
模型调优:调整模型的超参数,使得模型的性能更好。超参数是指在训练模型之前需要设置的参数,例如学习率、迭代次数等。
-
使用:可以搭建一个 API,使得其他系统可以调用这个模型。
数据收集
数据收集往往有三种方法:
-
自己记录数据
-
使用公开数据集,许多企业和组织都会公开一些数据集,例如 UCI 机器学习库。
-
使用爬虫从网站上爬取数据。
数据预处理
数据预处理是机器学习中最重要的一步,它直接影响到模型的性能。
对分类数据进行预处理
分类数据是指有限个数的数据,例如性别、颜色、品牌等。常用的处理方法有:
-
Label Encoding:将分类数据转换成整数,例如将性别转换成 0 和 1。
-
One-Hot Encoding:将分类数据转换成二进制,例如将颜色转换成 [1, 0, 0]、[0, 1, 0]、[0, 0, 1]。它将导致数据的维度增加,但内存占用增加。
-
计数编码:将分类数据转换成它们的频率,例如将品牌转换成它们的频率。
例如,有下面的数据需要预处理:
ID | 城市 |
---|---|
1 | 北京 |
2 | 上海 |
3 | 北京 |
4 | 广州 |
我们可以使用 Label Encoding 将城市转换成整数:
ID | 城市 |
---|---|
1 | 0 |
2 | 1 |
3 | 0 |
4 | 2 |
也可以使用 One-Hot Encoding 将城市转换成二进制:
ID | 北京 | 上海 | 广州 |
---|---|---|---|
1 | 1 | 0 | 0 |
2 | 0 | 1 | 0 |
3 | 1 | 0 | 0 |
4 | 0 | 0 | 1 |
也可以使用计数编码将城市转换成它们的频率:
ID | 城市 |
---|---|
1 | 2 |
2 | 1 |
3 | 2 |
4 | 1 |
对数值数据进行预处理
数值数据是指连续的数据,例如年龄、体重、身高等。常用的处理方法有:
-
离散化:将连续的数据转换成离散的数据,例如将年龄转换成年龄段。
-
对数变化:将数据取对数,使得数据更加符合正态分布。
-
缩放:将数据缩放到一个范围内,例如将数据缩放到 [0, 1]。因为某些情况下,数据的上限是一个没有固定的值,所以我们需要将数据缩放到一个范围内。最具代表的缩放方法是 Min-Max 缩放。它有两种形式:
-
Min-Max 缩放:将数据缩放到 [0, 1]。
-
标准化缩放:将数据缩放到均值为 0,标准差为 1。
-
模型制作和训练
什么是模型?模型是一个函数,它接受输入,然后输出一个预测值。模型的目标是使得预测值尽可能的接近真实值。我们可以把模型比喻为一个箱子,它接受输入,然后输出一个预测值。
下面设想一个场景,我们要预测一个公民的储蓄金额,输入的内容为其年收入。我们准备的数据是大量的公民的年收入和储蓄金额一一对应的数据,我们可以使用这些数据训练一个模型,使得对于一个新的公民,我们可以预测其储蓄金额。
让我们开始训练,我们的目标是预测的值尽可能的接近真实值。因此我们的训练就是在不断减小这个差距的过程。这个差距被称为训练误差。为了达到训练误差减小的目标,在训练过程中,我们需要不断调整模型的参数(这通常由算法自动完成),使得训练误差不断减小。
迭代是指对模型的参数进行不断的调整,使得训练误差不断减小。迭代的次数被称为迭代次数。
迭代的主要方法有:
-
批学习:将所有的训练数据一次性输入模型,然后调整模型的参数。
-
小批量学习:将训练数据分成若干个小批量,然后依次输入模型,然后调整模型的参数。
-
在线学习:每次训练都只输入一个样本,然后调整模型的参数。
后两个方法会导致计算量非常大。
使用测试数据验证模型
在训练模型之后,我们需要使用测试数据验证模型的性能。测试数据是模型没有见过的数据,它可以帮助我们评估模型的泛化能力。
如果我们使用训练数据来验证模型,那么模型的性能会非常好,但是这并不能说明模型的性能好,因为模型可能已经记住了训练数据。这就相当于我们考试之前背诵了答案,然后考试的时候自然会得高分。但是一旦考试的题目变了,可能就露馅了,模型的性能可能会变得很差。
那如何分割训练数据和测试数据呢?比较有代表性的方法就是 hold out 验证和 k 折交叉验证。
-
hold out 验证:从所有的数据中挑选出一部分数据作为测试数据,剩下的数据作为训练数据。但是有一个风险是如果我们挑选的测试数据不具有代表性,那么模型的性能可能会变得很差。
-
k 折交叉验证:保证所有的数据都做作为验证数据使用,让训练数据和验证数据相互交叉,制作成多个子集,在此之上分别使用训练数据进行训练,测试数据进行验证。这样可以保证所有的数据都被使用过,而且模型的性能也更加稳定。虽然 k 折交叉验证的计算量比 hold out 验证大,但是仍是一个非常常用的验证方法。在 K-1 个子集上训练,然后在剩下的一个子集上验证。