Python机器学习:Scikit-Learn教程

2018-07-25 16:40:56 浏览数 (1)

一个易于理解的scikit-learn教程,可以帮助您开始使用Python机器学习。

使用Python进行机器学习

机器学习是计算机科学的一个分支,研究可以学习的算法设计。

典型的任务是概念学习,功能学习或“预测建模”,聚类和发现预测模式。例如,通过经验或指示观察到的可用数据来学习这些任务。

该学科带来的希望是将经验纳入其任务最终将改善学习。但是这种改进需要以这样的方式发生,即学习本身变得自动化,以便像我们这样的人类不再需要干涉是最终目标。

今天的scikit-learn教程将向您介绍Python机器学习的基础知识:

  • 您将学习如何使用Python及其库在主要组件分析(PCA)的帮助下探索数据matplotlib
  • 并且您将通过规范化预处理数据,并将数据拆分为训练和测试集。
  • 接下来,您将使用众所周知的KMeans算法构建无监督模型,使此模型适合您的数据,预测值并验证您构建的模型。
  • 另外,您还将看到如何使用支持向量机(SVM)构建另一个模型来对数据进行分类。

如果您对R教程更感兴趣,请查看我们的机器学习与R for Beginners教程。

或者,在Python课程中查看DataCamp的监督学习与scikit-learn和Unsupervised Learning!

加载数据集

关于数据科学中任何事情的第一步是加载数据。这也是这个scikit-learn教程的起点。

该学科通常适用于观察到的数据。您可以自己收集此数据,也可以浏览其他来源以查找数据集。但如果你不是研究员或参与实验,你可能会做后者。

如果您是新手,并且想要自己解决问题,那么找到这些数据集可能会成为一项挑战。但是,您通常可以在UCI机器学习库或Kaggle网站上找到好的数据集。另外,请查看此KD Nuggets列表中的资源。

现在,你应该热身,不要担心自己找到任何数据,只需加载digits一个名为Python库的数据集scikit-learn

有趣的事实:您是否知道该名称源于此库是围绕SciPy构建的科学工具箱?顺便说一句,那里不只有一个scikit。此scikit包含专门用于机器学习和数据挖掘的模块,它解释了库名称的第二个组件。:)

要加载数据,请datasets从中导入模块sklearn。然后,您可以使用load_digits()方法datasets来加载数据:

  • script.py
代码语言:javascript复制
# Import `datasets` from `sklearn`
from sklearn import ________

# Load in the `digits` data
digits = datasets.load_digits()

# Print the `digits` data 
print(______)

请注意,该datasets模块包含其他加载和获取常用参考数据集的方法,如果需要人工数据生成器,您还可以依赖此模块。此外,此数据集也可通过上面提到的UCI存储库获得:您可以在此处找到数据。

如果您决定从后一页中提取数据,那么您的数据导入将如下所示:

  • script.py
代码语言:javascript复制
# Import the `pandas` library as `pd`
import ______ as __

# Load in the data with `read_csv()`
digits = pd.read_csv("http://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra", header=None)

# Print out `digits`
print(______)

请注意,如果您下载这样的数据,则数据已经在训练和测试集中分开,由扩展名.tra.tes。您需要加载这两个文件来详细说明您的项目。使用上面的命令,您只需加载训练集。

提示:如果您想了解有关使用Python数据操作库Pandas导入数据的更多信息,请考虑在Python课程中使用 DataCamp的导入数据。

使用DataCamp学习Python for Data Science

探索您的数据

首次使用数据集时,最好通过数据描述并查看您已经学到的内容。当谈到时scikit-learn,您不会立即获得这些信息,但是如果您从其他来源导入数据,通常会出现数据描述,这些信息已经足以收集到您的一些数据。数据。

但是,这些见解不仅仅足以进行您要执行的分析。您确实需要掌握有关数据集的良好工作知识。

对数据集执行探索性数据分析(EDA),就像本教程现在所拥有的那样,可能看起来很困难。

你从哪里开始探索这些手写数字?

收集有关您数据的基本信息

假设您没有检查任何数据描述文件夹(或者您想要仔细检查已经提供给您的信息)。

然后你应该从收集基本信息开始。

当您digitsscikit-learn datasets模块的帮助下加载数据后打印出数据时,您会注意到已经有很多可用的信息。您已经了解了诸如目标值和数据描述之类的信息。您可以digits通过该属性访问数据data。同样,您也可以通过target属性和描述通过DESCR属性访问目标值或标签。

要查看您可以使用哪些密钥来了解您的数据,您可以运行digits.keys()

在以下DataCamp Light块中尝试全部:

  • script.py
代码语言:javascript复制
# Get the keys of the `digits` data
print(digits.______)

# Print out the data
print(digits.____)

# Print out the target values
print(digits.______)

# Print out the description of the `digits` data
print(digits.DESCR)

您可以(双重)检查的下一件事是您的数据类型。

如果您曾经read_csv()导入数据,那么您将拥有一个仅包含数据的数据框。没有任何描述组件,但您可以诉诸于,head()tail()检查您的数据。在这些情况下,阅读数据描述文件夹总是明智的!

但是,本教程假定您使用库的数据,digits如果您不熟悉库,则变量的类型不是那么简单。查看第一个代码块中的打印输出。你会看到digits实际上包含numpy数组!

这已经是一些非常重要的信息。但是你怎么访问这些arays?

实际上很简单:使用属性来访问相关的数组。

请记住,您已经看过打印时可用的属性digits.keys()。例如,您具有data隔离数据的属性,target以查看目标值和DESCR描述,...

那么呢?

你应该知道的第一件事是它的形状。也就是说,数组中包含的维度和项目数。数组的形状是一个整数元组,用于指定每个维的大小。换句话说,如果你有这样的3d数组y = np.zeros((2, 3, 4)),你的数组的形状将是(2,3,4)

现在让我们来试试,看形状是你区分这三个阵列(的东西datatargetDESCR阵列)。

首先使用该data属性将numpy数组与digits数据隔离,然后使用该shape属性查找更多信息。你可以为target和做同样的事情DESCR。还有images属性,它基本上是图像中的数据。你也要测试一下。

使用shape数组上的属性检查此语句:

  • script.py
代码语言:javascript复制
# Isolate the `digits` data
digits_data = digits.data

# Inspect the shape
print(digits_data.shape)

# Isolate the target values with `target`
digits_target = digits.______

# Inspect the shape
print(digits_target._____)

# Print the number of unique labels
number_digits = len(np.unique(digits.target))

# Isolate the `images`
digits_images = digits.images

# Inspect the shape
print(digits_images.shape)

回顾一下:通过检查digits.data,您会看到有1797个样本,并且有64个特征。因为您有1797个样本,所以您还有1797个目标值。

但是所有这些目标值都包含10个唯一值,即从0到9.换句话说,所有1797目标值都由0到9之间的数字组成。这意味着模型需要识别的数字是数字从0到9。

最后,您会看到images数据包含三个维度:有1797个实例,大小为8 x 8像素。您可以通过将数组重新整形为两个维度来直观地检查相关imagesdata相关imagesdigits.images.reshape((1797, 64))

但如果你想完全确定,最好还是检查一下

代码语言:javascript复制
print(np.all(digits.images.reshape((1797,64)) == digits.data))

使用该numpy方法all(),可以测试沿给定轴的所有数组元素是否计算结果True。在这种情况下,您可以评估重新整形的images数组是否正确digits.data。你会看到结果将是True这种情况。

使用可视化您的数据图像 matplotlib

然后,通过可视化您将要使用的图像,您可以将您的探索提升一个档次。您可以使用Python的数据可视化库之一,例如[matplotlib](http://matplotlib.org/)

代码语言:javascript复制
# Import matplotlib
import matplotlib.pyplot as plt

# Figure size (width, height) in inches
fig = plt.figure(figsize=(6, 6))

# Adjust the subplots 
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

# For each of the 64 images
for i in range(64):
    # Initialize the subplots: add a subplot in the grid of 8 by 8, at the i 1-th position
    ax = fig.add_subplot(8, 8, i   1, xticks=[], yticks=[])
    # Display an image at the i-th position
    ax.imshow(digits.images[i], cmap=plt.cm.binary, interpolation='nearest')
    # label the image with the target value
    ax.text(0, 7, str(digits.target[I]))

# Show the plot
plt.show()

代码块似乎很乍一看,这可能是压倒性的。但是,一旦你将其分解成部分,上面的代码块中发生的事情实际上非常简单:

  • 你导入matplotlib.pyplot
  • 接下来,设置一个图形尺寸为6英寸宽和6英寸长的图形。这是您的空白画布,其中将显示包含图像的所有子图。
  • 然后你转到子图的级别来调整一些参数:你将图的suplots的左侧设置为,图的suplots 0的右侧1,底部0和顶部1。suplots之间的空白区域的高度设置为0.005,宽度设置为0.05。这些只是布局调整。
  • 之后,你开始填充你在for循环的帮助下所做的数字。
  • 您可以通过一个初始化suplots之一,在为网格中的每个位置添加一个88大图像。
  • 每次在网格中的每个位置显示一个图像时都会显示。作为颜色贴图,您可以使用二进制颜色,在这种情况下会产生黑色,灰色值和白色。您使用的插值方法是'nearest',这意味着您的数据以不平滑的方式进行插值。您可以在此处查看不同插值方法的效果。
  • 馅饼上的樱桃是你的子图中添加的文字。目标标签印在每个子图的坐标(0,7)处,这实际上意味着它们将出现在每个子图的左下角。
  • 别忘了用情节来展示情节plt.show()

最后,您将看到以下内容:

Python机器学习图像的可视化

更简单的说明,您还可以使用图像可视化目标标签,如下所示:

代码语言:javascript复制
# Import matplotlib
import matplotlib.pyplot as plt 

# Join the images and target labels in a list
images_and_labels = list(zip(digits.images, digits.target))

# for every element in the list
for index, (image, label) in enumerate(images_and_labels[:8]):
    # initialize a subplot of 2X4 at the i 1-th position
    plt.subplot(2, 4, index   1)
    # Don't plot any axes
    plt.axis('off')
    # Display images in all subplots 
    plt.imshow(image, cmap=plt.cm.gray_r,interpolation='nearest')
    # Add a title to each subplot
    plt.title('Training: '   str(label))

# Show the plot
plt.show()

这将呈现以下可视化:

Python scikit-学习图像的可视化

请注意,在这种情况下,在导入之后matplotlib.pyplot,将两个numpy数组压缩在一起并将其保存到名为的变量中images_and_labels。您现在将看到此列表包含每次实例digits.images和相应digits.target值的suples 。

然后,你说对于images_and_labels索引从0开始的-note 的前八个元素! - ,你在每个位置初始化2乘4网格中的子图。您可以打开轴的绘图,然后使用颜色贴图plt.cm.gray_r(返回所有灰色)显示所有子图中的图像,并使用插值方法nearest。您为每个子图提供一个标题,然后显示它。

不太难,是吗?

现在您对将要使用的数据非常了解!

可视化您的数据:主成分分析(PCA)

但是没有其他方法可视化数据吗?

由于digits数据集包含64个功能,因此这可能是一项具有挑战性的任务。您可以想象,很难理解结构并保持digits数据的概述。在这种情况下,据说您正在使用高维数据集。

数据的高维度是尝试通过一组特征描述对象的直接结果。高维数据的其他例子是,例如,财务数据,气候数据,神经影像,......

但是,正如您可能已经收集到的那样,这并不总是那么容易。在某些情况下,高维度可能会有问题,因为您的算法需要考虑太多功能。在这种情况下,你谈到维度的诅咒。因为具有大量维度也意味着您的数据点几乎远离其他所有点,这使得数据点之间的距离无法提供信息。

不过不要担心,因为维度的诅咒不仅仅是计算特征数量的问题。还存在这样的情况:有效维度可能远小于特征的数量,例如在某些特征无关的数据集中。

此外,您还可以理解仅具有两维或三维的数据更易于掌握,并且还可以轻松实现。

这一切都解释了为什么你要借助一种降维技术,即主成分分析(PCA)来可视化数据。PCA中的想法是找到包含大部分信息的两个变量的线性组合。这个新变量或“主成分”可以代替两个原始变量。

简而言之,它是一种线性变换方法,可以产生最大化数据方差的方向(主成分)。请记住,方差表示一组数据点分开多远。如果您想了解更多信息,请转到此页面。

您可以通过以下方式轻松应用PCA执行数据scikit-learn

  • script.py
代码语言:javascript复制
# Create a Randomized PCA model that takes two components
randomized_pca = RandomizedPCA(n_components=2)

# Fit and transform the data to the model
reduced_data_rpca = randomized_pca.fit_transform(digits.data)

# Create a regular PCA model 
pca = PCA(n_components=2)

# Fit and transform the data to the model
reduced_data_pca = pca.fit_transform(digits.data)

# Inspect the shape
reduced_data_pca.shape

# Print out the data
print(reduced_data_rpca)
print(reduced_data_pca)

提示:您已使用RandomizedPCA()此处,因为当存在大量维度时,它的效果会更好。尝试用常规PCA模型替换随机PCA模型或估计器对象,看看有什么区别。

请注意如何明确告诉模型只保留两个组件。这是为了确保您具有要绘制的二维数据。另外,请注意,您不会将带有标签的目标类传递给PCA转换,因为您要调查PCA是否显示不同标签的分布以及是否可以清楚地将实例彼此分开。

您现在可以构建一个散点图来可视化数据:

代码语言:javascript复制
colors = ['black', 'blue', 'purple', 'yellow', 'white', 'red', 'lime', 'cyan', 'orange', 'gray']
for i in range(len(colors)):
    x = reduced_data_rpca[:, 0][digits.target == I]
    y = reduced_data_rpca[:, 1][digits.target == I]
    plt.scatter(x, y, c=colors[I])
plt.legend(digits.target_names, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.xlabel('First Principal Component')
plt.ylabel('Second Principal Component')
plt.title("PCA Scatter Plot")
plt.show()

看起来像这样:

Scikit-learn教程 - 主成分分析(PCA)

您再次使用matplotlib可视化数据。这对于快速可视化您正在使用的内容是有好处的,但如果您正在努力使这部分数据科学组合,您可能不得不考虑一些更加花哨的东西。

另请注意,plt.show()如果您在Jupyter Notebook中工作,则无需显示plot()的最后一次调用,因为您需要将图像内联。如有疑问,您可以随时查看我们的Jupyter笔记本权威指南。

以上代码块中发生的情况如下:

  1. 您将颜色放在一个列表中。请注意,您列出了十种颜色,这些颜色等于您拥有的标签数量。这样,您可以确保您的数据点可以根据标签着色。然后,设置一个从0到10的范围。请注意,此范围不包括在内!请记住,例如,对于列表的索引,这是相同的。
  2. 你设置你的xy坐标。您可以选择第一列或第二列reduced_data_rpca,并仅选择标签等于您正在考虑的索引的那些数据点。这意味着在第一次运行中,您将考虑带有标签的数据点0,然后标记1,......等等。
  3. 您构建散点图。填写xy协调并为正在处理的批次指定颜色。第一次运行时,您将为black所有数据点,下一次运行blue,......等等提供颜色。
  4. 您可以在散点图中添加图例。使用target_names密钥为您的数据点获取正确的标签。
  5. 为您xy有意义的轴添加标签。
  6. 显示结果图。

现在去哪里?

现在您已经掌握了有关数据的更多信息,并且已准备好可视化,它看起来有点像数据点组合在一起,但您也看到有一些重叠。

这可能是进一步调查的有趣之处。

您是否认为,如果您知道有10个可能的数字标签要分配给数据点,但您无法访问这些标签,那么观察结果会以某种方式将这些标准分组或“聚集”在一起你可以推断标签?

现在这是一个研究问题!

通常,当您对数据有一个很好的理解时,您必须决定与您的数据集相关的用例。换句话说,您可以考虑数据集可能教给您什么,或者您认为可以从数据中学到什么。

从那以后,您可以考虑将哪种算法应用于数据集,以获得您认为可以获得的结果。

提示:您对数据越熟悉,就越容易评估特定数据集的用例。同样适用于寻找合适的机器算法。

但是,当您第一次开始使用时scikit-learn,您会发现该库包含的算法数量非常庞大,并且在您对数据集进行评估时可能仍需要其他帮助。这就是为什么这scikit-learn台机器学习地图会派上用场的原因。

请注意,此映射确实需要您了解scikit-learn库中包含的算法。顺便说一句,这也为你的项目中的下一步提供了一些事实:如果你不知道什么是可能的,那么很难决定你的数据用例。

由于您的用例是用于群集的用例,您可以按照地图上的路径向“KMeans”方向移动。你会看到你刚想过的用例要求你有超过50个样本(“check!”),要有标记数据(“check!”),要知道你想要预测的类别数量(“检查!”)并且样本少于10K(“check!”)。

但究竟什么是K-Means算法?

它是解决聚类问题的最简单和广泛使用的无监督学习算法之一。该过程遵循一种简单易用的方法,通过在运行算法之前设置的特定数量的集群对给定数据集进行分类。调用此簇数,k您可以随机选择此数字。

然后,k-means算法将为每个数据点找到最近的聚类中心,并分配最接近该聚类的数据点。

将所有数据点分配给群集后,将重新计算群集中心。换句话说,新的集群中心将从集群数据点的平均值出现。重复此过程,直到大多数数据点粘附到同一群集。群集成员资格应该稳定下来。

您已经可以看到,因为k-means算法以它的方式工作,您放弃的初始集群中心集会对最终找到的集群产生很大影响。当然,你可以处理这种效果,你会进一步看到。

但是,在为数据制作模型之前,您一定要考虑为此目的准备数据。

使用DataCamp学习Python for Data Science

预处理您的数据

正如您在上一节中所述,在对数据建模之前,您首先要做好准备。该准备步骤称为“预处理”。

数据规范化

我们要做的第一件事是预处理数据。您可以digits通过使用以下scale()方法来标准化数据:

  • script.py
代码语言:javascript复制
# Import
from sklearn.preprocessing import scale

# Apply `scale()` to the `digits` data
data = _____(digits.data)

通过缩放数据,您可以将每个属性的分布转换为平均值为零,标准差为1(单位方差)。

将您的数据拆分为训练和测试集

为了在以后评估模型的性能,您还需要将数据集分为两部分:训练集和测试集。第一个用于训练系统,而第二个用于评估学习或训练的系统。

在实践中,将数据集划分为测试和训练集是不相交的:最常见的拆分选择是将原始数据集的2/3作为训练集,而剩下的1/3将构成测试集。

您也可以尝试这样做。你可以在下面的代码块中看到这个“传统的”拆分选择得到尊重:在train_test_split()方法的参数中,你清楚地看到它test_size被设置为0.25

您还会注意到参数random_state具有42分配给它的值。使用此参数,您可以保证您的拆分始终相同。如果您想要可重复的结果,这尤其方便。

  • script.py
代码语言:javascript复制
# Import `train_test_split`
from sklearn.cross_validation import ________________

# Split the `digits` data into training and test sets
X_train, X_test, y_train, y_test, images_train, images_test = train_test_split(data, digits.target, digits.images, test_size=0.25, random_state=42)

将数据集拆分为训练集和测试集后,可以在开始数据建模之前快速检查数据:

  • script.py
代码语言:javascript复制
# Number of training features
n_samples, n_features = X_train.shape

# Print out `n_samples`
print(_________)

# Print out `n_features`
print(__________)

# Number of Training labels
n_digits = len(np.unique(y_train))

# Inspect `y_train`
print(len(_______))

您将看到训练集X_train现在包含1347个样本,这正好是原始数据集包含的样本的2 / 3d,以及64个未更改的特征。该y_train训练集还包含原始数据集的标签的2 / 3D。这意味着测试设置X_testy_test包含450个样本。

聚类digits数据

完成所有这些准备步骤后,您已确保存储了所有已知(训练)数据。直到现在才进行实际的模型或学习。

现在,终于找到训练集的那些集群了。使用KMeans()cluster模块设置你的模型。你会看到,有传递给这个方法三个参数:initn_clustersrandom_state

当您将数据拆分为训练集和测试集时,您可能还记得之前的最后一个参数。这个论点基本上保证了你得到了可重复的结果。

  • script.py
代码语言:javascript复制
# Import the `cluster` module
from sklearn import ________

# Create the KMeans model
clf = cluster.KMeans(init='k-means  ', n_clusters=10, random_state=42)

# Fit the training data `X_train`to the model
clf.fit(________)

init指示初始化方法即使它默认为‘k-means ’,你看它明确回来的代码。这意味着如果你愿意,你可以把它留下来。在上面的DataCamp Light块中尝试一下!

接下来,您还会看到n_clusters参数设置为10。此数字不仅表示您希望数据形成的聚类或组的数量,还指示要生成的质心数。请记住,群集质心是群集的中间位置。

您是否还记得上一节如何将此描述为K-Means算法的可能缺点之一?

也就是说,您放弃的初始集群中心集对最终找到的集群有很大影响?

通常,您尝试通过在多次运行中尝试多个初始集并通过选择具有最小平方误差总和(SSE)的集群来处理此效果。换句话说,您希望最小化群集中每个点与该群集的平均值或质心的距离。

通过添加n-init参数KMeans(),您可以确定算法将尝试多少个不同的质心配置。

再次注意,当您将模型与数据拟合时,您不希望插入测试标签:这些将用于查看您的模型是否擅长预测实例的实际类!

您还可以将构成群集中心的图像可视化,如下所示:

代码语言:javascript复制
# Import matplotlib
import matplotlib.pyplot as plt

# Figure size in inches
fig = plt.figure(figsize=(8, 3))

# Add title
fig.suptitle('Cluster Center Images', fontsize=14, fontweight='bold')

# For all labels (0-9)
for i in range(10):
    # Initialize subplots in a grid of 2X5, at i 1th position
    ax = fig.add_subplot(2, 5, 1   i)
    # Display images
    ax.imshow(clf.cluster_centers_[i].reshape((8, 8)), cmap=plt.cm.binary)
    # Don't show the axes
    plt.axis('off')

# Show the plot
plt.show()

KMeans使用scikit-learn进行群集可视化

如果你想看到另一个可视化的例子 <digits style="box-sizing: border-box;">数据集群及其中心,请转到此处。</digits>

下一步是预测测试集的标签:

  • script.py
代码语言:javascript复制
# Predict the labels for `X_test`
y_pred=clf.predict(X_test)

# Print out the first 100 instances of `y_pred`
print(y_pred[:100])

# Print out the first 100 instances of `y_test`
print(y_test[:100])

# Study the shape of the cluster centers
clf.cluster_centers_._____

在上面的代码块中,您可以预测测试集的值,其中包含450个样本。您将结果存储在y_pred。您还打印出前100个实例,y_predy_test立即看到一些结果。

此外,您可以研究集群中心的形状:您可以立即看到每个64个要素有10个集群。

但这并没有告诉你太多,因为我们将簇数设置为10,你已经知道有64个功能。

也许可视化会更有帮助。

让我们可视化预测的标签:

代码语言:javascript复制
# Import `Isomap()`
from sklearn.manifold import Isomap

# Create an isomap and fit the `digits` data to it
X_iso = Isomap(n_neighbors=10).fit_transform(X_train)

# Compute cluster centers and predict cluster index for each sample
clusters = clf.fit_predict(X_train)

# Create a plot with subplots in a grid of 1X2
fig, ax = plt.subplots(1, 2, figsize=(8, 4))

# Adjust layout
fig.suptitle('Predicted Versus Training Labels', fontsize=14, fontweight='bold')
fig.subplots_adjust(top=0.85)

# Add scatterplots to the subplots 
ax[0].scatter(X_iso[:, 0], X_iso[:, 1], c=clusters)
ax[0].set_title('Predicted Training Labels')
ax[1].scatter(X_iso[:, 0], X_iso[:, 1], c=y_train)
ax[1].set_title('Actual Training Labels')

# Show the plots
plt.show()

您可以使用Isomap()它来减少高维数据集的尺寸digits。与PCA方法的不同之处在于Isomap是一种非线性还原方法。

Isomap可视化

提示:再次运行上面的代码,但使用PCA简化方法而不是Isomap来自行研究简化方法的效果。

你会在这里找到解决方案:

代码语言:javascript复制
# Import `PCA()`
from sklearn.decomposition import PCA

# Model and fit the `digits` data to the PCA model
X_pca = PCA(n_components=2).fit_transform(X_train)

# Compute cluster centers and predict cluster index for each sample
clusters = clf.fit_predict(X_train)

# Create a plot with subplots in a grid of 1X2
fig, ax = plt.subplots(1, 2, figsize=(8, 4))

# Adjust layout
fig.suptitle('Predicted Versus Training Labels', fontsize=14, fontweight='bold')
fig.subplots_adjust(top=0.85)

# Add scatterplots to the subplots 
ax[0].scatter(X_pca[:, 0], X_pca[:, 1], c=clusters)
ax[0].set_title('Predicted Training Labels')
ax[1].scatter(X_pca[:, 0], X_pca[:, 1], c=y_train)
ax[1].set_title('Actual Training Labels')

# Show the plots
plt.show()

使用matplotlib进行PCA可视化

乍一看,可视化似乎并不表示该模型运作良好。

但这需要进一步调查。

评估您的聚类模型

这种进一步调查的需要将带您进入下一个重要步骤,即评估模型的性能。换句话说,您想要分析模型预测的正确程度。

让我们打印一个混淆矩阵:

  • script.py
代码语言:javascript复制
# Import `metrics` from `sklearn`
from sklearn import _______

# Print out the confusion matrix with `confusion_matrix()`
print(metrics.confusion_matrix(y_test, y_pred))

乍一看,结果似乎证实了我们从可视化中收集到的第一个想法。5在41例中只有数字被正确分类。此外,该数字8在11个实例中被正确分类。但这并不是真的成功。

您可能需要更多地了解结果,而不仅仅是混淆矩阵。

让我们尝试通过应用不同的群集质量指标来更多地了解群集的质量。这样,您就可以判断簇标签的适合度是否正确。

  • script.py
代码语言:javascript复制
from sklearn.metrics import homogeneity_score, completeness_score, v_measure_score, adjusted_rand_score, adjusted_mutual_info_score, silhouette_score
print('% 9s' % 'inertia    homo   compl  v-meas     ARI AMI  silhouette')
print('%i   %.3f   %.3f   %.3f   %.3f   %.3f    %.3f'
          %(clf.inertia_,
      homogeneity_score(y_test, y_pred),
      completeness_score(y_test, y_pred),
      v_measure_score(y_test, y_pred),
      adjusted_rand_score(y_test, y_pred),
      adjusted_mutual_info_score(y_test, y_pred),
      silhouette_score(X_test, y_pred, metric='euclidean')))
代码语言:javascript复制
inertia    homo   compl  v-meas     ARI AMI  silhouette
54276   0.688   0.733   0.710   0.567   0.674    0.146

您会看到需要考虑的一些指标:

  • 同质性分数告诉您所有集群在多大程度上仅包含属于单个类的成员的数据点。
  • 完整性分数测量作为给定类的成员的所有数据点也是同一群集的元素的程度。
  • V-measure得分是同质性和完整性之间的调和平均值。
  • 调整后的Rand分数测量两个聚类之间的相似性,并考虑在预测和真实聚类中在相同或不同聚类中分配的所有样本对和计数对。
  • 调整后的相互信息(AMI)分数用于比较群集。它测量聚类中数据点之间的相似性,计算机会分组,并在聚类等效时取最大值1。
  • 剪影得分测量对象与其他聚类相比与其自身聚类的相似程度。轮廓分数范围从-1到1,其中较高的值表示对象与其自己的群集更好地匹配,并且更差地与邻近群集匹配。如果许多点具有高值,则clusteirng配置很好。

您清楚地看到这些分数并不出色:例如,您看到轮廓分数的值接近于0,这表示样本处于或非常接近两个相邻群集之间的决策边界。这可能表示样本可能已分配给错误的群集。

此外,ARI度量似乎表明,并非给定群集中的所有数据点都相似,并且完整性分数告诉您确实存在未放入正确群集的数据点。

显然,您应该考虑使用另一个估算器来预测digits数据的标签。

尝试另一种模式:支持向量机

当您重新获取从数据探索中收集的所有信息时,您看到可以构建模型来预测数字所属的组,而无需您知道标签。事实上,您只是使用训练数据而不是目标值来构建KMeans模型。

假设您偏离了使用digits训练数据和相应目标值来构建模型的情况。

如果您遵循算法映射,您将看到您遇到的第一个模型是线性SVC。我们现在将其应用于digits数据:

  • script.py
代码语言:javascript复制
# Import `train_test_split`
from sklearn.cross_validation import train_test_split

# Split the data into training and test sets 
X_train, X_test, y_train, y_test, images_train, images_test = train_test_split(digits.data, digits.target, digits.images, test_size=0.25, random_state=42)

# Import the `svm` model
from sklearn import svm

# Create the SVC model 
svc_model = svm.SVC(gamma=0.001, C=100., kernel='linear')

# Fit the data to the SVC model
svc_model.fit(X_train, y_train)

您可以在此处看到,您可以使用X_train并将y_train数据拟合到SVC模型。这明显不同于聚类。另请注意,在此示例中,您gamma可以手动设置值。通过使用网格搜索和交叉验证等工具,可以自动为参数找到合适的值。

尽管这不是本教程的重点,但如果您使用网格搜索来调整参数,您将看到如何解决这个问题。你会做如下的事情:

  • script.py
代码语言:javascript复制
# Split the `digits` data into two equal sets
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.5, random_state=0)

# Import GridSearchCV
from sklearn.grid_search import GridSearchCV

# Set the parameter candidates
parameter_candidates = [
  {'C': [1, 10, 100, 1000], 'kernel': ['linear']},
  {'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
]

# Create a classifier with the parameter candidates
clf = GridSearchCV(estimator=svm.SVC(), param_grid=parameter_candidates, n_jobs=-1)

# Train the classifier on training data
clf.fit(X_train, y_train)

# Print out the results 
print('Best score for training data:', clf.best_score_)
print('Best `C`:',clf.best_estimator_.C)
print('Best kernel:',clf.best_estimator_.kernel)
print('Best `gamma`:',clf.best_estimator_.gamma)

运行

代码语言:javascript复制
Best score for training data: 0.9844097995545658
Best `C`: 10
Best kernel: rbf
Best `gamma`: 0.001

接下来,将分类器与刚刚创建的分类器和参数候选一起使用,以将其应用于数据集的第二部分。接下来,您还使用网格搜索找到的最佳参数训练新的分类器。您对结果进行评分,以查看在网格搜索中找到的最佳参数是否确实有效。

  • script.py
代码语言:javascript复制
# Apply the classifier to the test data, and view the accuracy score
clf.score(X_test, y_test)  

# Train and score a new classifier with the grid search parameters
svm.SVC(C=10, kernel='rbf', gamma=0.001).fit(X_train, y_train).score(X_test, y_test)

运行

代码语言:javascript复制
0.99110122358175756

参数确实运作良好!

现在,这些新知识告诉您在完成网格搜索之前已经建模的SVC分类器是什么?

让我们回到你之前制作的模型。

您可以在SVM分类器中看到C错误术语的惩罚参数指定在100.。最后,您会看到内核已明确指定为一个内核linear。该kernel参数指定你要在算法中,默认情况下使用的内核类型,这是rbf。在其他情况下,您可以指定其他如linearpoly...

但究竟什么是内核呢?

内核是相似函数,用于计算训练数据点之间的相似性。当您为算法提供内核以及训练数据和标签时,您将获得分类器,就像这里的情况一样。您将训练一个模型,将新的看不见的对象分配到特定类别。对于SVM,您通常会尝试线性划分数据点。

但是,网格搜索告诉您rbf内核将更好地工作。惩罚参数和伽马指定正确。

提示:使用rbf内核尝试分类器。

现在,让我们假设您继续使用线性内核并预测测试集的值:

  • script.py
代码语言:javascript复制
# Predict the label of `X_test`
print(svc_model.predict(______))

# Print `y_test` to check the results
print(______)

您还可以显示图像及其预测标签:

代码语言:javascript复制
# Import matplotlib
import matplotlib.pyplot as plt

# Assign the predicted values to `predicted`
predicted = svc_model.predict(X_test)

# Zip together the `images_test` and `predicted` values in `images_and_predictions`
images_and_predictions = list(zip(images_test, predicted))

# For the first 4 elements in `images_and_predictions`
for index, (image, prediction) in enumerate(images_and_predictions[:4]):
    # Initialize subplots in a grid of 1 by 4 at positions I 1
    plt.subplot(1, 4, index   1)
    # Don't show axes
    plt.axis('off')
    # Display images in all subplots in the grid
    plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')
    # Add a title to the plot
    plt.title('Predicted: '   str(prediction))

# Show the plot
plt.show()

此图与您在浏览数据时所绘制的图非常相似:

用matplotlib可视化的图像和预测标签

只有这一次,你将图像和预测值压缩在一起,你只需要前4个元素images_and_predictions

但现在最大的问题是:这个模型是如何表现的?

  • script.py
代码语言:javascript复制
# Import `metrics`
from sklearn import metrics

# Print the classification report of `y_test` and `predicted`
print(metrics.classification_report(______, _________))

# Print the confusion matrix of `y_test` and `predicted`
print(metrics.confusion_matrix(______, _________))

您清楚地看到此模型比您之前使用的聚类模型执行得更好。

在以下情况下可视化预测标签和实际标签时,您也可以看到它Isomap()

代码语言:javascript复制
# Import `Isomap()`
from sklearn.manifold import Isomap

# Create an isomap and fit the `digits` data to it
X_iso = Isomap(n_neighbors=10).fit_transform(X_train)

# Compute cluster centers and predict cluster index for each sample
predicted = svc_model.predict(X_train)

# Create a plot with subplots in a grid of 1X2
fig, ax = plt.subplots(1, 2, figsize=(8, 4))

# Adjust the layout
fig.subplots_adjust(top=0.85)

# Add scatterplots to the subplots 
ax[0].scatter(X_iso[:, 0], X_iso[:, 1], c=predicted)
ax[0].set_title('Predicted labels')
ax[1].scatter(X_iso[:, 0], X_iso[:, 1], c=y_train)
ax[1].set_title('Actual Labels')

# Add title
fig.suptitle('Predicted versus actual labels', fontsize=14, fontweight='bold')

# Show the plot
plt.show()

这将为您提供以下散点图:

Isomap散点图可视化

您将看到此可视化确认您的分类报告,这是一个非常好的消息。:)

下一步是什么?

自然图像中的数字识别

恭喜,您已经到了这个scikit-learn教程的末尾,这本教程旨在向您介绍Python机器学习!现在轮到你了。

首先,确保你掌握了DataCamp的scikit-learn备忘录。

接下来,使用不同的数据开始您自己的数字识别项目。您已经可以使用的一个数据集是MNIST数据,您可以在此处下载。

您可以采取的步骤与本教程中的步骤非常相似,但如果您仍然觉得可以使用某些帮助,则应该查看此页面,该页面使用MNIST数据并应用KMeans算法。

使用digits数据集是使用字符进行分类的第一步scikit-learn。如果你已经完成了这个,你可能会考虑尝试一个更具挑战性的问题,即在自然图像中对字母数字字符进行分类。

可用于此问题的众所周知的数据集是Chars74K数据集,其中包含超过74,000个0到9的数字图像以及英文字母的小写和高写字母。您可以在此处下载数据集。

数据可视化和 pandas

无论您是从上面提到的项目开始,这绝对不是您使用Python进行数据科学之旅的终点。如果您尚未选择不扩大视图,请考虑深化数据可视化和数据操作知识。

不要错过我们的交互式数据可视化与Bokeh课程,以确保您可以通过令人惊叹的数据科学组合或我们的pandas基础课程给您的同行留下深刻印象,以了解有关使用Python中的数据框架的更多信息。

原文:https://www.datacamp.com/community/tutorials/machine-learning-python 作者: Karlijn Willems

0 人点赞