Python-机器学习小项目

守給你的承諾、 提交于 2020-01-06 10:05:43

原文地址:https://segmentfault.com/a/1190000017067753?utm_source=tag-newest

学习机器学习相关技术的最好方式就是先自己设计和完成一些小项目。

Python 是一种非常流行和强大的解释性编程语言。不像 R 语言,Python 是个很完整的语言和平台,你既可以用来做研发,也可以用来开发产品体系。

而且,Python 还有很多模块和程序库供我们选择,从而针对一个任务能有很多个解决方案。怎么样,听起来还是很厉害的吧?

如果用 Python 执行机器学习,刚开始时最好方式就是先完成一个小项目,为什么这么说呢?

因为这会让你先懂得如何安装和启动 Python 解释器(这是最起码的要求吧)。
因为这会让你从总体上知道怎样一步步完成一个项目。
因为这会增加你的信心,或许能让你开始创建自己的小项目。

新手很需要一个完整的小项目练手

教材书还有课程这些东西还是比较烦人的,虽然给你讲解的很细,讲的也很多,但都太零碎,你单靠这些很难领会这些知识点如何综合运用到一起。

将机器学习运用到自己的数据集上时,就算是开始一个项目了。

一个机器学习项目可能并不是直线式的,但是很多步骤都是耳熟能详:

定义问题。
准备数据。
评估算法。
优化结果。
呈现结果。

真正掌握一个新平台新工具的最好方法,就是用它一步步完成一个完整的机器学习项目,并涉及所有的重要步骤,也就是从导入数据,总结数据,评估算法到做出预测等。

这么一套流程操作下来,你大概就能明白其中的套路了。

机器学习的 Hello World

先开始拿来练手的一个最好的小项目就是分类鸢尾花(数据集链接),这项目很适合新手,因为非常简单易懂。

因为属性都是数值,所以你要知道这么去导入和处理数据。

该项目是个分类问题,能让你练习操作一种相对简单的监督式学习算法。

同时它也是个多类分类问题,因此可能需要一些特殊的处理方法。

它只有 4 个属性和 150 个示例,意味着数据集很小,不会占太多内存。

所有数值属性都有相同的单位和大小,在使用前无需进行特别的缩放和转换。

下面我们就开始学习如何用 Python 执行机器学习中的 Hello World。

用 Python 进行机器学习:手把手教程

在这部分,我们会完成一个完整的机器学习小项目,下面是主要步骤:

安装 Python 和 SciPy 平台。
导入数据集。
总结数据集。
可视化数据集。
评估算法。
做出预测。

可以自己试着敲命令行代码,要想加快速度,也可以复制粘贴我的代码。

1.下载、安装和启动 Python SciPy

如果你电脑上没安装,先安装 Python 和 SciPy 平台。

这部分不再细说,因为网上有很多教程。

1.1 安装 SciPy 程序库

本文所用 Python 版本为 2.7 或 3.5 。

scipy
numpy
matplotlib
pandas
Sklearn

安装上面这些程序库有很多种方法,建议选择选择一种方法,然后安装这些程序库都用这种方法。

SciPy 安装页面上提供了在多种系统安装上文程序库的详细方法:

在 Mac OS 上,你可以用 macports 安装 Python2.7 和这些程序库,更多信息点击这里
在 Linux 上,可以用你的软件包管理器,就跟在 Fedora 上安装 RPM 一样。
如果你是 Windows 系统,建议安装免费版的 Anaconda。

注意:上面这些方法的基础是你的电脑上已经安装了 0.18 或更高版本的 scikit-learn。

1.2启动 Python,检查程序版本

这一步很重要,一定要确保你成功安装了 Python 环境,可以正常运行。

下面的脚本可以帮你测试你的 Python 环境,它会导入本教程所需的每个程序库,并导出相应版本。

打开命令行,启动 Python 解释器:

Python

我建议你直接在解释器上工作,或者写出脚本后在命令行上运行,不用在很大的编辑器和 IDE上跑脚本。我们要关注的重点是机器学习,而不是软件工具。

输入或复制粘贴以下脚本:

# Check the versions of libraries
 
# Python version
import sys
print('Python: {}'.format(sys.version))
# scipy
import scipy
print('scipy: {}'.format(scipy.__version__))
# numpy
import numpy
print('numpy: {}'.format(numpy.__version__))
# matplotlib
import matplotlib
print('matplotlib: {}'.format(matplotlib.__version__))
# pandas
import pandas
print('pandas: {}'.format(pandas.__version__))
# scikit-learn
import sklearn
print('sklearn: {}'.format(sklearn.__version__))

如果在 OS X 工作站上运行,会得到如下输出:

Python: 2.7.11 (default, Mar 1 2016, 18:40:10) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)]
scipy: 0.17.0
numpy: 1.10.4
matplotlib: 1.5.1
pandas: 0.17.1
sklearn: 0.18.1

可以和你自己的输出对照一下。

理想状况下,两者应该一样或者大部分很接近。API 一般不会快速变化,所以如果你的版本有点低的话,也不用担心,本教程仍然适用你后面的学习。

如果你在这里出现了错误,先暂停一下,修正错误。

如果你没法流畅的运行上述脚本,那你后面就没法完整地完成这篇教程。

建议针对你出现的错误上网搜一下,或者问问有经验的人,比如上集智社区。

2.导入数据

我们要用的是鸢尾花数据集,这数据集很有名,几乎入门学习机器学习的人最先用的数据集就是它了,可以说是机器学习数据集中的 Hello Word。

它包含了 150 个鸢尾花观察值,花的测量值以厘米为单位分为 4 列。第 5 列是观察到的花朵的种类。所有观察花朵都属于三个种类。

在这一步,我们会从 CSV 文件 URL 中导入鸢尾花数据。

2.1 导入程序库

首先,我们导入本教程用到的所有模块、函数和对象。

# Load libraries
import pandas
from pandas.plotting import scatter_matrix
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

所有信息导入时必须准确无误。如果出现错误,马上停止。在继续操作前,一定确保得到正确的 SciPy 环境。

2.2 导入数据集

我们可以从 UCI 机器学习库中直接导入数据,使用工具为 Pandas。我们下面还会接着用它来进行数据统计和可视化工作。

注意,我们在导入数据时会指明每一列的名字,这有助于后面我们处理数据。

# Load dataset
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
dataset = pandas.read_csv(url, names=names)

导入数据集时也应没有任何差错。

如果你出现了网络问题,可以将iris.data 文件下载至你的工作目录,然后将 URL 改为本地文件名,用同样的方法导入它。

3.总结数据集

现在我们可以看一看数据了。

在这一步,我们以多个方式分析一下数据:

数据集的维度。
详细查看数据本身。
所有属性的统计摘要。
数据根据类别变量的分类状况。

别担心,每种方式只有一行命令行。这些命令行不是一次性的,将来项目里可以重复使用,绝不浪费。

3.1 数据集维度

我们可以快速的了解数据的形状属性包含了多少行(示例)和多少列(属性)。

# shape
print(dataset.shape)

你应该会看到有 150 行和 5 列:

(150, 5)

3.2 详细查看数据

认认真真看看你数据总归是件好事。

# head
print(dataset.head(20))
你应该会看到数据的前20行:
  sepal-length sepal-width petal-length petal-width       class
0           5.1         3.5          1.4         0.2 Iris-setosa
1           4.9         3.0          1.4         0.2 Iris-setosa
2           4.7         3.2          1.3         0.2 Iris-setosa
3           4.6         3.1          1.5         0.2 Iris-setosa
4           5.0         3.6          1.4         0.2 Iris-setosa
5           5.4         3.9          1.7         0.4 Iris-setosa
6           4.6         3.4          1.4         0.3 Iris-setosa
7           5.0         3.4          1.5         0.2 Iris-setosa
8           4.4         2.9          1.4         0.2 Iris-setosa
9           4.9         3.1          1.5         0.1 Iris-setosa
10          5.4         3.7          1.5         0.2 Iris-setosa
11          4.8         3.4          1.6         0.2 Iris-setosa
12          4.8         3.0          1.4         0.1 Iris-setosa
13          4.3         3.0          1.1         0.1 Iris-setosa
14          5.8         4.0          1.2         0.2 Iris-setosa
15          5.7         4.4          1.5         0.4 Iris-setosa
16          5.4         3.9          1.3         0.4 Iris-setosa
17          5.1         3.5          1.4         0.3 Iris-setosa
18          5.7         3.8          1.7         0.3 Iris-setosa
19          5.1         3.8          1.5         0.3 Iris-setosa

3.3 统计摘要

现在我们可以看看对每个属性的统计摘要,包含了数量、平均值、最大值、最小值,还有一些百分位数值。

# descriptions
print(dataset.describe())

我们可以看到所有的数字值都有相同的单位(厘米),大小也都在0到8厘米之间。

sepal-length sepal-width petal-length petal-width
count   150.000000  150.000000   150.000000  150.000000
mean      5.843333    3.054000     3.758667    1.198667
std       0.828066    0.433594     1.764420    0.763161
min       4.300000    2.000000     1.000000    0.100000
25%       5.100000    2.800000     1.600000    0.300000
50%       5.800000    3.000000     4.350000    1.300000
75%       6.400000    3.300000     5.100000    1.800000
max       7.900000    4.400000     6.900000    2.500000

3.4 类别分布

我们现在看一看属于每个类别下的行的数量,可以将其看作一个绝对计数。

class
Iris-setosa       50
Iris-versicolor   50
Iris-virginica    50

4.数据可视化

我们现在对数据已经有了一个基本的了解,现在需要用一些可视化形式再扩展一下对数据的认识。

主要是看两种可视化图:

单变量图形,从而更好的理解每个属性。
多变量图形,从而更好的理解各个属性之间的关系。

4.1 单变量图形

我们先以一些单变量图形开始,也就是每个单独变量的图形。

考虑到输入变量都是数字,我们可以为每个输入变量创建箱线图。

# box and whisker plots
dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
plt.show()

这能让我们更清晰的看到输入属性的分布状况:

我们也可以为每个输入变量创建一个直方图以了解它们的分布状况。

# histograms
dataset.hist()
plt.show()

似乎其中两个输入变量呈高斯分布,这点是有点用的,因为我们后面可以用算法充分利用这个假设。

4.2 多变量图形

现在我们可以看看变量之间的相互作用。

首先,我们看看全部属性对的散点图,这有助于我们看出输入变量之间的结构化关系。

# scatter plot matrix
scatter_matrix(dataset)
plt.show()

注意一些属性对呈对角线分布,这显示了它们之间有高度关联性以及可预测的关系。

5.评估算法

现在我们为数据搭建一些模型,并测试它们对不可见数据的准确度。

这一部分的主要步骤为:

将数据集分离出一个验证集。
设定测试工具,使用10折交叉验证。
搭建6个不同的模型根据花朵测量值预测出鸢尾花种类。
选出最佳模型。

5.1 创建验证集

我们需要知道搭建的模型效果怎样。后面我们会用统计方法来验证模型对新数据的准确度。我们还希望通过评估模型在真正不可见数据时的表现,来进一步确定模型的准确度。

也就是我们会留一些数据不让算法看到,然后用这些数据来确定模型到底有多准确。

我们会将导入的数据集拆分为两部分,80% 用于训练模型,20% 用于验证模型。

# Split-out validation dataset
array = dataset.values
X = array[:,0:4]
Y = array[:,4]
validation_size = 0.20
seed = 7
X_train, X_validation, Y_train, Y_validation = model_selection.train_test_split(X, Y, test_size=validation_size, random_state=seed)

得到的 X_train 和 Y_train 里的训练数据用于准备模型,得到的 X_validation 和 Y_validation 集我们后面会用到。

5.2 测试工具

我们会用十折交叉验证法测试模型的准确度。

这会将我们的数据集分成 10 部分,轮流将其中 9 份作为训练数据,1份作为测试数据,进行试验。

# Test options and evaluation metric
seed = 7
scoring = 'accuracy'

现在我们用“准确率”这个维度去评估模型,也就是能正确预测出鸢尾花类别的比例。我们后面运行和评估模型时会使用分数变量。

5.3 搭建模型

针对这个问题,我们并不知道哪个算法最好,应当用哪些配置。我们从可视化图表中能够得知在有些维度上一些类别的部分是线性可分的,因此我们预期总体效果会不错。

我们看看这 6 种算法:

逻辑回归(LR)
线性判别分析(LDA)
K最近邻算法(KNN)
分类和回归树(CART)
高斯朴素贝叶斯(NB)
支持向量机(SVM)

这里面既有简单的线性算法(LA和LDA),也有非线性算法(KNN,CART,NB和SVM)。我们每次运行算法前都要重新设置随机数量的种子,以确保是在用相同的数据拆分来评估每个算法。这样能保证最终结果可以直接进行比较。

我们来搭建和评估模型:

 Spot Check Algorithms
models = []
models.append(('LR', LogisticRegression()))
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('KNN', KNeighborsClassifier()))
models.append(('CART', DecisionTreeClassifier()))
models.append(('NB', GaussianNB()))
models.append(('SVM', SVC()))
# evaluate each model in turn
results = []
names = []
for name, model in models:
kfold = model_selection.KFold(n_splits=10, random_state=seed)
cv_results = model_selection.cross_val_score(model, X_train, Y_train, cv=kfold, scoring=scoring)
results.append(cv_results)
names.append(name)
msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
print(msg)

5.4 选择最佳模型

我们现在获得了 6 个模型以及每种模型的准确度评估状况。接下来需要将模型相互比较,选出最准确的那个。

运行上面的例子,会得到如下初步结果:

LR: 0.966667 (0.040825)
LDA: 0.975000 (0.038188)
KNN: 0.983333 (0.033333)
CART: 0.975000 (0.038188)
NB: 0.975000 (0.053359)
SVM: 0.981667 (0.025000)

我们可以看到似乎 KNN 的估计准确率分值最高。

我们也可以将模型评估结果用图形表示出来,比较每个模型的跨度和平均准确度。这种衡量模型准确率的方法比较流行,因为每种算法都被评估了 10 次(十折交叉验证法)。

# Compare Algorithms
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()

你可以看到箱线图的顶部范围 呈压缩状,不少模型都达到了 100% 的准确率。

6.做出预测

经过验证,KNN 算法的准确率最高。现在我们看看该模型在验证集上的准确度。

我们最后来验证一下最好的模型的准确率有多高。拆分并保留一个验证集很值得,以防你在训练期间出现错误,比如对训练集过拟合或者数据泄露之类,这两种错误都会造成最终结果过于乐观。

我们可以直接在验证集上运行 KNN 算法,将结果总结为一个最终准确率分值,一个混淆矩阵和一个分类报告。

# Make predictions on validation dataset
knn = KNeighborsClassifier()
knn.fit(X_train, Y_train)
predictions = knn.predict(X_validation)
print(accuracy_score(Y_validation, predictions))
print(confusion_matrix(Y_validation, predictions))
print(classification_report(Y_validation, predictions))

我们可以看到模型的准确率为 0.9,即 90%。混淆矩阵显示了所犯的三个错误。最终,分类报告显示了每个类别的精确率、召回率、F1 值等。

[[ 7 0 0]
 [ 0 11 1]
 [ 0 2 9]]
 
             precision   recall f1-score  support
 
Iris-setosa      1.00     1.00     1.00        7
Iris-versicolor  0.85     0.92     0.88       12
Iris-virginica   0.90     0.82     0.86       11
 
avg / total      0.90     0.90     0.90       30

人人可用 Python 做机器学习任务

把上面的这篇教程过一遍,最多花你5-10分钟!

你不需要什么都懂。 你的目标就是完整的跟着操作一遍这个教程,然后得到结果。刚开始你不必什么都懂。可以一边做一边列出问题,多用用 help(FunctionName) 帮你理解 Python 中的语法,学习你正在用的函数。

你不需要明白算法的原理 。当然,知道机器学习算法的局限性和配置方式很重要,但对算法原理的学习可以放在后头。你应该循序渐进的了解算法的原理,在当前阶段主要任务就是熟悉平台。

你也不必是个Python程序员。 如果你是个 Python 初学者,Python 的语法会很陌生。和其它语言一样,重点关注函数调用和赋值,后面再详细深挖语法知识。

你也不用是个机器学习专家。 你可以在后面学习每种算法的好处和局限性,而且这方面有很多资料,比如关于机器学习项目的操作步骤,以及用验证集评估模型的重要性等。

机器学习项目的其它步骤。 本文并没有涉及机器学习项目的全部步骤,因为这毕竟是我们的第一个项目,关注重要步骤就行了,也就是:导入数据、查看数据、评估算法、做出预测.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!