1. 引言
当大多数人听到“机器学习”,在脑海中就会浮现一个机器人:一个可靠的助手或一个可怕的终结者,这取决你问的是谁。事实上,在一些特定的应用中机器学习已经存在几十年了,比如:光学字符识别(OCR),垃圾邮件过滤器等。后来出现了数以百计的机器学习应用,支撑数百个现在经常使用的产品和特性(如推荐系统到语音搜索)。
本章将简单介绍机器学习涉及的所有基础概念,包括:监督学习和无监督学习、在线学习和批量学习、基于实例学习和基于模型学习,然后介绍一个典型的机器学习项目的工作流程,接着讨论可能遇到的难点,最后介绍如何评估和微调一个机器学习系统。
2. 机器学习概念
机器学习是一门通过编程让计算机从数据中进行学习的科学。
思考一下,你如何使用传统的编程技术写一个垃圾邮件过滤器。
- 你会先看一下垃圾邮件一般都是什么样子,可能注意到一些词或短语(比如4U、credit card、free、amazing)在邮件主题中频繁出现,也许还注意到一些邮件的发件人名字、正文和其他地方会出现的固定模式等。
- 你会为观察到的每个模式各写一个检测算法,如果检测到某个规律,程序就会将邮件标记为垃圾邮件。
- 你会测试程序,重复第1步和第2步,直到足够可以发布。
这样,你的程序可能变成一长串复杂的规则,很难维护。
相反,基于机器学习的垃圾邮件过滤器会自动学习词和短语,这些词和短语是垃圾邮件的预测因素,通过与非垃圾邮件比较,检测垃圾邮件中反复出现的词语模式,这个程序更短,更易维护,也更精确。
举个例子,如果垃圾邮件的发送者发现包含“4U”的邮件被屏蔽了,他们会转而使用“For U”,如果使用传统方法的垃圾邮件过滤器需要更新来标记“For U”,这样如果垃圾邮件发送者持续更改,你就需要一直不停地写入新的规则。相反,基于机器学习的垃圾邮件过滤器会自动注意到“For U”在用户手动标记的垃圾邮件中频繁出现,然后就能自动标记垃圾邮件而无须人工干预。
机器学习的另一个亮点是善于处理对于传统方法而言太复杂或没有已知算法的问题。最后,机器学习可以帮助人力进行学习,它可以检测自己学到什么。例如,在垃圾邮件过滤器训练了足够多的垃圾邮件后,就可以用它列出垃圾邮件预测器的单词和单词组合。有时可能会发现不引人关注的关联和新趋势,这有助于更好地理解问题。使用机器学习方法挖掘大量数据来帮助发现不太明显的规律,这称作数据挖掘。
总结一下,机器学习适用于:
- 有解决方案的问题,但解决方案需要进行大量人工微调或需要遵循大量规则,机器学习算法通常可以简化代码,相比传统方法有更好的性能。
- 传统方法难以解决复杂的问题:最好的机器学习技术也许可以找到解决方案。
- 环境有波动,机器学习算法可以适应新数据。
- 洞察复杂问题和大量数据。
3. 机器学习的应用示例
- 分析生产线上的产品图像来对产品进行自动分类。(这是图像分类问题,使用卷积神经网络的典型示例)
- 通过脑部扫描发现肿瘤(这是语义分割,图像中的每个像素都需要被分类,当我们想确定肿瘤的确切位置和形状时)
- 自动分类新闻(这是NLP,更具体是文本分类,可以使用RNN、CNN、Transformer)
- 论坛中自动标记恶评(这是文本分类)
- 自动对长文章做总结(这是NLP的一个分支,叫文本总结)
- 创建一个聊天机器人或者个人助理(这涉及自然语言处理的很多分支,包括自然语言理解NLU和问答模块)
- 基于很多性能指标来预测公司下一年的收入(这是一个回归问题,可以使用线性回归、多项式回归、SVM回归、随机森林回归、人工神经网络等)
- 让应用对语音命令做出反应(这是语音识别,要求能处理音频采样,因为音频很长、很复杂的序列,所以一般需要使用RNN、CNN或者Transformer等)
- 检测信用卡欺诈(这是异常检测)
- 基于客户的购买记录来对客户进行分类,对每一类客户设计不同的市场策略(这是聚类问题)
- 用清晰而有洞察力的图表来表示复杂高维数据集(这是数据可视化,经常涉及降维技术)
- 基于以前的购买记录给客户推荐可能感兴趣的产品(这是一个推荐系统,一个办法是将以前的购买记录和客户的其他信息输入人工神经网络,从而输出客户最可能购买的产品,这个神经网络是在所有客户的购买记录上训练的)
- 为游戏建造智能机器人(这通常通过强化学习来解决,强化学习是机器学习的一个分支,在一个给定的环境中,训练机器人选择在一段时间内将它们的奖励最大化的行动)
4. 机器学习系统的类型
我们根据以下标准将它们进行大的分类:
- 是否在人类监督下训练(有监督学习、无监督学习、半监督学习、强化学习)
- 是否可以动态进行增量学习(在线学习和批量学习)
- 是简单将新的数据点和已知的数据点进行匹配,还是像科学家那样,对训练数据进行模式检测然后建立一个预测模型(基于实例学习和基于模型学习)
这些标准之间互相并不排斥,例如,垃圾邮件过滤器可能使用深度神经网络模型对垃圾邮件和常规邮件进行训练,完成动态学习。它使其成为一个在线的、基于模型的有监督学习系统。
4.1 有监督学习和无监督学习
有监督学习 分类任务是一个典型的有监督学习任务,例如,垃圾邮件过滤器,通过大量的电子邮件实例及其所属的类别(垃圾邮件还是常规邮件)进行训练,然后学习如何对新邮件进行分类。另一个典型的任务是通过给定一组称为预测器的特征(里程、使用年限、品牌等)来预测一个目标数值(如汽车的价格),这种类型的任务称为回归。
常见得有监督学习算法有:
- k-近邻算法
- 线性回归
- 逻辑回归
- 支持向量机
- 决策树和随机森林
- 神经网络
无监督学习 无监督学习的训练数据都是未经过标记的。
常见的一些无监督学习的算法:
- 聚类算法: k-means, DBSCAN, 分层聚类分析(HCA)
- 异常检测和新颖性检测:单类SVM、孤立森林
- 可视化和降维:主成分分析(PCA)、核主成分分析、局部线性嵌入(LLE)、t-分布随机近邻嵌入(t-SNE)
- 关联规则学习:Apriori、Eclat
可视化算法是无监督学习算法的一种,如你提供大量复杂的、未标记的数据,算法轻松绘制输出2D/3D的数据表示,这些算法会尽其所能地保留尽量多的结构,以便于理解这些数据是怎么组织的,甚至识别出一些未知的模式。
与之相关的一个任务是降维,降维的目的是不丢失太多的信息前提下,简化数据。其中一种方法就是将多个相关特征合并为一个。例如,汽车里程与其使用年限存在很大的相关性,所以降维算法会将它们合并成一个代表汽车磨损的特征,这个过程叫作特征提取。
另一个很重要的无监督任务是异常检测,例如,检测异常信用卡交易,或者剔除异常值。
半监督学习 由于通常给数据做标记是非常昂贵和耗时的,你往往会有很多未标注的数据而很少有已标注的数据。有些算法可以处理部分已标注的数据。举例,华为手机相册,它会自动识别出人物A出现在照片1,5,11中,人物B出现在照片2,5,7中,这是算法的无监督部分,但现在系统需要你告诉它这些人都是谁,给每个人一个标签之后,它就可以给每张照片中每个人命名,这对于搜索图片非常重要。
4.2 批量学习和在线学习
判断的标准是系统是否可以从传入的数据流中进行增量学习。
批量学习 系统无法进行增量学习,即必须使用所有可用数据进行训练。这需要大量时间和计算资源,所以通常都是离线完成的,离线学习就是先训练系统,然后将其投入生产环境,这时学习过程停止,它只是将其所学到的应用出来。
如果希望批量学习系统,去学习新数据,需要在完整数据集的基础上重新训练系统的新版本,然后停用旧系统,用系统取而代之。虽然每次都能正常工作,但每次使用完整的数据集进行训练可能花上好几个小时,如果系统要应对快速变化的数据(预测股票价格),那么你需要一个更具向应力的解决方案。甚至当数据量非常大,资源又有限,那么我们需要一个更好的选择,那就是进行增量学习。
在线学习 可以循序渐进地给系统提供训练数据,逐步积累学习成果,这种提供数据的方式可以是单独的,也可以采用小批量的小组数据来进行训练。每一步学习都很快速并且便宜,这样系统可以快速写入最新的数据进行学习。在线学习,模型经过训练投入生产环境,然后随着新数据的进入不断学习。
在线学习面临的一个重大挑战,如果给系统输入不良数据,系统的性能将会逐渐下降。所以要密切监控系统,一旦检测到性能下降,就及时中断学习。
4.3 基于实例的学习和基于模型的学习
基于实例的学习 通过使用相似度度量来比较新实例和已经学习的实例,从而泛化新实例。如k近邻算法。
基于模型的学习 构建训练数据的模型,然后使用该模型进行预测。
举例,假设你想知道金钱是否让人感到快乐,我们可以从经合组织(OECD)的网站上下载“幸福指数”的数据,再从国际货币基金组织(IMF)的网站上找到人均GDP的统计数据,从而构建一个线性模型,下面用代码展示从加载、训练、预测,构建一个典型的机器学习项目。
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import pandas as pd
import urllib.request
from sklearn import linear_model
from pathlib import Path
DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml2/master/"
path = Path('./datasets', 'lifesat')
path.mkdir(exist_ok=True, parents=True)
for filename in ("oecd_bli_2015.csv", "gdp_per_capita.csv"):
print("DownLoading ", filename)
if (path / filename).exists():
continue
url = DOWNLOAD_ROOT + "datasets/lifesat/" + filename
urllib.request.urlretrieve(url, path / filename)
DownLoading oecd_bli_2015.csv
DownLoading gdp_per_capita.csv
oecd_bli = pd.read_csv(path / "oecd_bli_2015.csv", thousands=',')
gdp_per_capita = pd.read_csv(path / "gdp_per_capita.csv", thousands=',', delimiter='\t',
encoding='latin1', na_values="n/a")
def prepare_country_stats(oecd_bli, gdp_per_capita):
oecd_bli = oecd_bli[oecd_bli["INEQUALITY"]=="TOT"]
oecd_bli = oecd_bli.pivot(index="Country", columns="Indicator", values="Value")
gdp_per_capita.rename(columns={"2015": "GDP per capita"}, inplace=True)
gdp_per_capita.set_index("Country", inplace=True)
full_country_stats = pd.merge(left=oecd_bli, right=gdp_per_capita,
left_index=True, right_index=True)
full_country_stats.sort_values(by="GDP per capita", inplace=True)
remove_indices = [0, 1, 6, 8, 33, 34, 35]
keep_indices = list(set(range(36)) - set(remove_indices))
return full_country_stats[["GDP per capita", 'Life satisfaction']].iloc[keep_indices]
country_stats = prepare_country_stats(oecd_bli, gdp_per_capita)
X = np.c_[country_stats["GDP per capita"]]
y = np.c_[country_stats["Life satisfaction"]]
country_stats.plot(kind='scatter', x="GDP per capita", y='Life satisfaction')
plt.show()
model = linear_model.LinearRegression()
model.fit(X, y)
X_new = [[22587]]
print(model.predict(X_new))
?
[[5.96242338]]
import sklearn.neighbors
model = sklearn.neighbors.KNeighborsRegressor(n_neighbors=3)
model.fit(X,y)
print(model.predict(X_new))
[[5.76666667]]
如果一起顺利,你的模型将会做出很棒的预测,如果布线,则需要使用更多的属性,例如就业率、健康、空气污染等,获得更多或更高质量的训练数据,或者选择一个强大的模型。
一个典型的机器学习项目流程:
- 研究数据
- 选择模型
- 使用训练数据进行训练
- 应用模型对新数据进行预测,希望模型的泛化结果不错。
5. 机器学习的主要挑战
简单来说,我们的主要任务是选择一个学习算法,并对某些数据进行训练,所以最可能出现的两个问题不外乎是“坏算法”和“坏数据”,我们先从坏数据开始。
5.1 训练数据的数量不足
大部分机器学习算法需要大量的数据才能正常工作,即使是简单的问题,很可能也需要成千上万个实例,如图像或语音等复杂的问题。
5.2 训练数据不具代表性
为了更好地实现泛化,至关重要的一点是对于将要泛化的新实例来说,训练数据一定要非常有代表性。不具代表性的训练集训练出来的模型不可能做出准确的预估,比如非代表性数据被选中(噪声),模型的泛化能力就很差。
5.3 低质量的数据
如果训练集满是错误、异常值和噪声,更不太可能表现良好。
5.4 无关的特征
我们常说,垃圾入,垃圾出。一个成功的机器学习项目,其关键部分是提取出一组好的用来训练的特征集。
5.5 过拟合训练数据
解决方法:
- 简化模型:可以选择较少的参数模型,也可以减少训练数据中的属性数量,或是约束模型
- 收集更多的训练数据
- 减少训练数据中的噪声,如,修复数据错误和消除异常值
5.6 欠拟合训练数据
解决方法:
- 选择一个带有更多参数、更强大的模型
- 给学习算法提供更好的特征集
- 减少模型中的约束,如减少正则化超参数
测试与验证
超参数调整和模型选择,这里不做介绍。
参考资料: 《Hands-on Machine Learning with Scikit-Learn, Keras & TensorFlow》
|