1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 机器学习实战 | Python机器学习算法应用实践

机器学习实战 | Python机器学习算法应用实践

时间:2019-02-24 01:53:56

相关推荐

机器学习实战 | Python机器学习算法应用实践

作者:韩信子@ShowMeAI

教程地址:https://www.showmeai.tech/tutorials/41

本文地址:https://www.showmeai.tech/article-detail/201

声明:版权所有,转载请联系平台与作者并注明出处

收藏ShowMeAI查看更多精彩内容

引言

本篇文章希望带大家完整走一遍机器学习应用流程,我们会讲解到基于Python的机器学习算法,应用在结构化数据和非结构化数据(图像)上,希望通过文章内容帮助大家在案例中重温机器学习基础知识,并学习应用机器学习解决问题的基本流程。

文章中会用到下述两个库来实现机器学习算法:

Scikit-Learn:最常用的python机器学习算法工具库之一。Keras:便捷的深度学习神经网络搭建应用工具库。

对于上述两个工具库的用法,大家也可以通过ShowMeAI的文章AI建模工具速查 | Scikit-Learn使用指南AI建模工具速查 | Keras使用指南来快速查询和使用。

在本篇文章中,我们将讲解到以下内容:

问题抽象与理解数据准备与处理(预处理、特征提取、特征工程等)各种机器学习算法实验结果分析与对比模型选择与调优

我们会覆盖到的机器学习算法包括:KNN、朴素贝叶斯、逻辑回归、SVM、决策树、随机森林、感知机、前馈神经网络、卷积神经网络。

1.环境准备

工欲善其事必先利其器,我们先安装一下必需的Python库(当然我们也推荐大家用集成环境anaconda,具体的安装与设置可以参考ShowMeAI文章图解Python | 安装与环境设置完成):

Numpy:用于Python的科学计算。 相关重点知识请查看数据科学工具速查 | Numpy使用指南或者图解数据分析:从入门到精通系列教程中的Numpy详解教程。 PIL:一个简单的图像处理库。Scikit-Learn:包含多种机器学习算法。 相关重点知识请查看AI建模工具速查 | Scikit-Learn使用指南Kears和TensorFlow:用于深度学习。本教程可以仅采用CPU版本的TensorFlow。 相关重点知识请查看AI建模工具速查 | TensorFlow使用指南AI建模工具速查 | Keras使用指南OpenCV:本教程并不直接使用OpenCV,但imutils库依赖它。 相关重点知识请查看AI建模工具速查 | OpenCV使用指南imutils:图像处理/计算机视觉库。

可以采用pip安装,命令如下:$ pip install numpy$ pip install pillow$ pip install --upgrade scikit-learn$ pip install tensorflow # or tensorflow-gpu$ pip install keras$ pip install opencv-contrib-python$ pip install --upgrade imutils

2.数据集

因为本篇文章我们介绍结构化数据和非结构化数据的不同建模,我们这里用到两个数据集。

2.1 iris(鸢尾花)数据集

第一个数据集是iris(鸢尾花)数据集,它是一个入门级数据集。整个数据集都是数值型的数据,是一个结构化的表格数据,每一行代表一个样本,然后每一列就是不同的属性。

这个数据集主要是收集了三种不同的鸢尾花的数据,分别为:

Iris SetosaIris VersicolorIris Virginica

对应图中最后一列Class label,然后还有四种属性,分别是:

Sepal length:萼片长度Sepal width:萼片宽度Petal length:花瓣长度Petal width:花瓣宽度

对于该数据集,我们的目标就是根据给定的四个属性,训练一个机器学习模型来正确分类每个样本的类别,这是一个典型的分类任务。

2.2 图像数据集

第二个数据集是一个图像数据集。它包括海岸线(Coast)、森林(Forest)和高速公路(Highway)三种场景,总共是 948 张图片,我们需要构建模型完成类别的分类,每个类别的具体图片数量如下:

海岸线(Coast):360森林(Forest):328高速公路(Highway):260

3.机器学习应用步骤

我们在不同场景下应用机器学习算法,都有大致的步骤,比如下面是一个典型的机器学习应用流程:

当然,并不是其中的每一步都是必须的,我们也可能会调整其中某些步骤中的细节。

3.1 问题抽象与理解

针对我们的问题,问一下自己:

数据集是哪种类型?数值型,类别型还是图像?模型的最终目标是什么?如何定义和衡量“准确率”呢?以目前自身的机器学习知识来看,哪些算法在处理这类问题上效果很好?

前序问题比较简单,最后的问题,随着大家应用机器学习解决问题的经验积累,可以更准确快速地回答。

3.2 数据准备与处理

数据准备与处理,包括数据预处理以及特征工程了。一般这一步,包括了加载数据、检查数据、探索性数据分析(EDA)、数据预处理,进而决定需要做的特征提取或者特征工程。

特征提取是应用某种算法通过某种方式来量化数据的过程。比如,对于图像数据,我们可以采用计算直方图的方法来统计图像中像素强度的分布,通过这种方式,我们就得到描述图像颜色的特征。

特征工程是将原始输入数据转换成一个更好描述潜在问题的特征表示的过程。大家可以查看ShowMeAI的机器学习专题文章系统了解特征工程的常见方法。

3.3 多模型应用

下一步可以选择各种候选机器学习算法,并应用在数据集上。我们安装的工具包内,包含很多机器学习算法,比如下述模型都可以用作分类:

线性模型(逻辑回归、线性SVM)非线性模型(RBF、SVM、梯度下降分类器)树和基于集成的模型(决策树、随机森林)神经网络(多层感知机、卷积神经网络)

对于模型选择,当然很多需要依据实验效果来定,但我们也有一些先序的经验,比如:

对于稠密型多特征的数据集,随机森林算法的效果很不错;逻辑回归算法可以很好处理高维度的稀疏数据;对于图像数据,CNNs的效果非常好。

下图为scikit-learn工具库官方给的一个模型选择思路参考:

4.构建机器学习流程并实验分析

我们构建如下的代码文件目录,包含四个代码文件和一个3scenes图像文件夹(内含三场景数据集),iris数据集无需另外存储,直接采用scikit-learn库载入即可。

├── 3scenes│ ├── coast [360 entries]│ ├── forest [328 entries]│ └── highway [260 entries]├── iris_classifier.py├── image_classifier.py├── nn_iris.py└── basic_cnn.py

4.1 结构化数据建模

首先实现iris_classifier,我们这里直接使用sklearn的机器学习算法来对iris数据集进行分类。

# 导入需要的库from sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNBfrom sklearn.linear_model import LogisticRegressionfrom sklearn.svm import SVCfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.neural_network import MLPClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportfrom sklearn.datasets import load_irisimport argparse# 设置参数ap = argparse.ArgumentParser()ap.add_argument("-m", "--model", type=str, default="knn", help="type of python machine learning model to use")args = vars(ap.parse_args())# 定义一个保存模型的字典,根据 key 来选择加载哪个模型models = {"knn": KNeighborsClassifier(n_neighbors=1),"naive_bayes": GaussianNB(),"logit": LogisticRegression(solver="lbfgs", multi_class="auto"),"svm": SVC(kernel="rbf", gamma="auto"),"decision_tree": DecisionTreeClassifier(),"random_forest": RandomForestClassifier(n_estimators=100),"mlp": MLPClassifier()}

其中,models从前往后依次包括这些算法:KNN、朴素贝叶斯、逻辑回归、SVM、决策树、随机森林、感知机等。

我们直接调用sklearn中相应的函数来实现对应的算法即可,这里直接用一个models的字典来保存不同模型的初始化,然后根据参数--model来调用对应的模型,比如命令输入python iris_classifier.py --model knn就是调用knn算法模型。

接着就是载入数据部分:

print("加载数据中...")dataset = load_iris()trainX, testX, trainY, testY = train_test_split(dataset.data, dataset.target, random_state=3, test_size=0.2)

这里直接调用sklearn.datasets中的load_iris()载入数据,然后采用train_test_split来划分训练集和数据集,这里是80%数据作为训练集,20%作为测试集。

最后就是训练模型和预测部分:

# 训练模型print("应用 '{}' 模型建模...".format(args["model"]))model = models[args["model"]]model.fit(trainX, trainY)# 预测并输出一份分类结果报告print("评估模型效果...")predictions = model.predict(testX)print(classification_report(testY, predictions, target_names=dataset.target_names))

4.2 图像数据建模

类似的过程对三场景图像数据集构建代码image_classifier.py

# 导入工具库from sklearn.preprocessing import LabelEncoderfrom PIL import Imagefrom imutils import pathsimport numpy as npimport os

其中LabelEncoder是为了将标签从字符串编码为整型,然后其余几项都是处理图像相关。

对于图像数据,如果直接采用原始像素信息输入模型中,大部分的机器学习算法效果都很不理想,所以这里采用特征提取方法,主要是统计图像颜色通道的均值和标准差信息,总共是RGB3个通道,每个通道各计算均值和标准差,然后结合在一起,得到一个六维的特征,函数如下所示:

def extract_color_stats(image):'''将图片分成 RGB 三通道,然后分别计算每个通道的均值和标准差,然后返回:param image::return:'''(R, G, B) = image.split()features = [np.mean(R), np.mean(G), np.mean(B), np.std(R), np.std(G), np.std(B)]return features

然后同样会定义一个models字典,代码一样,这里就不贴出来了,然后图像载入部分的代码如下:

# 加载数据并提取特征print("抽取图像特征中...")imagePaths = paths.list_images(args['dataset'])data = []labels = []# 循环遍历所有的图片数据for imagePath in imagePaths:# 加载图片,然后计算图片的颜色通道统计信息image = Image.open(imagePath)features = extract_color_stats(image)data.append(features)# 保存图片的标签信息label = imagePath.split(os.path.sep)[-2]labels.append(label)# 对标签进行编码,从字符串变为整数类型le = LabelEncoder()labels = le.fit_transform(labels)# 进行训练集和测试集的划分,80%数据作为训练集,其余20%作为测试集trainX, testX, trainY, testY = train_test_split(data, labels, test_size=0.2)

上述代码就完成加载图片的路径信息,然后依次遍历,读取图片,提取特征,提取标签信息,保存特征和标签信息,接着编码标签,然后就是划分训练集和测试集。

接着是相同的训练模型和预测的代码,和前面的分类器一样。完整版代码如下:

# 导入工具库from sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNBfrom sklearn.linear_model import LogisticRegressionfrom sklearn.svm import SVCfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.neural_network import MLPClassifierfrom sklearn.preprocessing import LabelEncoderfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportfrom PIL import Imagefrom imutils import pathsimport numpy as npimport argparseimport os# 抽取图像特征def extract_color_stats(image):'''将图片分成 RGB 三通道,然后分别计算每个通道的均值和标准差,然后返回:param image::return:'''(R, G, B) = image.split()features = [np.mean(R), np.mean(G), np.mean(B), np.std(R), np.std(G), np.std(B)]return features# 设置参数ap = argparse.ArgumentParser()ap.add_argument("-d", "--dataset", type=str, default="3scenes",help="path to directory containing the '3scenes' dataset")ap.add_argument("-m", "--model", type=str, default="knn",help="type of python machine learning model to use")args = vars(ap.parse_args())# 定义一个保存模型的字典,根据 key 来选择加载哪个模型models = {"knn": KNeighborsClassifier(n_neighbors=1),"naive_bayes": GaussianNB(),"logit": LogisticRegression(solver="lbfgs", multi_class="auto"),"svm": SVC(kernel="rbf", gamma="auto"),"decision_tree": DecisionTreeClassifier(),"random_forest": RandomForestClassifier(n_estimators=100),"mlp": MLPClassifier()}# 加载数据并提取特征print("抽取图像特征中...")imagePaths = paths.list_images(args['dataset'])data = []labels = []# 循环遍历所有的图片数据for imagePath in imagePaths:# 加载图片,然后计算图片的颜色通道统计信息image = Image.open(imagePath)features = extract_color_stats(image)data.append(features)# 保存图片的标签信息label = imagePath.split(os.path.sep)[-2]labels.append(label)# 对标签进行编码,从字符串变为整数类型le = LabelEncoder()labels = le.fit_transform(labels)# 进行训练集和测试集的划分,80%数据作为训练集,其余20%作为测试集trainX, testX, trainY, testY = train_test_split(data, labels, random_state=3, test_size=0.2)# print('trainX numbers={}, testX numbers={}'.format(len(trainX), len(testX)))# 训练模型print("[应用 '{}' 模型建模".format(args["model"]))model = models[args["model"]]model.fit(trainX, trainY)# 预测并输出分类结果报告print("模型评估")predictions = model.predict(testX)print(classification_report(testY, predictions, target_names=le.classes_))

完成这两份代码后,我们就可以开始运行下代码,对比不同算法在两个数据集上的性能。

4.3 不同模型建模对比

(1) KNN

K-Nearest Neighbors分类器最简单的分类算法之一。该算法依赖于特征向量之间的距离。简单地说,KNN算法通过在k个最接近的样本中最多的类别来对未知数据点进行分类。关于KNN的详细讲解可以阅读ShowMeAI的文章图解机器学习 | KNN算法及其应用

这里我们先运行下image_classifier.py,调用默认的模型knn,看下KNNiris数据集上的实验结果,如下所示:

$ !python iris_classifier.py --model knn加载数据中...应用 'knn' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 10versicolor 0.900.900.90 10virginica 0.900.900.90 10accuracy 0.93 30macro avg 0.930.930.93 30weighted avg 0.930.930.93 30

其中主要是给出了对每个类别的精确率、召回率、F1以及该类别测试集数量,即分别对应precision、recall、f1-score、support。根据最后一行第一列,可以看到KNN取得93%的准确率。

接着是在三场景图片数据集上的实验结果:

$ !python image_classifier.py --model knn抽取图像特征中...应用 'knn' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.840.680.75 105forest 0.780.770.77 78highway 0.560.780.65 54micro avg 0.730.730.73 237macro avg 0.720.740.72 237weighted avg 0.750.730.73 237

这里KNN取得75%的准确率。

ps:实际上,运行这个算法,不同次数会有不同的结果,其主要原因是因为在划分训练集和测试集的时候,代码没有设置参数random_state,这导致每次运行划分的训练集和测试集的图片都是不同的,所以运行结果也会不相同!

(2) 朴素贝叶斯

接着是朴素贝叶斯算法,关于朴素贝叶斯算法的详细讲解可以阅读ShowMeAI的文章图解机器学习 | 朴素贝叶斯算法详解

分别测试两个数据集,结果如下:

$ !python iris_classifier.py --model naive_bayes加载数据中...应用 'naive_bayes' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 15versicolor 1.000.920.96 12virginica 0.921.000.96 11micro avg 0.970.970.97 38macro avg 0.970.970.97 38weighted avg 0.980.970.97 38

$ !python image_classifier.py --model naive_bayes抽取图像特征中...应用 'naive_bayes' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.690.400.50 88forest 0.680.820.74 84highway 0.610.780.68 65micro avg 0.650.650.65 237macro avg 0.660.670.64 237weighted avg 0.660.650.64 237

同样,朴素贝叶斯在iris上有98%的准确率,但是在图像数据集上仅有66%的准确率。

那么,我们是否可以说明KNN算法比朴素贝叶斯好呢?当然是不可以的,上述结果只能说明在三场景图像数据集上,KNN算法优于朴素贝叶斯算法。

实际上,每种算法都有各自的优缺点和适用场景,不能一概而论地说某种算法任何时候都优于另一种算法,这需要具体问题具体分析。

(3) 逻辑回归

接着是逻辑回归算法,关于逻辑回归算法的详细讲解可以阅读ShowMeAI的文章图解机器学习 | 逻辑回归算法详解

分别测试两个数据集,结果如下:

$ !python iris_classifier.py --model logit加载数据中...应用 'logit' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 15versicolor 1.000.920.96 12virginica 0.921.000.96 11micro avg 0.970.970.97 38macro avg 0.970.970.97 38weighted avg 0.980.970.97 38

$ !python image_classifier.py --model logit抽取图像特征中...应用 'logit' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.670.670.67 92forest 0.790.820.80 82highway 0.610.570.59 63micro avg 0.700.700.70 237macro avg 0.690.690.69 237weighted avg 0.690.700.69 237

同样,逻辑回归在iris上有 98% 的准确率,但是在图像数据集上仅有 69% 的准确率

(4) 支持向量机 SVM

接着是SVM算法,关于SVM算法的详细讲解可以阅读ShowMeAI的文章图解机器学习 | 支持向量机模型详解

分别测试两个数据集,结果如下:

$ !python iris_classifier.py --model svm加载数据中...应用 'svm' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 15versicolor 1.000.920.96 12virginica 0.921.000.96 11micro avg 0.970.970.97 38macro avg 0.970.970.97 38weighted avg 0.980.970.97 38

$ !python image_classifier.py --model svm抽取图像特征中...应用 'svm' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.840.760.80 92forest 0.860.930.89 84highway 0.780.800.79 61micro avg 0.830.830.83 237macro avg 0.830.830.83 237

同样,SVM在iris上有98%的准确率,但是在图像数据集上仅有83%的准确率。

(5) 决策树

接着是决策树算法,关于决策树算法的详细讲解可以阅读ShowMeAI的文章图解机器学习 | 决策树模型详解

分别测试两个数据集,结果如下:

$ !python iris_classifier.py --model decision_tree加载数据中...应用 'decision_tree' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 15versicolor 0.920.920.92 12virginica 0.910.910.91 11micro avg 0.950.950.95 38macro avg 0.940.940.94 38weighted avg 0.950.950.95 38

$ !python image_classifier.py --model decision_tree抽取图像特征中...应用 'decision_tree' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.710.740.72 85forest 0.760.800.78 83highway 0.770.680.72 69micro avg 0.740.740.74 237macro avg 0.750.740.74 237weighted avg 0.740.740.74 237

同样,决策树在iris上有98%的准确率,但是在图像数据集上仅有74%的准确率。

(6) 随机森林

接着是随机森林算法,关于随机森林算法的详细讲解可以阅读ShowMeAI的文章图解机器学习 | 随机森林分类模型详解

分别测试两个数据集,结果如下:

$ !python iris_classifier.py --model random_forest加载数据中...应用 'random_forest' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 15versicolor 1.000.830.91 12virginica 0.851.000.92 11micro avg 0.950.950.95 38macro avg 0.950.940.94 38weighted avg 0.960.950.95 38

$ !python image_classifier.py --model random_forest加载数据中...应用 'random_forest' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.800.830.81 84forest 0.920.840.88 90highway 0.770.810.79 63micro avg 0.830.830.83 237macro avg 0.830.830.83 237weighted avg 0.840.830.83 237

同样,随机森林在iris上有96%的准确率,但是在图像数据集上仅有84%的准确率。

注意了,一般如果决策树算法的效果还不错的话,随机森林算法应该也会取得不错甚至更好的结果,这是因为随机森林实际上就是多棵决策树通过集成学习方法组合在一起进行分类预测。

(7) 多层感知机

最后是多层感知机算法,分别测试两个数据集,结果如下:

$ !python iris_classifier.py --model mlp加载数据中...应用 'mlp' 模型建模...评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 15versicolor 1.000.920.96 12virginica 0.921.000.96 11micro avg 0.970.970.97 38macro avg 0.970.970.97 38weighted avg 0.980.970.97 38

$ !python image_classifier.py --model mlp抽取图像特征中...应用 'mlp' 模型建模...评估模型效果...precision recall f1-score supportcoast 0.720.910.80 86forest 0.920.890.90 79highway 0.790.580.67 72micro avg 0.800.800.80 237macro avg 0.810.790.79 237weighted avg 0.810.800.80 237

同样,多层感知机在iris上有 98% 的准确率,但是在图像数据集上仅有 81% 的准确率.

(8) 神经网络

最后是实现深度学习的算法,也就是nn_iris.pybasic_cnn.py这两份代码。

首先是nn_iris.py的实现,同样首先是导入库和数据的处理:

# 导入工具库from keras.models import Sequentialfrom keras.layers.core import Densefrom keras.optimizers import SGDfrom sklearn.preprocessing import LabelBinarizerfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportfrom sklearn.datasets import load_iris# 载入 Iris 数据集,然后进行训练集和测试集的划分,80%数据作为训练集,其余20%作为测试集print("加载数据中...")dataset = load_iris()(trainX, testX, trainY, testY) = train_test_split(dataset.data,dataset.target, test_size=0.2)# 将标签进行独热向量编码lb = LabelBinarizer()trainY = lb.fit_transform(trainY)testY = lb.transform(testY)

我们采用Keras来实现神经网络,然后这里需要将标签进行one-hot编码,即独热向量编码。

接着就是搭建网络模型的结构和训练、预测代码:

# 利用 Keras 定义网络模型model = Sequential()model.add(Dense(3, input_shape=(4,), activation="sigmoid"))model.add(Dense(3, activation="sigmoid"))model.add(Dense(3, activation="softmax"))# 采用梯度下降训练模型print('训练网络中...')opt = SGD(lr=0.1, momentum=0.9, decay=0.1 / 250)pile(loss='categorical_crossentropy', optimizer=opt, metrics=["accuracy"])H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=250, batch_size=16)# 预测print('评估模型效果')predictions = model.predict(testX, batch_size=16)print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=dataset.target_names))

上述代码构建了3层全连接层的神经网络,前两层采用Sigmoid激活函数,然后最后一层是输出层,所以采用softmax将输出变成概率值。优化算法选择的随机梯度下降SGD,损失函数是categorical_crossentropy,迭代次数是250次,每一批次的数据量batch_size是16。

完整版代码如下:

# 加载工具库from keras.models import Sequentialfrom keras.layers.core import Densefrom keras.optimizers import SGDfrom sklearn.preprocessing import LabelBinarizerfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportfrom sklearn.datasets import load_iris# 载入 Iris 数据集,然后进行训练集和测试集的划分,80%数据作为训练集,其余20%作为测试集print("加载数据中...")dataset = load_iris()(trainX, testX, trainY, testY) = train_test_split(dataset.data,dataset.target, test_size=0.2)# 将标签进行独热向量编码lb = LabelBinarizer()trainY = lb.fit_transform(trainY)testY = lb.transform(testY)# 利用 Keras 定义网络模型model = Sequential()model.add(Dense(3, input_shape=(4,), activation="sigmoid"))model.add(Dense(3, activation="sigmoid"))model.add(Dense(3, activation="softmax"))# 采用梯度下降训练模型print('训练网络中...')opt = SGD(lr=0.1, momentum=0.9, decay=0.1 / 250)pile(loss='categorical_crossentropy', optimizer=opt, metrics=["accuracy"])H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=250, batch_size=16)# 预测print('评估模型效果...')predictions = model.predict(testX, batch_size=16)print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=dataset.target_names))

直接运行命令python nn_iris.py,输出的结果如下:

$ python nn_iris.py Using TensorFlow backend.加载数据中...训练网络中...Train on 112 samples, validate on 38 samplesEpoch 1/250-02-08 10:28:19.104933: I tensorflow/core/platform/:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 AVX512F FMA112/112 [==============================] - 0s 2ms/step - loss: 1.1454 - acc: 0.3214 - val_loss: 1.1867 - val_acc: 0.2368Epoch 2/250112/112 [==============================] - 0s 48us/step - loss: 1.0828 - acc: 0.3929 - val_loss: 1.2132 - val_acc: 0.5000Epoch 3/250112/112 [==============================] - 0s 47us/step - loss: 1.0491 - acc: 0.5268 - val_loss: 1.0593 - val_acc: 0.4737...Epoch 248/250112/112 [==============================] - 0s 46us/step - loss: 0.1319 - acc: 0.9554 - val_loss: 0.0407 - val_acc: 1.0000Epoch 249/250112/112 [==============================] - 0s 46us/step - loss: 0.1024 - acc: 0.9643 - val_loss: 0.1595 - val_acc: 0.8947Epoch 250/250112/112 [==============================] - 0s 47us/step - loss: 0.0795 - acc: 0.9821 - val_loss: 0.0335 - val_acc: 1.0000评估模型效果...precision recall f1-score supportsetosa 1.001.001.00 9versicolor 1.001.001.00 10virginica 1.001.001.00 19avg / total 1.001.001.00 38

这里得到的是100%的准确率。

(9) CNN

最后我们要应用卷积神经网络,我们实现一下basic_cnn.py代码。

同样首先是导入必须的库函数:

# 导入工具库from keras.models import Sequentialfrom keras.layers.convolutional import Conv2Dfrom keras.layers.convolutional import MaxPooling2Dfrom keras.layers.core import Activationfrom keras.layers.core import Flattenfrom keras.layers.core import Densefrom keras.optimizers import Adamfrom sklearn.preprocessing import LabelBinarizerfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportfrom PIL import Imagefrom imutils import pathsimport numpy as npimport argparseimport os# 配置参数ap = argparse.ArgumentParser()ap.add_argument("-d", "--dataset", type=str, default="3scenes",help="path to directory containing the '3scenes' dataset")args = vars(ap.parse_args())

同样是要导入Keras来建立CNN的网络模型,另外因为是处理图像数据,所以PILimutils也是要导入的。

然后是加载数据和划分训练集和测试集,对于加载数据,这里直接采用原始图像像素数据,只需要对图像数据做统一尺寸的调整,这里是统一调整为32×32,并做归一化到[0,1]的范围。

# 加载数据并提取特征print("抽取图像特征中...")imagePaths = paths.list_images(args['dataset'])data = []labels = []# 循环遍历所有的图片数据for imagePath in imagePaths:# 加载图片,然后调整成 32×32 大小,并做归一化到 [0,1]image = Image.open(imagePath)image = np.array(image.resize((32, 32))) / 255.0data.append(image)# 保存图片的标签信息label = imagePath.split(os.path.sep)[-2]labels.append(label)# 对标签编码,从字符串变为整型lb = LabelBinarizer()labels = lb.fit_transform(labels)# 划分训练集和测试集(trainX, testX, trainY, testY) = train_test_split(np.array(data), np.array(labels), test_size=0.25)

接着定义了一个4层的CNN网络结构,包含3层卷积层和最后一层输出层,优化算法采用的是Adam而不是SGD。代码如下所示:

# 定义 CNN 网络模型结构model = Sequential()model.add(Conv2D(8, (3, 3), padding="same", input_shape=(32, 32, 3)))model.add(Activation("relu"))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))model.add(Conv2D(16, (3, 3), padding="same"))model.add(Activation("relu"))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))model.add(Conv2D(32, (3, 3), padding="same"))model.add(Activation("relu"))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))model.add(Flatten())model.add(Dense(3))model.add(Activation("softmax"))# 训练模型print("训练网络中...")opt = Adam(lr=1e-3, decay=1e-3 / 50)pile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])H = model.fit(trainX, trainY, validation_data=(testX, testY),epochs=50, batch_size=32)# 预测print("评估模型效果...")predictions = model.predict(testX, batch_size=32)print(classification_report(testY.argmax(axis=1),predictions.argmax(axis=1), target_names=lb.classes_))

运行命令python basic_cnn.py,输出结果如下:

$ python basic_cnn.py Using TensorFlow backend.加载图像数据...训练网络中...Train on 711 samples, validate on 237 samplesEpoch 1/50711/711 [==============================] - 0s 629us/step - loss: 1.0647 - acc: 0.4726 - val_loss: 0.9920 - val_acc: 0.5359Epoch 2/50711/711 [==============================] - 0s 313us/step - loss: 0.9200 - acc: 0.6188 - val_loss: 0.7778 - val_acc: 0.6624Epoch 3/50711/711 [==============================] - 0s 308us/step - loss: 0.6775 - acc: 0.7229 - val_loss: 0.5310 - val_acc: 0.7553...Epoch 48/50711/711 [==============================] - 0s 307us/step - loss: 0.0627 - acc: 0.9887 - val_loss: 0.2426 - val_acc: 0.9283Epoch 49/50711/711 [==============================] - 0s 310us/step - loss: 0.0608 - acc: 0.9873 - val_loss: 0.2236 - val_acc: 0.9325Epoch 50/50711/711 [==============================] - 0s 307us/step - loss: 0.0587 - acc: 0.9887 - val_loss: 0.2525 - val_acc: 0.9114评估模型效果...precision recall f1-score supportcoast 0.850.960.90 85forest 0.990.940.97 88highway 0.910.800.85 64avg / total 0.920.910.91 237

CNN的准确率是达到92%,它是优于之前的几种机器学习算法的结果。

5.小结

这篇简单的机器学习教程文章中,我们调用现有的库来应用对应的机器学习算法,解决了2个简单的场景问题。通过这份简单的入门教程,希望大家了解到:

(1) 没有任何一种算法是完美的,可以完全适用所有的场景,即便是目前很热门的深度学习方法,也存在它的局限性,所以应该具体问题具体分析!

(2) 经典的5步机器学习操作流程:

问题抽象与理解数据准备与处理(预处理、特征提取、特征工程等)各种机器学习算法实验结果分析与对比模型选择与调优

参考资料

AI建模工具速查 | Scikit-Learn使用指南AI建模工具速查 | Keras使用指南图解机器学习算法 | 从入门到精通系列

ShowMeAI系列教程推荐

图解Python编程:从入门到精通系列教程图解数据分析:从入门到精通系列教程图解AI数学基础:从入门到精通系列教程图解大数据技术:从入门到精通系列教程图解机器学习算法:从入门到精通系列教程机器学习实战:手把手教你玩转机器学习系列

相关文章推荐

Python机器学习算法应用实践SKLearn入门与简单应用案例SKLearn最全应用指南XGBoost建模应用详解LightGBM建模应用详解Python机器学习综合项目-电商销量预估Python机器学习综合项目-电商销量预估<进阶方案>机器学习特征工程最全解读自动化特征工程工具Featuretools应用AutoML自动化机器学习建模

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。