使用 Python 和 scikit-learn 的机器学习概念
介绍
本指南将讨论监督式机器学习算法。当在训练模型之前已知数据集的关注特征时,这些算法非常有用。例如,本指南将首先介绍分类。在分类中,数据集中的每个观察值对应于一组有限标签或类别中的一个。其任务是(准确地)预测任何新观察值的适当标签。这种监督方法与无监督方法(例如聚类)形成对比。无监督机器学习算法的任务是找到数据集中观察值中常见的特征。同样,本指南将重点介绍监督式方法。
如果您想继续学习,我建议您使用 Google Colab。这是一款基于 Jupyter 笔记本的免费浏览器工具。要开始使用,您需要做的就是在较新的浏览器中访问 https://colab.research.google.com/(Google Chrome 效果最佳),然后使用 Gmail 或与 Google 帐户关联的其他电子邮件登录。登录后,创建一个新的 Python 3 笔记本。
在新笔记本中,点击右上角的连接链接,配置并将笔记本连接到在 Google Compute Engine 上运行的虚拟机。连接后,您将能够在单元格中输入 Python 代码,然后按 Shift-Enter 或点击单元格左侧的运行按钮来执行它。这类似于 Chrome 开发者工具中的 JavaScript 控制台,但它的功能要多得多!
如果您想了解有关 Jupyter Notebook 的更多信息(其中大部分适用于 Google Colab),请查看 Pluralsight 目录中我的视频课程“ Jupyter Notebook 和 Python 入门”。
分类的概念
假设我们要教一组孩子自行车、汽车和飞机之间的区别,我们将通过向他们展示每种车辆的带标签的图片来做到这一点。这样做的目的是让孩子们开始将每种交通工具的特征与相应的标签联系起来。他们可能会注意到自行车有轮子但没有发动机,只能搭载一名乘客,并且在地面上行驶。对于汽车,他们可能会注意到有轮子、机动化、搭载一名以上乘客并且也在地面上行驶的车辆。飞机有轮子并且是机动化的,但它们可能搭载一名、几名或多名乘客,并且至少在大多数时间不在地面上行驶。
每辆车的这些特征在机器学习术语中称为特征。在这种情况下,我们可能会关注四个特征:
- 它有轮子吗?
- 它是机动的吗?
- 它可载多少名乘客?
- 它是在地面还是在空中飞行?
在上一段中,我们将一组特征与每辆车或标签关联起来:
- 自行车
- 汽车
- 飞机
如果我们给孩子们展示足够多的图片,他们大多数时候都能将公共汽车或轿车的图片与“汽车”这个标签联系起来。无论是双引擎螺旋桨飞机还是 737,他们都会断定它是一架飞机。但是如果我们向他们展示一张滑板的图片呢?滑板有轮子并在地面上行驶,所以它不是飞机。但它没有发动机,所以它不是汽车。这意味着,通过排除法,它一定是自行车,对吗?显然这是不正确的,但它揭示了分类的一个重要点和潜在错误。每个观察结果都将与有限标签集之一相关联。没有“以上都不是”。
scikit-learn 中的分类
我们在上一节中讨论的过程显然不是计算机尝试分类的方式。我们描述了人类会采取的直观步骤。另一方面,计算机以逻辑和数学的方式运行,而数学并不总是直观的。
幸运的是,Python 社区提供了 scikit-learn 包,使我们免受机器学习算法(即数学)大部分内部工作的影响,因此我们可以专注于通过超参数配置算法。现在,这是一个大词,但作为开发人员,我们对超参数的概念有一个有用的类比。
假设我们要生成一个密码。不同的应用程序和服务对密码有不同的要求,例如长度、字符多样性或某些可能不允许的字符。一种解决方案是编写一个类并将要生成的密码长度的属性附加到该类,等等。我们只需创建该类的一个实例,为属性分配值以配置生成的密码的强度,调用该类上的方法来生成它,并使用返回值作为密码。该类的属性在概念上类似于超参数。基本上,超参数允许我们修改流程,而不必涉及细节。
而且 scikit-learn 将分类算法实现为类!我们需要做的就是创建类的实例,设置超参数,然后调用一个方法来通过提供要分析的数据来训练模型。这个训练过程类似于密码生成的细节。我们不需要知道或关心它是如何工作的。我们只需要关注属性或超参数,以便根据我们的具体任务定制流程。
数据困境
但是这个模型呢?机器学习中的模型是通过分析(在监督学习的情况下)数据集中的标记观察值而得出的“知识”的数值和数学表示。它将是接受新数据并预测标签的模型。但必须先训练模型。为此,我们需要数据,大量生产数据。无论如何,数据都需要清理/规范化/准备。这个主题本身就值得写一系列指南,而且它不是机器学习特有的。因此,我不会在这里花太多时间。相反,我只会使用 scikit-learn 附带的一些示例数据集。
其中之一是葡萄酒数据集。要在 Google Colab(已安装 scikit-learn)中加载它,请从sklearn.datasets模块导入load_wine()函数:
from sklearn.datasets import load_wine
wine_data = load_wine()
load_wine()的返回值是一个字典。
wine_data.keys()
DESCR键是对数据集结构的解释。要读取它,请使用print()函数来维护格式:
print(wine_data['DESCR'])我们主要关注的是数据和目标键。数据键包含特征的值。在此数据集中,特征是各种葡萄酒的化学性质。要查看它们,请查看wine_data字典中的feature_names键。目标键包含葡萄酒的标签。
wine_data['目标']
都是整数。准确地说,这是目标的表示。Scikit-learn 和一般的机器学习更喜欢数字而不是字符串。如果你想查看目标的实际名称,请获取 target_names键:
wine_data['目标名称']
当然,这并没有太多描述性。但重点是我们有三个不同的标签,数据集中的每个观察值都对应这三个标签之一。现在我将使用 pandas 将数据排列在 DataFrame 中,以便在训练模型时更易于使用。
import pandas as pd
wine_data_frame = pd.DataFrame(data=wine_data['data'], columns=wine_data['feature_names'])
wine_data_frame['class'] = wine_data['target']
wine_classes = [wine_data_frame[wine_data_frame['class'] == x for x in range(3)]
testing_data = []
for wine_class in wine_classes:
row = wine_class.sample()
testing_data.append(row)
wine_data_frame = wine_data_frame.drop(row.index)
我在这里所做的就是将DataFrame按类别分成wine_classes。wine_classes也是DataFrame,我使用sample()方法从中随机选择一个观察值。这样,我就能保证从每个葡萄酒类别中获取一个样本进行测试。为了确保模型不在测试数据上进行训练,我从 wine_data_frame 中删除了每个测试行。这不是生产的最佳方法,但对于如此小的数据集来说已经足够了。(稍后我们将看到使用 scikit-learn 的更好方法。)
现在让我们训练模型。
了解邻居
在考虑分类算法时,scikit-learn 提供了大约十几种选择。根据具体情况,有些选择比其他选择更好。但一个好的通用算法是 K-Nearest Neighbors。虽然对 K-Nearest Neighbors(以下简称 KNN)的完整解释超出了本指南的范围,但这里还是简单介绍一下。
让我们简单一点,暂时假设观测值有两个特征。这样我们就可以使用 2D 散点图轻松地将它们可视化。
我将添加新数据,并用大绿点进行分类。
为了使用 KNN 对这些新数据进行分类,算法将测量新点与最接近新点的多个点(或邻居)之间的距离。利用这些测量值,算法将计算出每个类别中有多少个邻居,计数最高的类别就是新点的预测标签。在本例中,算法将预测橙色点所代表的类别。
如何用 scikit-learn 做到这一点?正如我之前所说,每个分类算法都有类。对于 KNN,该类是来自sklearn.neighbors模块的KNeighborsClassifier。
从 sklearn.neighbors 导入 KNeighborsClassifier
现在我可以创建该类的一个实例。
模型 = KNeighborsClassifier()
并使用fit()方法训练模型。fit () 的参数是训练数据集中的特征和目标,位于wine_data_frame中。
模型.拟合(wine_data_frame[wine_data_frame.columns[:-1]].值,wine_data_frame[wine_data_frame.columns[-1]])
最后,使用predict()方法,我们可以将新数据传递给模型并得到预测。
模型.预测(测试数据[0][:-1].重塑(1,-1)
由于这返回 0,对应于第一个测试行中的目标,因此到目前为止模型运行良好。我将其余的测试数据集留给读者作为练习。如果您想知道,reshape ()方法将测试数据中的值从行向量转换为列向量。
您可能会问自己, KNeighborsClassifier使用多少个邻居进行预测?答案是您告诉它多少个邻居。默认情况下,这个数字是 5,但您可以使用KNeighborsClassifier初始化程序中的n_neighbors=关键字参数更改它。由于它用于配置 KNeighborsClassifier ,因此它是一个超参数。
模型 = KNeighborsClassifier(n_neighbors=3)
scikit-learn 中还有许多其他分类算法,例如朴素贝叶斯和支持向量机 (SVM)。确定哪种算法最好使用超出了本指南的范围。但是,使用它们的过程基本与KNeighborsClassifier相同:
- 创建类的新实例
- 设置超参数
- 训练模型
- 做出预测
这种一致的 API 正是 scikit-learn 的美妙之处!
回归
监督学习中并非所有问题都有一组众所周知的目标值。在这种情况下,目标可能存在于无法枚举的连续值范围内。这类问题称为回归,scikit-learn 也提供了回归类。
与分类一样,我们需要一个数据集。sklearn.datasets模块中的fetch_california_housing()方法将下载包含加利福尼亚州房价数据的数据集。
housing_data = sklearn.datasets.fetch_california_housing()
与葡萄酒数据集一样,此字典包含data、target和feature_names的键。但是,它不提供目标名称,因为我们不知道确切的目标 - 它们是连续的。在训练模型之前,我想介绍机器学习和 scikit-learn 中的另一项任务:特征缩放。
看一下数据中的前五个观察结果:
np.set_printoptions(suppress=True) # suppress scientific notation
housing_data['data'][:5]
如您所见,数据的范围不同,这可能会在准确训练模型时引起问题。特征缩放将对值进行规范化,使它们适合一个共同的范围,但仍保持彼此之间的关系。Scikit-learn在sklearn.preprocessing模块中提供了MinMaxScaler类,它只需获取数据集并返回缩放后的值:
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler()
X = sc.fit_transform(housing_data[‘data’])
y = sc.fit_transform(housing_data[‘target’].reshape(1, -1)) # reshape() transforms row vector to column vector
大写字母X通常用于表示机器学习数据集中的特征,小写字母y则用于表示目标。看一下缩放特征中的前五行:
X[:5]
现在范围是一致的。为了将此数据集拆分为训练集和测试集,我将使用sklearn.model_selection模块中的train_test_split()函数。它采用特征、目标和用于测试的数据百分比。返回值是一个包含训练特征、测试特征、训练目标和测试目标的元组:
训练特征、测试特征、训练目标、测试目标 = 训练测试拆分(X,y,测试大小=0.2)
Scikit-learn 包含许多回归类,但我将使用最简单的类,因为它们都遵循类似的模式。
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(training_features, training_targets)
model.predict(testing_features[0].reshape(1, -1))
testing_targets[0]
我们之前看过这部电影。API 与用于分类的 API 相同。我们要做的就是将问题与算法相匹配,并在 scikit-learn 中选择适当的类。为了验证模型的性能,我将创建一个快速可视化。
predictions = model.predict(testing_features)
import matplotlib.pyplot as plt
%matplotlib in
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~