数据科学机器学习是我大三立志读研的研究方向,虽然今年初战失败了但这个执念始终无法放下。在成绩发表之际写下这一篇博文入门提醒自己不忘初心,调剂失败的话明年再来。
前言
事先说明,这虽然是一篇机器学习入门文章,但完全没有任何机器学习基础。这个文章旨在说明机器学习的基本流程和需要的各种环境、工具的简介。
执行环境、工具
数据科学所需的 numpy、pandas 等工具包属于 python 第三方库,个别安装比较麻烦,因此使用数据科学中广泛使用的工具包——Anaconda,这个工具中包含了大多数包,并集合 jupyter notebook 编辑运算工具。环境上 Python 2.7 可能在几年内停止官方支持,因此使用 Python 3 环境运行。
运行方法
安装过程不在此赘述,简要说明 Jupyter notebook 的运行方式:
运行 Anaconda Prompt,这个是 Anaconda 的命令行工具。
执行命令>>> jupyter notebook
为启动编辑器,但当前目录为 Anaconda 所在的根目录。如果想在项目文件夹下运行,需要在 prompt 中进入项目文件夹,文件访问命令和 Command 命令相同。
以我的项目文件夹为例:
(base) C:\Users\Username>g:
(base) G:\>cd G:\desktop\dev-python-workspace\anaconda
(base) G:\desktop\dev-python-workspace\anaconda>jupyter notebook
执行命令之后会在默认浏览器启动本地网页 jupyter notebook
参考视频:如何安装 Python 运行环境 Anaconda?_腾讯视频
机器学习的主要过程
- 定义问题。
- 准备数据。
- 评估算法。
- 优化结果。
- 呈现结果。
机器学习的 Hello World
先开始拿来练手的一个最好的小项目就是分类鸢尾花(数据集链接),这项目很适合新手,因为非常简单易懂。
因为属性都是数值,所以你要知道这么去导入和处理数据。
该项目是个分类问题,能让你练习操作一种相对简单的监督式学习算法。
同时它也是个多类分类问题,因此可能需要一些特殊的处理方法。
它只有 4 个属性和 150 个示例,意味着数据集很小,不会占太多内存。
所有数值属性都有相同的单位和大小,在使用前无需进行特别的缩放和转换。
下面我们就开始学习如何用 Python 执行机器学习中的 Hello World。
1. 检测环境、导入数据包
启动 jupyter notebook,复制或粘贴以下脚本
检查版本、库是否存在
# 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__))
输出(版本号)如果正常输出版本号说明依赖安装正常
Python: 3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)]
scipy: 1.1.0
numpy: 1.15.4
matplotlib: 3.0.2
pandas: 0.23.4
sklearn: 0.20.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
2. 导入数据集
我们要用的是鸢尾花数据集,这数据集很有名,几乎入门学习机器学习的人最先用的数据集就是它了,可以说是机器学习数据集中的 Hello Word。
它包含了 150 个鸢尾花观察值,花的测量值以厘米为单位分为 4 列。第 5 列是观察到的花朵的种类。所有观察花朵都属于三个种类。
在这一步,我们会从 CSV 文件 URL 中导入鸢尾花数据。
从 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)
本文采用在线导入,如果网络有问题可以使用本地导入,下载后将 url 改为本地路径即可。
3. 总结数据集
现在我们可以看一看数据了。
在这一步,我们以多个方式分析一下数据:
数据集的维度。
详细查看数据本身。
所有属性的统计摘要。
数据根据类别变量的分类状况。
数据集维度
了解数据的形状属性包含了多少行(示例)和多少列(属性)
# shape
print(dataset.shape)
你应该会看到有 150 行和 5 列:
(150, 5)
详细查看数据
# 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
统计摘要
# 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
4. 数据可视化
我们现在对数据已经有了一个基本的了解,现在需要用一些可视化形式再扩展一下对数据的认识。
主要是看两种可视化图:
单变量图形,从而更好的理解每个属性。 多变量图形,从而更好的理解各个属性之间的关系。
单变量图形
我们先以一些单变量图形开始,也就是每个单独变量的图形。
考虑到输入变量都是数字,我们可以为每个输入变量创建箱线图。
# box and whisker plots
dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
plt.show()
输出
我们也可以为每个输入变量创建一个直方图以了解它们的分布状况。
# histograms
dataset.hist()
plt.show()
输出
多变量图形
现在我们可以看看变量之间的相互作用。
首先,我们看看全部属性对的散点图,这有助于我们看出输入变量之间的结构化关系。
# scatter plot matrix
scatter_matrix(dataset)
plt.show()
输出
5. 评估算法
现在我们为数据搭建一些模型,并测试它们对不可见数据的准确度。
这一部分的主要步骤为:
将数据集分离出一个验证集。
设定测试工具,使用 10 折交叉验证。
搭建 6 个不同的模型根据花朵测量值预测出鸢尾花种类。
选出最佳模型。
创建验证集
我们需要知道搭建的模型效果怎样。后面我们会用统计方法来验证模型对新数据的准确度。我们还希望通过评估模型在真正不可见数据时的表现,来进一步确定模型的准确度。
也就是我们会留一些数据不让算法看到,然后用这些数据来确定模型到底有多准确。
我们会将导入的数据集拆分为两部分,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 集我们后面会用到。
测试工具
我们会用十折交叉验证法测试模型的准确度。
这会将我们的数据集分成 10 部分,轮流将其中 9 份作为训练数据,1 份作为测试数据,进行试验。
# Test options and evaluation metric
seed = 7
scoring = 'accuracy'
现在我们用“准确率”这个维度去评估模型,也就是能正确预测出鸢尾花类别的比例。我们后面运行和评估模型时会使用分数变量。
搭建模型
针对这个问题,我们并不知道哪个算法最好,应当用哪些配置。我们从可视化图表中能够得知在有些维度上一些类别的部分是线性可分的,因此我们预期总体效果会不错。
我们看看这 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)
输出
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.991667 (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
[[ 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
micro avg 0.90 0.90 0.90 30
macro avg 0.92 0.91 0.91 30
weighted avg 0.90 0.90 0.90 30
结论:我们可以看到模型的准确率为 0.9,即 90%。混淆矩阵显示了所犯的三个错误。最终,分类报告显示了每个类别的精确率、召回率、F1 值等。
以上为鸢尾花数据集的入门机器学习。
Be Iris to you.
参考资料: