《Hands-On-Machine-Learning》PART I

PART 1:The Fundamentals of Machine Learning

CHAPTER 1 :The Machine Learning Landscape (机器学习领域)

什么是机器学习?

例如,垃圾邮件过滤器是一个机器学习过程,可以学习标记垃圾邮件。系统用于学习的示例称为训练集。每个训练示例称为一个训练样本。在这种情况下,任务T是为新邮件标记垃圾邮件,E是训练数据,定义性能度量为P(比如p可以为是否正确区分出垃圾邮件),这种特殊的性能度量称为准确性,通常用于分类任务。

为什么要使用机器学习?

从上面的例子接着来看:

1.首先你要关注的是典型的垃圾邮件长什么样,比如会有免费,信用卡等字眼

2.您可以为您注意到的每个部分编写一个检测算法,如果检测到许多这样的部分,程序将把电子邮件标记为垃圾邮件。

3.测试程序,并重复步骤1和步骤2,直到足够好为止。

这是一种传统解决方法,如下图

3w59SA.png

这样循环下来,你的程序很可能会变成一长串复杂的规则,也就是说它很难维护。

相比之下,一个基于机器学习技术的垃圾邮件过滤器通过检测垃圾邮件示例中与非垃圾邮件示例相比单词的异常频率模式,自动学习哪些单词和短语是垃圾邮件的标志

程序要短得多,易于维护,而且很可能更准确。如下图:

3w5iOP.png

更深一步来看,如果垃圾邮件的发送者发现他们的“4U”被屏蔽了,那么他们很有可能再次使用‘“FOR U”来代替。然而一个基于机器学习的垃圾邮件过滤器会自动识别用户标记的垃圾邮件中出现的异常频繁的“For U”,它会在没有用户干预的情况下标记它们。下图是一个自动适应的例子:

3wLhoq.png

机器学习的另一个亮眼的表现是解决传统方法难以解决的问题,或者没有已知的算法。例如,考虑语音识别:假设你想从简单的开始,然后编写一个能够分辨“一”和“二”的程序。你可能会注意到,“two”这个词是以一个高音调的声音(“T”)开头的,所以你可以硬编码一个算法来测量高音调的声音强度,并用它来区分1和2。很明显,这种方法不能扩展到成千上万不同的人说的成千上万个单词。

机器学习可以帮助人类学习,可以检查ML算法,看看它们学到了什么,就像垃圾邮件过滤器对足够多的垃圾邮件进行了训练,就可以很容易地检查出它认为是垃圾邮件最佳预测器的单词列表和单词组合。有时,这将揭示意想不到的关系或新趋势,从而导致更好地理解问题。

应用ML技术挖掘大量数据可以帮助发现没有立即显现的模式,这叫做数据挖掘

30i5kD.png

总结机器学习的好处是:
•现有解决方案需要大量手工调整或大量规则列表的问题:一个机器学习算法通常可以简化代码并更好的执行。

•使用传统方法根本没有好的解决方案的复杂问题:最好的机器学习技术可以找到解决方案。

•环境波动:机器学习系统可以适应新数据。

•获得关于复杂问题和大量数据的见解。

机器学习系统的类型

•是否在人力监督下训练(监督、非监督、半监督和强化学习)

•是否可以随时学习(在线学习与批量学习)

•工作方式是简单地将新数据点与已知数据点进行比较,还是检测训练数据中的模式并建立预测模型(基于实例与基于模型的学习)

这些标准并不互斥;你可以任意组合它们。例如,一个最先进的垃圾邮件过滤器可能使用深度神经网络从垃圾邮件和非垃圾邮件种学习,使得它成为一个在线的、基于模型的、有监督的学习系统

监督学习和非监督学习(Supervised/Unsupervised Learning)

机器学习系统可以根据它们在训练中得到的监督的数量和类型来分类。有四大类:监督学习、非监督学习、半监督学习和强化学习。

监督学习(supervised learning):

在监督学习中,您提供给算法的训练数据包括所需的答案,称为标记(label)。

注:监督学习的input是{data,label},无监督学习的input是{data},feature是从data中归纳出来的低维度的表征信息不是直接给你的,是你的算法自己探索的

例如下图是一个用来训练监督学习的label数据集。

30KAxO.png

典型的监督学习任务是分类。垃圾邮件过滤器就是一个很好的例子:它使用许多示例邮件及其类(垃圾邮件或普通邮件)进行训练,并且必须学习如何对新邮件进行分类。

另一个典型的任务是预测一个目标数值,例如汽车的价格,给定一组称为预测器的特性(里程、年龄、品牌等)。

这类任务称为回归。要训练系统,你需要给它很多汽车的例子,包括它们的预测器和标签(例如他们的价格)。

下图为回归:

30Mw0H.png

注意,一些回归算法也可以用于分类,反之亦然。例如,逻辑回归通常用于分类,因为它可以输出与属于给定类的概率相对应的值,例如:百分之二十的概率为垃圾邮件

以下是一些最重要的监督学习算法:

•K -近邻算法 k-Nearest Neighbors

•线性回归 Linear Regression

•逻辑回归 Logistic Regression

•支持向量机(SVMs) Support Vector Machines (SVMs)

•决策树和随机森林 Decision Trees and Random Forests

•神经网络 Neural networks

非监督学习 (Unsupervised learning)

在无监督学习中,训练数据是没有标记的。

下面是一些最重要的无监督学习算法:

• 聚类分析

​ ——k均值聚类算法 k-Means

​ ——层次聚类分析(HCA) Hierarchical Cluster Analysis

​ ——期望最大化 Expectation Maximization

• 可视化和降维

——主成分分析(PCA) Principal Component Analysis (PCA)

—— 核主成分分析 Kernel PCA

——局部线性嵌入(LLE) Locally-Linear Embedding (LLE)

—— t分布随机近邻嵌入(t-SNE) t-distributed Stochastic Neighbor Embedding (t-SNE)

• 关联规则学习

—— 关联分析算法 Apriori

—— eclat算法 Eclat

聚类算法:

例如,假设您有关于博客访问者的大量数据。您可能想要运行一个聚类算法来尝试检测相似访问者的组。在任何情况下,你都不能告诉算法一个访问者属于哪个组:它在没有你的帮助下找到这些连接。例如,它可能会注意到40%的访问者是喜欢漫画书的男性,他们通常在晚上阅读你的博客
20%是年轻的科幻爱好者,他们会在周末去看科幻电影,等等。如果使用层次聚类算法,也可以将每个组细分为更小的组。

下图是一个聚类算法:

303LGR.png

拓展一下不难发现,当坐标的位维数增加,也就是feature增加,此时聚类算法根据不同的feature特征进行详细的分类。

可视化算法:

可视化算法也是无监督学习算法的好例子:你给它们输入大量复杂的、未标记(无监督学习中的数据是未标记的,这个是指label未标记,但是feature是包含的)的数据,它们输出2D或3D的数据表示,这些数据很容易绘制:

下图是一个利用 t分布随机近邻嵌入(t-SNE) 进行语义聚类

30YneK.png

注意上图中 动物是如何与车辆很好地分离,马是如何接近鹿而远离鸟,等等。

降维其目标是在不丢失太多信息的情况下简化数据(dimensionality reduction, )。一种方法是将几个相关的特性合并成一个。例如,一辆汽车的行驶里程可能与它的使用年限密切相关,因此降维算法会将它们合并成一个特征,以反映汽车的磨损情况。这叫做特征提取

另一个重要的非监督任务是异常检测(anomaly detection )——例如,检测不寻常的信用卡交易以防止欺诈,捕捉制造缺陷,或在将数据集中的异常值提供给另一个学习算法之前自动删除异常值。系统使用普通实例进行训练,当它看到一个新实例时,它可以判断它看起来是否像一个普通实例或者是否是一个异常的实例,如下图:

30Nfz9.png

最后,另一个常见的非监督任务是关联规则学习(association rule learning ),其目标是挖掘大量数据并发现属性之间有趣的关系。例如,假设你拥有一家超市。在你的销售记录上运行一个关联规则,可能会发现购买烧烤酱和薯片的人也倾向于购买牛排。因此,您可能希望将这些项放在彼此靠近的位置。

半监督学习(Semisupervised learning)

一些算法可以处理部分标记的训练数据通常是大量的未标记数据和少量标记数据。这被称为半监督学习

一些照片托管服务,比如谷歌Photos,就是很好的例子。一旦你将所有的家庭照片上传至该服务,它会自动识别出同一个人A出现在照片1、5和11中,而另一个人B出现在照片2、5和7中。我们可以这样理解:我们给照片a标注为妈妈,这显然是一个监督学习,在接下来大量无标记的照片加入后,通过非监督学习中的聚类分析将照片中的妈妈都标记出来,如下图就是一个半监督学习的例子。

30as4U.png

强化学习(Reinforcement Learning )

强化学习是一个非常不同的概念。该学习系统在此上下文中称为代理,它可以观察环境、选择和执行操作,并获得回报(或负回报形式的惩罚,如图下所示)。然后,它必须自己学习什么是最好的策略,称为策略,以获得最大的回报。策略定义了在给定的情况下,代理应该选择什么操作。

30wkWD.png

批量和在线学习(Batch and Online Learning ):

用于对机器学习系统进行分类的另一个标准是,系统是否能够从输入的数据流逐渐地学习。

批量学习(Batch learning ):

在批量学习中,系统不能渐进地学习:它必须使用所有可用的数据进行训练。这通常会花费大量的时间和计算资源,所以通常是离线完成的。首先对系统进行培训,然后将其投入生产并在不学习的情况下运行;它只是应用它所学到的东西。这叫做离线学习(offline learning )

如果希望批处理学习系统了解新数据(例如一种新类型的垃圾邮件),则需要从头开始在整个数据集上培训系统的新版本(不仅是新的数据,还有旧的数据),然后停止旧的系统,用新的系统替换它。

这个解决方案很简单,而且通常工作得很好,但是使用完整的数据集进行培训可能会花费很多小时,所以您通常只需要每24小时甚至每周培训一个新系统。如果你的系统需要适应快速变化的数据(例如预估值股票价格),那么你需要一个更有反应性的解决方案。同时面对大数据量的任务我们几乎不会使用批量学习

在线学习(Online learning ):

在在线学习中,您可以通过顺序地向系统提供数据实例来增量地培训系统,这些数据实例可以是单个的,也可以是小批量的。每个学习步骤都是快速和低代价的,因此系统可以在新数据到达时动态地学习,这是一个例子:

30TMKs.png

在线学习可以用无法装进主存的巨大数据集来训练系统(称为核外学习out-of-core learning ),该算法加载部分数据,在该数据上运行一步训练,然后重复该过程,直到它在所有数据上运行,如下图就是这样一个例子:

30TxZq.png

在线学习系统的一个重要参数是它们应该以多快的速度适应不断变化的数据:这称为学习率(learning rate)

如果您设置了一个高的学习率,那么您的系统将很快适应新的数据,但是它也会很快忘记旧的数据(您不希望垃圾邮件过滤器只标记它显示的最新类型的垃圾邮件)。

相反,如果你设定一个较低的学习率,系统会有更多的惯性;也就是说,它将学习得更慢,但它也将对新数据中的噪声或非代表性数据点的序列不那么敏感

在线学习面临的一大挑战是,如果向系统输入错误的数据,系统的性能将逐渐下降。例如,错误的数据可能来自于机器人传感器的故障。了减少这种风险,您需要密切监视您的系统,并在检测到性能下降时立即关闭学习(并可能恢复到以前的工作状态)。您可能还希望监视输入数据并对异常数据做出反应(例如,使用异常检测算法)。

基于实例和基于模型的学习(Instance-Based Versus Model-Based Learning ):

另一种对机器学习系统进行分类的方法是看它们如何泛化(generalize)
大多数机器学习任务都是关于预测的。这意味着,给定大量的训练示例,系统需要能够将其推广到以前从未见过的示例。对培训数据进行训练有良好的效果是很好,但还不够;真正的目标是在新实例上表现良好。

泛化主要有两种主要方法:基于实例的学习基于模型的学习

基于实例的学习(Instance-based learning )

除了标记与已知的垃圾邮件相同的电子邮件外,您的垃圾邮件过滤器还可以标记与已知的垃圾邮件非常相似的电子邮件。这需要衡量两封电子邮件之间的相似性。一个(非常基本的)度量两封邮件之间的相似度的方法是计算它们共有的字数。如果一封已知的垃圾邮件中有很多单词,系统会将其标记为垃圾邮件。

这称为基于实例的学习:系统记住示例,然后使用相似度度量将其推广到新的案例

30HB4K.png

基于模型的学习( Model-based learning )

从一组例子中归纳出另一种方法是建立这些例子的模型,然后使用该模型进行预测。这叫做基于模型的学习

30qqkq.png

例如,假设你想知道钱是否能让人快乐,那么你可以下载经合组织网站上的美好生活指数数据,以及国际货币基金组织网站上的人均GDP统计数据。然后你加入表格,并根据人均GDP排序。

30LZcD.png

30LuBd.png

这里似乎确实有一种趋势! 虽然数据是有噪声的(即(部分是随机的),看起来生活满意度或多或少随着国家人均GDP的增长呈线性增长。所以你决定将生活满意度建模为人均GDP的线性函数。这一步被称为模型选择:你选择了一个只有一个属性的线性的生活满意度模型(人均GDP)

$life_satisfaction=θ_0 +θ_1× GDP_per_capita $

这个模型有两个模型参数,$θ_0,θ_1$通过调整这些参数,可以使你的模型代表任何线性函数,如图。

30Lo8K.png

您可以定义一个效用函数(或适应度函数)来度量模型的好坏,也可以定义一个成本函数来度量模型的好坏。

对于线性回归问题,人们通常使用一个成本函数来度量线性模型的预测与训练示例之间的距离;目标是最小化这个距离。

线性回归算法的用武之地:你给它输入你的训练样本,它就会找到使线性模型最适合你的数据的参数。

30XPW6.png

可视化创建散点图,然后训练一个线性模型并进行预测:

Training and running a linear model using Scikit-Learn

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
# Load the data
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]

oecd_bli = pd.read_csv("oecd_bli_2015.csv", thousands=',')
gdp_per_capita = pd.read_csv("gdp_per_capita.csv",thousands=',',delimiter='\t',
encoding='latin1', na_values="n/a")
# Prepare the data
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"]]
# Visualize the data
country_stats.plot(kind='scatter', x="GDP per capita", y='Life satisfaction')
plt.show()
# Select a linear model
lin_reg_model = LinearRegression()
# Train the model
lin_reg_model.fit(X, y)
# Make a prediction for Cyprus
X_new = [[22587]] # Cyprus' GDP per capita
print(lin_reg_model.predict(X_new)) # outputs [[ 5.96242338]]

机器学习的主要挑战( Main Challenges Of Machine Learning)

简而言之,由于您的主要任务是选择一种学习算法并对其进行数据训练,因此可能出错的两件事是“坏算法”和“坏数据”。让我们从坏数据的例子开始。

数据层面

培训数据数量不足(Insufficient Quantity of Training Data )

机器学习还没有完全实现;大多数机器学习算法需要大量的数据才能正常工作。即使是非常简单的问题,你通常也需要成千上万的例子。

在2001年发表的一篇著名论文中,微软研究员Michele Banko和Eric Brill 指出,包括相当简单的机器学习算法在内的各种不同的机器学习算法,一旦获得了足够的数据,在解决自然语言消除歧义的复杂问题上,其表现几乎是一样的好,如图:

3Lfl26.png

这无疑体现了数据相对于算法的重要性。

非代表性的训练数据(Nonrepresentative Training Data )

为了更好地泛化,重要的是您的训练数据要能够代表您想泛化到的新案例。无论您使用基于实例的学习还是基于模型的学习,这都是正确的。

例如,我们之前用于训练线性模型的国家集并不完全具有代表性;有几个国家失踪了。

3LhkFA.png

如果你用这些数据训练一个线性模型,你会发现 :而旧的模型用虚线表示。正如您所看到的,添加几个缺失的国家不仅会显著地改变模型,而且还清楚地表明,这样一个简单的线性模型可能永远不会很好地工作。非常富裕的国家似乎并不比中等富裕的国家更幸福(事实上,他们似乎更不幸福),相反,一些贫穷的国家似乎比许多富裕的国家更幸福。

通过使用非代表性的训练集,我们训练了一个不太可能做出准确预测的模型,特别是对于非常贫穷和非常富裕的国家。
使用一个能代表你想要了解的案例的培训集是至关重要的。这通常比听起来要困难:如果样本太小,就会产生采样噪声(即噪声)。但是,如果抽样方法有缺陷,即使是非常大的样本也可能不具有代表性。这叫做抽样偏差(sampling bias )

低质量数据(Poor-Quality Data )

显然,如果您的训练数据充满了错误、异常值和噪声(例如,由于质量度量不佳),那么系统将更难检测底层模式,因此您的系统不太可能表现良好。

无关的特性(Irrelevant Features)

机器学习项目成功的一个关键部分是提供一组良好的feature来进行训练,这叫做特征工程(feature engineering )

•特性选择:在现有特性中选择最有用的特性进行培训。

•特征提取:结合现有的特征,生成更有用的特征(正如我们前面看到的,降维算法可以提供帮助)。

•通过收集新数据来创建新功能

算法层面

数据过拟合(overfitting the training data)

假设你在国外旅游,出租车司机把你敲诈了一顿。你可能会说那个国家所有的出租车司机都是小偷。过度概括是我们人类经常做的事情,不幸的是,如果我们不小心,机器也会落入同样的陷阱。

在机器学习中,这被称为过度拟合:它意味着模型在训练数据上表现良好,但不能很好地泛化。

比如预测GDP与幸福指数关系,拟合出了一个十分符合数据集的函数,但是很明显这是十分不可信的。

3L7t61.png

当模型相对于训练数据的数量和噪声过于复杂时,就会发生过拟合。可能的解决办法是:
•通过选择参数较少的模型来简化模型(例如,一个线性模型而不是一个高次多项式模型),通过减少训练数据中的属性数量或对模型进行约束

•收集更多的培训数据

•减少训练数据中的噪音(例如,修复数据错误并删除异常值)

为了简化模型并降低过度拟合的风险而对模型进行约束称为正则化(regularization)。比如线性模型我们定义了两个参数$θ _0$和$θ _1$,所以这就给了算法两个维度的方向来训练,如果我们规定$\theta_0=0$,这样就只剩下了一个维度,也就是说直线只能进行上下移动,那么训练出的是一个均值的模型。如果我们允许算法修改$θ _1$,但我们迫使它让它很小,那么学习算法将有效地在一到两个维度之间。它将产生一个比有两个自由度时更简单的模型,但比只有一个自由度时更复杂。我们希望在完美地拟合数据保持模型足够简单以确保它能够很好地泛化之间找到适当的平衡

3LjWxe.png

学习过程中需要应用的正则化的数量可以由一个超参数控制。超参数是机器学习算法的参数(不是模型的参数)。因此,它不受学习算法本身的影响;它必须在训练前设置,并在训练中保持不变。如果你将正则化超参数设置为一个非常大的值,你会得到一个几乎平坦的模型(斜率接近于零);学习算法几乎肯定不会对训练数据进行过度拟合,但找到一个好的解决方案的可能性较小。调优超参数是构建机器学习系统的一个重要部分。

测试与验证(Testing and Validating)


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!