简介
你是一个正在进入机器学习领域的Python程序员吗? 掌握Scikit-Learn就是一个开启你的旅程的很好的方式。
使用Scikit-Learn进行一些分类是应用你所学到的知识的一种直接而简单的方法,通过使用一个用户友好的、文档良好且健壮的库来实现这些分类可以让机器学习概念更具体化。
什么Scikit-Learn?
Scikit-Learn是一个Python库,由David Cournapeau在2007年首次开发。它包含一系列容易实现和调整的有用算法,可以用来实现分类和其他机器学习任务的目的。
Scikit-Learn使用SciPy作为基础,因此在使用Scikit-Learn之前必须安装这个库的基础堆栈。
定义术语
Python学习交流群:1004391443
在我们进一步探索Scikit-Learn之前,让我们花一分钟来定义我们的术语。理解描述Scikit-Learn功能时使用的词汇是很重要的。
首先,机器学习系统或网络接受输入和输出。机器学习框架的输入通常被称为“特征”。
特征本质上与科学实验中的变量相同,它们是被观察现象的特点,可以用某种方式量化或测量。
当这些特性被输入到机器学习框架中时,该网络就会尝试识别这些特征之间的相关模式。然后使用这些模式生成框架/网络的输出。
框架的输出通常被称为“分类”,因为输出特征会具有一些网络给予它们的标签,它是一些关于输出属于哪个类别的假设。
在机器学习上下文中,分类是一种监督学习。监督学习是指输入网络的数据已经被标记,重要的特征/属性已经预先被划分为不同的类别。
这意味着网络知道输入的哪些部分是重要的,并且还有一个目标或标准答案,网络可以根据它来检查自己。分类的一个例子是把一堆不同的植物分类成不同的种类,比如蕨类植物或被子植物。这个任务可以通过一个决策树(Scikit-Learn中的一种分类器)来完成。
相反,无监督学习是指输入网络的数据没有被标记,而网络必须自己学习哪些特性是最重要的。如前所述,分类是一种类型的监督学习,因此我们在本文中将不讨论非监督学习方法。
模型的训练过程是将数据输入神经网络,让神经网络学习数据的模式的过程。训练过程接收数据并提取数据集的特征。在一个监督分类任务的训练过程中,网络既要传递训练数据的特征,又要传递训练数据的分类。但是,在测试过程中,只给网络传入特征。
测试过程是对网络学习到的模式进行测试的地方。特征被提供给网络,并且网络必须预测其分类。提供给网络的数据被分为训练集和测试集,这是两个不同的输入集。你不能使用训练分类器的同一个数据集来测试该分类器,因为这个模型已经学习了这组数据的模式,所以结果可能会偏差很大。
相反,如果数据集被分割成训练集和测试集,那么这样一来,一个是用来训练分类器的数据集,而另一个则是分类器从未见过的数据集。
不同类型的分类器
Scikit-Learn提供了对多种不同分类算法的简单访问。这些分类器包括:
- K最近邻算法
- 支持向量机
- 决策树分类器/随机森林
- 朴素贝叶斯
- 线性判别分析
- 逻辑回归
有很多关于这些分类器如何运行的文献,你也可以在Scikit-Learn的网站上找到它们的简要解释。
由于这个原因,我们不打算在这里深入研究它们是如何工作的,但是会对分类器的工作方式进行简要的说明。
K最近邻分类算法
K最近邻分类算法通过检查某个测试示例到某个训练示例的已知值之间的距离来进行计算。能给出训练点与测试点之间最小距离的一组数据点/类就是该算法所选择的类。
决策树
决策树分类器通过根据不同的标准将数据集分解为越来越小的子集来进行计算。它会使用不同的排序标准来划分数据集,每划分一次,示例的数量就会减少。
一旦网络将数据划分为一个示例,这个示例将被放入一个对应于一个键的类中。当多个随机的森林分类器链接在一起时,它们就被称为随机森林分类器。
朴素贝叶斯
一个朴素贝叶斯分类器会确定一个例子属于某个类的概率,它会计算在某个输入事件已经发生的情况下,某个事件发生的概率。
当它进行这种计算时,它会假定一个类的所有预测器都对结果具有相同的影响,即预测器是相互独立的。
线性判别分析
线性判别分析的工作原理是通过降低数据集的维度,将所有数据点投影到一条直线上。然后根据这些点与所选点或矩心的距离将它们组合成类。
和你所猜想的一样,线性判别分析是一种线性分类算法,最好在数据具有线性关系时使用。
支持向量机
支持向量机的工作原理是在不同的数据点集群之间画一条线,将它们分组到一些类中。线的一边的点是一类,另一边的点属于另一类。
分类器会尝试最大化它所绘制的线与它两边的点之间的距离,以增加它对哪个点属于哪类的置信度。当测试点被绘制出来时,它们在直线的哪边就是它们所属的类。
逻辑回归
逻辑回归以二元范围 (0或1)输出关于测试数据点的预测。如果某个东西的值为0.5或以上,则将其划分为第1类,如果值低于0.5就属于第0类。
每个特征也只有0或1的分类。逻辑回归是一种线性分类器,因此当数据之间存在某种线性关系时就会用到它。
分类任务的例子
分类任务是将样本放入两个或多个类中的任何任务。确定一个图片是猫还是狗就是一项分类任务,就像根据酸度和酒精含量等特征确定一瓶酒的质量一样。
根据手头的分类任务,你可能希望使用不同的分类器。例如,逻辑回归模型最适合于二元分类任务,即使存在多变量逻辑回归模型。
随着你获得的分类器经验越多,你就会对何时使用哪个分类器有更好的感觉。但是,通常的做法是实例化多个分类器,并比较它们之间的性能,然后选择性能最好的分类器。
实现一个分类器
现在我们已经讨论了Scikit-Learn为我们提供的各种分类器,我们来看看如何实现一个分类器。
实现分类器的第一步是将所需要的分类器导入到Python中。我们来看看逻辑回归的import语句:
下面是本文讨论的其他分类器的import语句:
Scikit-Learn还有其他分类器,它们各自的文档页面会展示如何导入它们。
在导入之后,你就必须实例化分类器。实例化是在Python程序中将分类器转换成存在的实例的过程,也就是创建分类器/对象的实例。
这通常只需要创建一个变量并调用与分类器关联的函数来完成:
现在需要对分类器进行训练。要做到这一点,分类器必须与训练数据相匹配。
训练特征和训练分类通过fit命令传入分类器:
分类器模型在训练数据上进行训练后,可以对测试数据进行预测了。
这很容易做到,你可以调用分类器上的预测命令,并为其提供预测所需的参数,这些参数是你的测试数据集中的特征:
实例化、拟合/训练和预测这些步骤是Scikit-Learn中分类器的基本工作流。
然而,分类器的处理只是使用Scikit-Learn进行分类的一部分。在Scikit-Learn中分类的另一部分是处理数据。
为了理解处理分类器和处理数据是怎样作为一个整体分类任务结合在一起的,我们花点时间来理解机器学习管道。
机器学习管道
机器学习管道包括以下步骤:准备数据、创建训练/测试集、实例化分类器、训练分类器、进行预测、评估性能、调整参数。
在数据集上训练分类器的第一步是准备数据集——将数据转换为分类器所需的正确形式,并处理数据中的任何异常。如果数据中有缺失值、异常值或任何其他异常,这些数据点都要被处理,因为它们会对分类器的性能产生负面影响。这一步称为数据预处理。
数据预处理完成后,必须将数据分解为训练集和测试集。我们之前已经讨论了创建训练和测试集的基本原理,这可以通过一个非常有用的名为traintestsplit的函数在Scikit-Learn中轻松实现。
如前所述,分类器必须进行实例化并在训练数据上进行训练。然后就可以利用分类器进行预测。通过将分类器的预测与测试数据中分类的实际已知值进行比较,你就可以测量该分类器的准确度。
将假定的分类与实际分类进行比较并评估分类器的方法有很多。我们稍后将讨论这些不同的评估指标。现在,要知道,在测量了分类器的准确的之后,你可能会回过头来调整你的模型的参数,直到达到你满意的准确度为止(因为你的分类器不太可能在第一次运行时就达到你的期望)。
让我们看一个机器学习管道的例子,从处理数据到进行评估。
示例分类器实现
由于iris数据集非常常见,Scikit-Learn实际上已经具有了,我们可以用以下命令进行加载:
不过,我们将在这里加载一个CSV文件,以便你了解如何加载和预处理数据。你可以在这里(https://www.kaggle.com/uciml/iris )下载这个csv文件。
只需将数据文件放在与Python文件相同的目录中。Pandas库有一个简单的加载数据的方法,即read_csv():
因为数据集准备得很好,所以我们不需要进行很多预处理。我们可能会想做的一件事是删除“ID”列,因为它只是对示例所在行的一个表示。
由于这一列并没有任何帮助,所以我们可以使用drop()函数从数据集中删除它:
现在我们需要定义特征和分类。我们可以使用Pandas库通过对数据表进行切片,并使用iloc()选择特定的行/列来轻松地实现这一点:
上面的切片符号会选择除最后一列(这是我们的分类,物种)之外的每一行和每一列。
或者,你也可以通过使用括号符号和传递列标头来选择你感兴趣的某些数据集特性:
现在我们已经有了我们想要的特征和分类,我们可以使用sklearn的train_test_split()函数将数据分割为训练集和测试集:
你可能想打印结果,以确保你的数据正在按照你所期望的方式被解析:
现在我们可以实例化这个模型。我们尝试使用两个分类器,一个支持向量分类器和一个k最近邻分类器:
现在我们来适应分类器:
以上调用已经训练了这个模型,现在我们可以进行预测并将预测结果存储在一个变量中:
现在我们应该评估一下分类器的运行情况。有多种方法可以用来评估一个分类器的性能,你可以在下面阅读关于这些不同方法的更多信息。
在Scikit-Learn中,你只需要输入与你测试标签中存储的真实分类相对的预测结果即可:
作为参考,下面是我们得到的关于指标的输出:
乍一看,KNN的表现似乎更好。这是SVC的混淆矩阵:
这可能有点难以解释,但是每个类的正确预测数都是从左上角到右下角的对角线上运行的。查看下面的更多信息。
最后,这是KNN分类报告的输出:
评估分类器
在评估你的分类器时,有几种不同的方法可以用来测量它的性能。
分类准确度
分类准确度是所有评估准确性的方法中最简单的,也是最常用的。分类准确度就是正确预测的数量除以所有预测或者正确预测与总预测的比例。
虽然它可以让你快速了解分类器的执行情况,但是最好在每个类中的观察值/示例数量大致相当时再使用它。因为这种情况不会经常发生,所以你最好使用另一种指标方法。
对数损失
对数损失,或LogLoss,本质上是评估分类器对其预测结果的自信程度。LogLoss会返回给定类中一个示例中成员的概率,将它们加起来表示分类器的总体信心。
针对预测的值取值为1到0,1表示完全自信,0表示不自信。损失,或者信心的总缺乏度,以负数的形式返回,0表示一个完美的分类器,所以值越小越好。
ROC曲线下与坐标轴围成的面积(AUC)
这是一个仅用于二元分类问题的指标。曲线下的面积代表了模型正确区分正负样本的能力,以及区分一个类和另一个类的能力。
落在曲线下的面积总和为1.0,这代表一个完美的分类器。这意味着AUC为0.5基本上和随机猜测一样好。ROC曲线根据灵敏度(真阳率/召回率)和特异性(真阴率)计算。你可以在这篇ROC曲线文章中阅读更多关于这些计算的内容。
混淆矩阵
混淆矩阵是一个表或图表,表示模型相对于两个或多个类的准确性。模型的预测用x轴表示,而结果/准确度用y轴表示。
这个单元格中被填入了模型做出的预测数量。正确的预测可以在从左上角到右下角的对角线上找到。你可以在这里阅读更多关于解释混淆矩阵的内容。
分类报告
分类报告是一种Scikit-Learn的内置指标,专门针对分类问题而创建。使用分类报告可以让你快速直观地了解模型的执行情况。召回率会将你的模型标记为类A(某些给定的类)的样本数量与类A的样本总数进行比较,这在报告中会表示出来。
该报告还返回预测和f1得分。精确度是您的模型被标记为类A的实例的百分比,它实际上属于类A(真阳性对假阳性),而f1-score是精确度和召回率的平均值。
结论
为了进一步加深你对Scikit-Learn的理解,你最好多了解一些可用的不同分类算法。一旦你理解了这些算法,阅读更多关于如何评估分类器的内容。
分类的许多细微差别只是随着时间和实践而来的,但是如果你按照本指南中的步骤,那你将会在成为一个使用Scikit-Learn处理分类任务的专家的道路上走得很好。