《scikit-learn机器学习常用算法原理及编程实战》—2.6 scikit-learn简介

举报
华章计算机 发表于 2019/05/31 16:39:39 2019/05/31
【摘要】 本书摘自《scikit-learn机器学习常用算法原理及编程实战》一书中的第2章,第2.6.1节,编著是黄永昌 .

2.6  scikit-learn简介

  scikit-learn是一个开源的Python语言机器学习工具包,它涵盖了几乎所有主流机器学习算法的实现,并且提供了一致的调用接口。它基于Numpy和scipy等Python数值计算库,提供了高效的算法实现。总结起来,scikit-learn工具包有以下几个优点。

* 文档齐全:官方文档齐全,更新及时。

* 接口易用:针对所有的算法提供了一致的接口调用规则,不管是KNN、K-Mean还是PCA。

* 算法全面:涵盖主流机器学习任务的算法,包括回归算法、分类算法、聚类分析、数据降维处理等。

  当然,scikit-learn不支持分布式计算,不适合用来处理超大型数据。但这并不影响 scikit-learn作为一个优秀的机器学习工具库这个事实。许多知名的公司,包括Evernote和Spotify都使用scikit-learn来开发他们的机器学习应用。

2.6.1  scikit-learn示例

  回顾前面章节介绍的机器学习应用开发的典型步骤,我们使用scikit-learn来完成一个手写数字识别的例子。这是一个有监督的学习,数据是标记过的手写数字的图片。即通过采集足够多的手写数字样本数据,选择合适的模型,并使用采集到的数据进行模型训练,最后验证手写识别程序的正确性。

  1.数据采集和标记

  如果我们从头实现一个数字手写识别的程序,需要先采集数据,即让尽量多不同书写习惯的用户,写出从0~9的所有数字,然后把用户写出来的数据进行标记,即用户每写出一个数字,就标记他写出的是哪个数字。

  为什么要采集尽量多不同书写习惯的用户写的数字呢?因为只有这样,采集到的数据才有代表性,才能保证最终训练出来的模型的准确性。极端的例子,我们采集的都是习惯写出瘦高形数字的人,那么针对习惯写出矮胖形数字的人写出来的数字,模型的识别成功率就会很低。

  所幸我们不需要从头开始这项工作,scikit-learn自带了一些数据集,其中一个是手写数字识别图片的数据,使用以下代码来加载数据。

  

  from sklearn import datasets

  digits = datasets.load_digits()

  

  可以在ipython notebook环境下把数据所表示的图片用Mathplotlib显示出来:

  # 把数据所代表的图片显示出来

  images_and_labels = list(zip(digits.images, digits.target))

  plt.figure(figsize=(8, 6), dpi=200)

  for index, (image, label) in enumerate(images_and_labels[:8]):

      plt.subplot(2, 4, index + 1)

      plt.axis('off')

      plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')

      plt.title('Digit: %i' % label, fontsize=20)

  

  其结果如图2-19所示。

image.png

图2-19  数字图片

  从图2-19中可以看出,图片是一个个手写的数字。

  2.特征选择

  针对一个手写的图片数据,应该怎么样来选择特征呢?一个直观的方法是,直接使用图片的每个像素点作为一个特征。比如一个图片是200 ? 200的分辨率,那么我们就有 40000个特征,即特征向量的长度是40000。

  实际上,scikit-learn使用Numpy的array对象来表示数据,所有的图片数据保存在 digits.images里,每个元素都是一个8?8尺寸的灰阶图片。我们在进行机器学习时,需要把数据保存为样本个数?特征个数格式的array对象,针对手写数字识别这个案例,scikit-learn已经为我们转换好了,它就保存在digits.data数据里,可以通过digits.data.shape来查看它的数据格式为:

  

  print("shape of raw image data: {0}".format(digits.images.shape))

  print("shape of data: {0}".format(digits.data.shape))

  

  输出为:

  

  shape of raw image data: (1797, 8, 8)

  shape of data: (1797, 64)

  

  可以看到,总共有1797个训练样本,其中原始的数据是8?8的图片,而用来训练的数据是把图片的64个象素点都转换为特征。下面将直接使用digits.data作为训练数据。

  3.数据清洗

  人们不可能在8?8这么小的分辨率的图片上写出数字,在采集数据的时候,是让用户在一个大图片上写出这些数字,如果图片是200 ? 200分辨率,那么一个训练样例就有40000个特征,计算量将是巨大的。为了减少计算量,也为了模型的稳定性,我们需要把200 ? 200的图片缩小为8?8的图片。这个过程就是数据清洗,即把采集到的、不适合用来做机器学习训练的数据进行预处理,从而转换为适合机器学习的数据。

  4.模型选择

  不同的机器学习算法模型针对特定的机器学习应用有不同的效率,模型的选择和验证留到后面章节详细介绍。此处,我们使用支持向量机来作为手写识别算法的模型。关于支持向量机,后面章节也会详细介绍。

  5.模型训练

  在开始训练我们的模型之前,需要先把数据集分成训练数据集和测试数据集。为什么要这样做呢?第1章的模型训练和测试里有详细的介绍。我们可以使用下面代码把数据集分出20%作为测试数据集。

  

  # 把数据分成训练数据集和测试数据集

  from sklearn.cross_validation import train_test_split

  Xtrain, Xtest, Ytrain, Ytest = train_test_split(digits.data,

                    digits.target, test_size=0.20, random_state=2);

  

  接着,使用训练数据集Xtrain和Ytrain来训练模型。

  

  # 使用支持向量机来训练模型

  from sklearn import svm

  clf = svm.SVC(gamma=0.001, C=100.)

  clf.fit(Xtrain, Ytrain);

  

  训练完成后,clf对象就会包含我们训练出来的模型参数,可以使用这个模型对象来进行预测。

  6.模型测试

  我们来测试一下训练出来的模型的准确度。一个直观的方法是,我们用训练出来的模型clf预测测试数据集,然后把预测结果Ypred和真正的结果Ytest比较,看有多少个是正确的,这样就能评估出模型的准确度了。所幸,scikit-learn提供了现成的方法来完成这项工作:

  

  clf.score(Xtest, Ytest)

  

  笔者计算机上的输出结果为:

  

  0.9*********5

  

  显示出模型有97.8%的准确率。读者如果运行这段代码的话,在准确率上可能会稍有差异。

  除此之外,还可以直接把测试数据集里的部分图片显示出来,并且在图片的左下角显示预测值,右下角显示真实值。运行效果如图2-20所示。

  

  # 查看预测的情况

  fig, axes = plt.subplots(4, 4, figsize=(8, 8))

  fig.subplots_adjust(hspace=0.1, wspace=0.1)

  

  for i, ax in enumerate(axes.flat):

      ax.imshow(Xtest[i].reshape(8, 8), cmap=plt.cm.gray_r,

                                        interpolation='nearest')

      ax.text(0.05, 0.05, str(Ypred[i]), fontsize=32,

              transform=ax.transAxes,

              color='green' if Ypred[i] == Ytest[i] else 'red')

      ax.text(0.8, 0.05, str(Ytest[i]), fontsize=32,

              transform=ax.transAxes,

              color='black')

      ax.set_xticks([])

      ax.set_yticks([])

image.png

图2-20  预测值与真实值

  从图2-20中可以看出来,第二行第一个图片预测出错了,真实的数字是4,但预测成了8。

  7.模型保存与加载

  当我们对模型的准确度感到满意后,就可以把模型保存下来。这样下次需要预测时,可以直接加载模型来进行预测,而不是重新训练一遍模型。可以使用下面的代码来保存模型:

  

  # 保存模型参数

  from sklearn.externals import joblib

  joblib.dump(clf, 'digits_svm.pkl');

  

  当我们需要这个模型来进行预测时,直接加载模型即可进行预测。

  

  # 导入模型参数,直接进行预测

  clf = joblib.load('digits_svm.pkl')

  Ypred = clf.predict(Xtest);

  clf.score(Ytest, Ypred)

  

  笔者计算机上的输出结果是:

  

  0.9*********5

  

  这个例子包含在随书代码ch02.06.ipynb上,读者可以下载下来运行并参考。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。