个性化阅读
专注于IT技术分析

Scikit-Learn教程:Python与机器学习

srcmini团队很高兴宣布我们的朋友和srcmini用户Tony Yao-Jen Kuo慷慨地将我们的Python机器学习:Scikit-Learn教程翻译成繁体中文!

使用 Python 实现机器学习

机器学习是一门设计如何让演算法能够学习的电脑科学, 让机器能够透过观察已知的资料学习预测未知的资料。典型的应用包含概念学习(Concept learning)、函数学习(Function learning)、预测模型(Predictive modeling)、分群(Clustering)与找寻预测特征(Finding predictive patterns)。终极目标是让电脑能够自行提升学习能力, 预测未知资料的准确性能够随着已知资料的增加而提高, 节省使用者人工调整校正的精力。

机器学习跟知识发掘(Knowledge Discovery)、资料采矿(Data Mining)、人工智慧(Artificial Intelligence, AI)以及统计(Statistics)有着密不可分的关系, 应用范围从学术研究到商业应用, 从机器人科学家到垃圾邮件筛选与推荐系统, 都可见其踪影。

要成为一个优秀的资料科学家, 机器学习是不可或缺的技能, 这份教学会从零开始介绍如何使用Python 来实现机器学习, 并且示范如何使用一些非监督式与监督式的机器学习演算法。如果你对于使用 R 语言来实现机器学习更有兴趣, 可以参阅 Machine Learning with R for Beginners tutorial。

读入资料

跟任何的资料科学专案相同, 我们在教学的一开始就是将资料读入 Python 的开发环境。如果你是一位机器学习的初学者, 我们推荐三个很棒的资料来源, 分别是加州大学 Irvine 分校的机器学习资料集、Kaggle 网站与 KD Nuggets 整理的资料集资源。

好, 让我们来暖身一下, 利用 Python 的机器学习套件 scikit-learn 将一个叫作 digits 的资料读入。

冷知识:scikit-learn 源于于 SciPy, 事实上 scikit 有很多个, 我们使用的 scikit-learn 套件是专门用来实现机器学习以及资料采矿的, 这也是为什么使用 learn 来命名:)

我们首先由sklearn 套件载入datasets 模组, 然后使用datasets 模组的load_digits() 方法来输入资料, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

datasets 模组还有其他读取资料的方法, 你也可以用它来产生虚拟资料。我们现在所使用的资料集 digits 也可以从加州大学 Irvine 分校的机器学习资料集载入, 你可以在这个连结找到。假如你想要从加州大学Irvine 分校的机器学习资料集载入digits, 读入资料的程式写法会变得像这样, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

值得注意的是, 从档名的.tra 与.tes 可以得知, 加州大学Irvine 分校的机器学习资料集已经切分好训练与测试资料, 而上面这段程式中我们只读入了训练资料, 如果要实现机器学习则还需要再读入测试资料,

秘诀:想学习更多使用 Python 的 Pandas 套件来读入与整理资料的技巧, 可以参阅 Importing Data in Python course。

探索资料

仔细阅读资料的文件或描述是很好的习惯, 加州大学 Irvine 分校的机器学习资料集针对每个资料都有提供文件, 阅读文件可以提高我们对资料的了解程度。然而光是初步认识还是略嫌不足, 接着我们要进行的是探索性分析(Exploratory data analysis), 我们又该从何开始探索这些手写数字图片资料呢?

搜集基本资讯

假如我们直接透过 scikit-learn 读入 digits 资料, 那么不同于加州大学 Irvine 分校的机器学习资料集在网页中提供描述或文件, 我们必须另外透过使用 digits 的属性与方法来搜集基本资讯。

我们将透过 digits 的 keys() 方法来得知有哪些基本资讯可以搜集;透过 data 属性观察预测变数;透过 target 属性观察目标变数;透过 DESCR 属性阅读资料的描述文件。试着依照注解的提示完成程式后点选 Run 观察结果, 如果没有头绪, 可以点选 Solution 将程式完成后再点选 Run 观察结果:

接着我们回忆一下在第一个练习中印出的 digits, 里头出现很多的 numpy 阵列, 了解阵列最重要的特性是形状(shape)。假如我们有一个 3d 阵列:y = np.zeros((2, 3, 4)), 这个阵列的形状就是 (2, 3, 4), 由整数组成的 tuple 资料结构。

我们延续前一个练习来观察data、target、DESCR 与images 的形状, 利用digits 的data 属性将这个阵列独立指派给digits_data 并检视其shape 属性, 并且对另外三个属性也依样画葫芦进行相同的操作, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

我们在这小结一下, 检视digits.data.shape 可以得知资料有1, 797 个观测值, 64 个变数, 检视digits.target.shape 可以得知资料有1, 797 个目标值(或称标签值), 而检视len(np.unique(digits.target)) 可以得知所有的目标值只有10 个相异值:0 到9, 意即我们的模型是要辨识手写数字图片是0 到9 中的哪一个数字。

最后是digits.images 的三个维度:1, 797 个8 x 8 像素的矩阵, 我们可以进一步将digits.images 转换(reshape)为两个维度, 并且使用numpy 的all() 方法比较阵列内的元素是否与digits.data 完全相同:print(np.all(digits.images.reshape((1797, 64)) == digits.data)), 而我们会得到True 的结果。

使用 matplotlib 视觉化手写数字图片

接下来我们要使用 Python 的资料视觉化套件 matplotlib 来视觉化这些手写数字图片:


# 從 `sklearn` 載入 `datasets`
from sklearn import datasets
# 載入 matplotlib
import matplotlib.pyplot as plt

# 載入 `digits`
digits = datasets.load_digits()

# 設定圖形的大小(寬, 高)
fig = plt.figure(figsize=(4, 2))

# 調整子圖形 
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

# 把前 8 個手寫數字顯示在子圖形
for i in range(8):
    # 在 2 x 4 網格中第 i + 1 個位置繪製子圖形, 並且關掉座標軸刻度
    ax = fig.add_subplot(2, 4, i + 1, xticks = [], yticks = [])
    # 顯示圖形, 色彩選擇灰階
    ax.imshow(digits.images[i], cmap = plt.cm.binary)
    # 在左下角標示目標值
    ax.text(0, 7, str(digits.target[i]))

# 顯示圖形
plt.show()

这段程式看起来有点难懂, 让我们分开来看:

  • 载入 matplotlib 套件。
  • 设定一个长 2 吋, 宽 4 吋的空白画布, 准备待会将子图形画在上面。
  • 调整子图形的一些参数。
  • 使用一个 for 回圈开始要将空白画布填满。
  • 初始化 8 个子图形, 并依序填入 2 x 4 网格中的每一格。
  • 最后画龙点睛的部分是在每个子图形 (0, 7) 的位置(左下角)显示目标值。
  • 别忘了使用 plt.show() 将画好的图显示出来!

完成后我们可以看到这张视觉化图形

Python机器学习

或者采取这段较简洁的程式:


# 從 `sklearn` 載入 `datasets`
from sklearn import datasets
# 載入 matplotlib
import matplotlib.pyplot as plt

# 載入 `digits`
digits = datasets.load_digits()

# 將觀測值與目標值放入一個 list
images_and_labels = list(zip(digits.images, digits.target))

# list 中的每個元素
for i, (image, label) in enumerate(images_and_labels[:8]):
    # 在 i + 1 的位置初始化子圖形
    plt.subplot(2, 4, i + 1)
    # 關掉子圖形座標軸刻度
    plt.axis('off')
    # 顯示圖形, 色彩選擇灰階
    plt.imshow(image, cmap = plt.cm.binary)
    # 加入子圖形的標題
    plt.title('Training: ' + str(label))

# 顯示圖形
plt.show()

完成后我们可以看到这张视觉化图形:

Scikit-Learn教程:Python与机器学习2

在这个例子中, 我们将两个阵列存入images_and_labels 这个变数, 然后将这个变数中的前8 个元素(包含digits.images 与相对应的digits.target)在一个2 x 4 的格线上绘制子图形, 并且使用plt.cm.binary 这个灰阶色彩, 搭配子图形标题显示出来。

经过这两个视觉化练习之后, 你应该对目前手上处理的 digits 资料有更深的认识!

视觉化:主成份分析(Principal Component Analysis, PCA)

digits 资料有64 个变数, 面对这种高维度的资料(实务上还有其他很多像是财务或者气候资料也都属于高维度资料), 我们需要用一些方法找出特别重要的二到三个变数, 或者将许多的变数组合成让我们更容易理解且视觉化的几个维度。

这种方法称作降维(Dimensionality Reduction), 我们接着要使用其中一种方法称为:主成份分析(Principal Component Analysis, PCA)来协助我们视觉化 digits 资料。主成份分析的精神在于找出变数之间的线性关系组成新的一个主成份, 然后使用这个主成份取代原有的变数, 属于一种最大化资料变异性的线性转换方法, 如果你想了解更多, 可以参阅这个连结。

我们可以透过 scikit-learn 轻松对 digits 资料实现主成份分析, 直接点选 Run 观察结果:

秘诀:比较 RandomizedPCA() 与 PCA() 产生的结果, 观察两者的差异。

我们在程式中指定降维成两个主成份, 确保可以使用散布图视觉化, 并观察用两个主成份是否可以将不同的目标值区隔开:


from sklearn import datasets
digits = datasets.load_digits()
import matplotlib.pyplot as plt

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教程:Python与机器学习3

我们再一次使用了 matplotlib 来绘图, 假如你正在制作自己的资料科学作品集, 也许可以考虑更高阶且更美观的绘图套件。另外如果你使用 Jupyter Notebook 进行开发, 不需要执行 plt.show(), 如果你对 Jupyter Notebook 有兴趣可以参阅 Definitive Guide to Jupyter Notebook。

让我们分开来看前一段程式码:

  1. 将不同的颜色储存在一个 list 中。由于相异的目标值有 10 个(0 到 9), 所以我们指定了 10 种不同的颜色来标示。
  2. 设定 x 轴与 y 轴。分别选出reduced_data_rpca 的第一栏与第二栏, 根据不同的目标值选出对应的观测值, 意即当回圈开始的时候, 会选出目标值为0 的观测值, 接着是目标值为1 的观测值, 依此类推。
  3. 画出散布图。当回圈开始的时候, 会将目标值为 0 的观测值用黑色(black)画出, 接着是将目标值为 1 的观测值用蓝色(blue)画出, 依此类推。
  4. 使用 target_names 键值在散布图旁边加上图例。
  5. 加入图形标题与座标轴标签。
  6. 显示图形。

下一步呢?

在对资料本身有了一定认知后, 我们必须思索的是如何应用, 以及使用什么样的机器学习演算法来建立预测模型。

秘诀:对资料的认知程度愈高, 愈容易找到应用与合适的机器学习演算法。

然而对于 scikit-learn 的初学者来说, 这个套件的内容有点过于庞大, 这时你可以参考scikit-learn 机器学习地图来获得额外的帮助。

我们想要对digits 资料使用非监督式学习演算法, 在这个机器学习地图上我们沿着资料超过50 个观测值(确认!)、预测类别(确认!)、没有目标值(只要不使用digits. target 即可, 确认!)、需要知道有几个类别要预测(确认!)以及需要小于1 万个观测值(确认!), 我们可以顺利应用K-Means!

但是 K-Means 演算法究竟是什么? K-Means 演算法是最简单且最广泛被运用来解决分群问题的非监督式学习演算法。演算法首先随意设定 k 个中心点, 然后计算各个观测值与这 k 个中心点的距离, 然后将观测值分配给距离最近的中心点贴上标签, 形成 k 个群集。接着这 k 个中心点的位置会被重新计算并移动到各个群集目前的中心, 然后再重新计算各个观测值与这 k 个中心点的距离, 更新各个观测值的群集标签。前述的流程会重复进行, 一直到各个观测值的群集标签稳定不更动为止。 k 值由使用者指定, 而一开始这k 个中心点的位置则是随机摆放, 这些随机摆放的位置会影响K-Means 演算法的结果, 可以透过设定n-init 参数来处理这个问题。

资料的预处理

在开始使用 K-Means 演算法之前, 我们应该先学习关于资料的预处理(Preprocessing)。

资料的标准化

我们使用sklearn.preprocessing 模组的scale() 方法将digits 资料作标准化, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

透过标准化, 我们将这 64 个维度的分布转换为平均数为 0, 标准差为 1 的标准常态分布。

将资料切分为训练与测试资料

为了之后要评估模型的表现, 我们也需要将资料切分为训练与测试资料, 训练资料是用来建立模型, 测试资料则用来评估模型。实务中两个资料不会有交集, 常见的切分比例是 2/3 作为训练资料, 1/3 作为测试资料。

在接下来的程式我们将train_test_split() 方法中的test_size 参数设为0.25, 另外一个参数random_state 设为42 用来确保每次切分资料的结果都相同, 如果你希望产出可复制的结果, 这是非常实用的技巧。试着依照注解的提示完成程式后点选 Run 观察结果, 如果没有头绪, 可以点选 Solution 将程式完成后再点选 Run 观察结果:

切分完训练与测试资料之后, 我们很快地看一下训练资料的观测值与目标值资讯, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

现在训练资料X_train 有1347 个观测值, y_train 有1347 个目标值, 恰好是原始资料digits 的2/3;而X_test 有450 个观测值, y_test 有450 个目标值, 恰好是原始资料digits 的1/ 3。

digits 资料的分群

经过标准化与切分之后, 我们就可以开始使用 K-Means 演算法, 透过 cluster 模组的 KMeans() 方法来建立模型, 在这里要注意三个参数:init、n_clusters 与 random_state。你一定还记得random_state, 这个参数能够确保我们每次执行这段程式得到的结果相同, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

init 参数指定我们使用的 K-Means 演算法 k-means++, init 参数预设就是使用 K-Means 演算法, 所以这个参数其实是可以省略的。

n_clusters 参数被设定为 10, 这呼应了我们有 0 到 9 这 10 个相异目标值。假使在未知群集的情况下, 通常会尝试几个不同的n_clusters 参数值, 分别计算平方误差和(Sum of the Squared Errors, SSE), 然后选择平方误差和最小的那个n_clusters 作为群集数, 换句话说就是让各个群集中的每个观测值到群集中心点的距离最小化。

再提醒一下, 不需要将测试资料放入模型中, 测试资料是用来评估模型的表现。接着我们可以利用将各个群集的中心图片视觉化:


# 建立 K-Means 模型
from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import scale
import numpy as np
from sklearn import cluster

digits = datasets.load_digits()
data = scale(digits.data)
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)
clf = cluster.KMeans(init='k-means++', n_clusters=10, random_state=42)
clf.fit(X_train)

# 載入 matplotlib
import matplotlib.pyplot as plt

# 設定圖形的大小
fig = plt.figure(figsize=(8, 3))

# 圖形標題
fig.suptitle('Cluster Center Images', fontsize=14, fontweight='bold')

# 對所有的目標值(0 - 9)
for i in range(10):
    # 在 2x5 的網格上繪製子圖形
    ax = fig.add_subplot(2, 5, i + 1)
    # 顯示圖片
    ax.imshow(clf.cluster_centers_[i].reshape((8, 8)), cmap=plt.cm.binary)
    # 將座標軸刻度關掉
    plt.axis('off')

# 顯示圖形
plt.show()
Scikit-Learn教程:Python与机器学习4

接下来我们要预测测试资料的目标值, 试着依照注解的提示完成程式后点选 Run 观察结果, 如果没有头绪, 可以点选 Solution 将程式完成后再点选 Run 观察结果:

在上述的程式中, 我们预测450 笔测试资料的目标值并将结果储存于y_pred 之中, 接着将y_pred 与y_test 的前100 个元素印出, 很快就可以看到一些结果, 知道哪几个观测值预测正确, 哪几个观测值预测错误。

接着我们来将预测的目标值视觉化:


# 建立 K-Means 模型
from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import scale
import numpy as np
from sklearn import cluster
# 載入 `Isomap()`
from sklearn.manifold import Isomap

digits = datasets.load_digits()
data = scale(digits.data)
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)
clf = cluster.KMeans(init='k-means++', n_clusters=10, random_state=42)
clf.fit(X_train)

# 使用 Isomap 對 `X_train` 資料降維
X_iso = Isomap(n_neighbors=10).fit_transform(X_train)

# 使用 K-Means 演算法
clusters = clf.fit_predict(X_train)

# 在 1x2 的網格上繪製子圖形
fig, ax = plt.subplots(1, 2, figsize=(8, 4))

# 調整圖形的外觀
fig.suptitle('Predicted Versus Training Labels', fontsize=14, fontweight='bold')
fig.subplots_adjust(top=0.85)

# 加入散佈圖 
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')

# 顯示圖形
plt.show()

这次我们改用 Isomap() 来对 digits 资料进行降维, 跟主成份分析不同的地方是 Isomap 属于非线性的降维方法。

Scikit-Learn教程:Python与机器学习5

秘诀:改用主成份分析重新执行上面的程式, 并观察跟 Isomap 有什么差异:


# 建立 K-Means 模型
from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import scale
import numpy as np
from sklearn import cluster
# 載入 `PCA()`
from sklearn.decomposition import PCA

# 使用 PCA 對 `X_train` 資料降維
X_pca = PCA(n_components=2).fit_transform(X_train)

# 使用 K-Means 演算法
clusters = clf.fit_predict(X_train)

# 在 1x2 的網格上繪製子圖形
fig, ax = plt.subplots(1, 2, figsize=(8, 4))

# 調整圖形的外觀
fig.suptitle('Predicted Versus Training Labels', fontsize=14, fontweight='bold')
fig.subplots_adjust(top=0.85)

# 加入散佈圖 
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')

# 顯示圖形
plt.show()
Scikit-Learn教程:Python与机器学习6

我们发现 K-Means 演算法的效果可能不是很好, 但还需要更进一步评估。

评估分群模型的表现

评估模型的表现是机器学习很重要的课题, 我们首先将混淆矩阵(Confusion matrix)印出, 试着依照注解的提示完成程式后点选Run 观察结果, 如果没有头绪, 可以点选Solution 将程式完成后再点选Run 观察结果:

我们可以看到 41 个 5 被正确预测, 11 个 8 被正确预测, 但混淆矩阵并不是唯一的评估方式, 还有非常多的评估指标可以参考, 直接点选 Run 观察结果:

这些指标包含了:

  • 同质性评分
  • 完整性分数
  • V测量分数
  • 调整后的兰德评分
  • 调整后的相互信息得分, AMI得分
  • 轮廓分数

但这些评估指标都不是太好, 像是silhouette score 接近0, 代表很多的观测值都接近分群边界而可能被分到错误的群集中;而ARI 则告诉我们同一群集中的观测值没有完全相同; Completeness score 则告诉我们一定有观测值被分在错误的群集。

这提示我们针对 digits 资料也许应该尝试另外一种演算法。

尝试另外一种演算法:支持向量机(Support Vector Machines, SVM)

当训练资料没有目标值的时候适用前述的分群演算法, 当训练资料具有目标值的时候就能够适用分类演算法。我们再回顾一下 scikit-learn 机器学习地图, 在分类演算的区域第一个看到的是线性 SVC, 让我们对 digits 资料使用这个演算法试试看, 直接点选 Run 观察结果:

在这段程式中我们手动设定了gamma 参数, 但其实透过网格搜索(Grid search)或交叉验证(Cross validation)都可以自动找出合适的参数设定, 但这些方法并不是这份教学的重点, 所以我们只是很快地展示一下如何使用网格搜索来调整参数而不去深究, 直接点选Run 观察结果:

接下来, 我们会比较手动设定参数与使用网格搜索调整参数的两个分类器, 看看网格搜索找出来的参数是不是真的比较好, 直接点选 Run 观察结果:

在这样的参数设定下准确率高达 99%!

在使用网格搜索以前, 我们将 kernel 参数指定为 linear, 在 SVM 演算法 kernel 参数预设为 rbf, 而除了前面指定的 linear, 尚可以设定为 poly。但是究竟 kernel 是什么? kernel 是一种计算训练资料观测值相似度的函数, SVM 演算法利用这个函数来进行分类, 我们先假设这些观测值线性可分, 所以设定kernel = linear, 但是网格搜索的结果则建议我们使用kernel = rbf 的参数设定。

我们接着使用 kernel = linear 的分类器来预测测试资料, 试着依照注解的提示完成程式后点选 Run 观察结果, 如果没有头绪, 可以点选 Solution 将程式完成后再点选 Run 观察结果:

视觉化手写数字图片与预测的结果:


# 使用 SVC 演算法
from sklearn import datasets
from sklearn.preprocessing import scale
from sklearn import cluster
digits = datasets.load_digits()
data = scale(digits.data)
from sklearn.cross_validation import train_test_split
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)
from sklearn import svm
svc_model = svm.SVC(gamma=0.001, C=100., kernel='linear')
svc_model.fit(X_train, y_train)

# 載入 matplotlib
import matplotlib.pyplot as plt

# 將預測結果指派給 `predicted`
predicted = svc_model.predict(X_test)

# 將 `images_test` 與 `predicted` 存入 `images_and_predictions`
images_and_predictions = list(zip(images_test, predicted))

# 繪製前四個元素
for index, (image, prediction) in enumerate(images_and_predictions[:4]):
    # 在 1x4 的網格上繪製子圖形
    plt.subplot(1, 4, index + 1)
    # 關掉座標軸的刻度
    plt.axis('off')
    # 色彩用灰階
    plt.imshow(image, cmap=plt.cm.binary)
    # 加入標題
    plt.title('Predicted: ' + str(prediction))

# 顯示圖形
plt.show()

这跟我们在探索性分析时作的视觉化非常相似, 只是这次我们只显示了前面四个测试资料与预测结果。

""

那么这个模型的表现如何呢?试着依照注解的提示完成程式后点选 Run 观察结果, 如果没有头绪, 可以点选 Solution 将程式完成后再点选 Run 观察结果:

我们很明显地看出 SVC 表现得比先前的 K-Means 分群好得太多, 接着我们利用 Isomap() 视觉化预测结果与目标值:


# 使用 SVC 演算法
from sklearn import datasets
from sklearn.preprocessing import scale
from sklearn import cluster
import matplotlib.pyplot as plt
from sklearn.manifold import Isomap

digits = datasets.load_digits()
data = scale(digits.data)
from sklearn.cross_validation import train_test_split
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)
from sklearn import svm
svc_model = svm.SVC(gamma=0.001, C=100., kernel='linear')
svc_model.fit(X_train, y_train)

# 對 `digits` 資料降維
X_iso = Isomap(n_neighbors=10).fit_transform(X_train)

# 使用 SVC 演算法
predicted = svc_model.predict(X_train)

# 在 1x2 的網格上繪製子圖形
fig, ax = plt.subplots(1, 2, figsize=(8, 4))

# 調整外觀
fig.subplots_adjust(top=0.85)

# 繪製散佈圖 
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')

# 加入標題
fig.suptitle('Predicted versus actual labels', fontsize=14, fontweight='bold')

# 顯示圖形
plt.show()

完成后我们可以看到这张散布图:

""

从上图我们可以看到非常好的分类结果, 这真是天大的好消息 🙂

下一步呢?

图片辨识

恭喜你完成了这份教学, 我们示范了如何对 digits 资料使用监督式与非监督式的机器学习演算法!假如你想要练习更多关于数字图片辨识的机器学习演算法, 那绝对不能错过 MNIST 资料, 你可以在这里下载。

处理 MNIST 资料的手法跟这份教学的内容非常相似, 除此之外你还可以参阅这个网页如何对 MNIST 资料使用 K-Means 演算法。

如果你已经练习过使用scikit-learn 辨识手写数字图片, 也许可以考虑挑战更高难度的字母与数字图片辨识, 这个著名的资料是Chars74K, 包含了74, 000 张除了手写数字0 到9 以外, 还有大写A 到Z 以及小写的a 到z 的图片, 你可以在这里下载。

资料视觉化与 pandas 套件

这份教学主要的内容简介是Python 与机器学习, 但这只是我们跟Python 与资料科学旅程的开端而已, 如果对于资料视觉化有兴趣接下来可以参阅Interactive Data Visualization with Bokeh course 或者对于在Python 中使用资料框(data frame)有兴趣可以参阅pandas Foundation course。

赞(0)
未经允许不得转载:srcmini » Scikit-Learn教程:Python与机器学习

评论 抢沙发

评论前必须登录!