关于机器学习:机器学习实战-Python机器学习算法应用实践

4次阅读

共计 19818 个字符,预计需要花费 50 分钟才能阅读完成。

作者:韩信子 @ShowMeAI
教程地址:http://www.showmeai.tech/tutorials/41
本文地址:http://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 Setosa
  • Iris Versicolor
  • Iris 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 KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.datasets import load_iris
import 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 LabelEncoder
from PIL import Image
from imutils import paths
import numpy as np
import os

其中 LabelEncoder 是为了将标签从字符串编码为整型,而后其余几项都是解决图像相干。

对于图像数据,如果间接采纳原始像素信息输出模型中,大部分的机器学习算法成果都很不现实,所以这里采纳特征提取办法,次要是统计图像色彩通道的均值和标准差信息,总共是RGB 3 个通道,每个通道各计算均值和标准差,而后联合在一起,失去一个六维的特色,函数如下所示:

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 KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from PIL import Image
from imutils import paths
import numpy as np
import argparse
import 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   support

      setosa       1.00      1.00      1.00        10
  versicolor       0.90      0.90      0.90        10
   virginica       0.90      0.90      0.90        10

    accuracy                           0.93        30
   macro avg       0.93      0.93      0.93        30
weighted avg       0.93      0.93      0.93        30

其中次要是给出了对每个类别的准确率、召回率、F1 以及该类别测试集数量,即别离对应 precision、recall、f1-score、support。依据最初一行第一列,能够看到 KNN 获得 93% 的准确率。

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

$ !python image_classifier.py --model knn
抽取图像特色中...
利用 'knn' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.84      0.68      0.75       105
      forest       0.78      0.77      0.77        78
     highway       0.56      0.78      0.65        54

   micro avg       0.73      0.73      0.73       237
   macro avg       0.72      0.74      0.72       237
weighted avg       0.75      0.73      0.73       237

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

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

(2) 奢侈贝叶斯

接着是奢侈贝叶斯算法,对于奢侈贝叶斯算法的具体解说能够浏览 ShowMeAI 的文章 图解机器学习 | 奢侈贝叶斯算法详解

别离测试两个数据集,后果如下:

$ !python iris_classifier.py --model naive_bayes
加载数据中...
利用 'naive_bayes' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       1.00      0.92      0.96        12
   virginica       0.92      1.00      0.96        11

   micro avg       0.97      0.97      0.97        38
   macro avg       0.97      0.97      0.97        38
weighted avg       0.98      0.97      0.97        38
$ !python image_classifier.py --model naive_bayes
抽取图像特色中...
利用 'naive_bayes' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.69      0.40      0.50        88
      forest       0.68      0.82      0.74        84
     highway       0.61      0.78      0.68        65

   micro avg       0.65      0.65      0.65       237
   macro avg       0.66      0.67      0.64       237
weighted avg       0.66      0.65      0.64       237

同样,奢侈贝叶斯在 iris 上有 98% 的准确率,然而在图像数据集上仅有 66% 的准确率。

那么,咱们是否能够阐明 KNN 算法比奢侈贝叶斯好呢?当然是不能够的,上述后果只能阐明在三场景图像数据集上,KNN 算法优于奢侈贝叶斯算法。
实际上,每种算法都有各自的优缺点和实用场景,不能一概而论地说某种算法任何时候都优于另一种算法,这须要具体问题具体分析。

(3) 逻辑回归

接着是逻辑回归算法,对于逻辑回归算法的具体解说能够浏览 ShowMeAI 的文章 图解机器学习 | 逻辑回归算法详解

别离测试两个数据集,后果如下:

$ !python iris_classifier.py --model logit
加载数据中...
利用 'logit' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       1.00      0.92      0.96        12
   virginica       0.92      1.00      0.96        11

   micro avg       0.97      0.97      0.97        38
   macro avg       0.97      0.97      0.97        38
weighted avg       0.98      0.97      0.97        38
$ !python image_classifier.py --model logit
抽取图像特色中...
利用 'logit' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.67      0.67      0.67        92
      forest       0.79      0.82      0.80        82
     highway       0.61      0.57      0.59        63

   micro avg       0.70      0.70      0.70       237
   macro avg       0.69      0.69      0.69       237
weighted avg       0.69      0.70      0.69       237

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

(4) 反对向量机 SVM

接着是 SVM 算法,对于 SVM 算法的具体解说能够浏览 ShowMeAI 的文章 图解机器学习 | 反对向量机模型详解

别离测试两个数据集,后果如下:

$ !python iris_classifier.py --model svm
加载数据中...
利用 'svm' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       1.00      0.92      0.96        12
   virginica       0.92      1.00      0.96        11

   micro avg       0.97      0.97      0.97        38
   macro avg       0.97      0.97      0.97        38
weighted avg       0.98      0.97      0.97        38
$ !python image_classifier.py --model svm
抽取图像特色中...
利用 'svm' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.84      0.76      0.80        92
      forest       0.86      0.93      0.89        84
     highway       0.78      0.80      0.79        61

   micro avg       0.83      0.83      0.83       237
   macro avg       0.83      0.83      0.83       237

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

(5) 决策树

接着是决策树算法,对于决策树算法的具体解说能够浏览 ShowMeAI 的文章 图解机器学习 | 决策树模型详解

别离测试两个数据集,后果如下:

$ !python iris_classifier.py --model decision_tree
加载数据中...
利用 'decision_tree' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       0.92      0.92      0.92        12
   virginica       0.91      0.91      0.91        11

   micro avg       0.95      0.95      0.95        38
   macro avg       0.94      0.94      0.94        38
weighted avg       0.95      0.95      0.95        38
$ !python image_classifier.py --model decision_tree
抽取图像特色中...
利用 'decision_tree' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.71      0.74      0.72        85
      forest       0.76      0.80      0.78        83
     highway       0.77      0.68      0.72        69

   micro avg       0.74      0.74      0.74       237
   macro avg       0.75      0.74      0.74       237
weighted avg       0.74      0.74      0.74       237

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

(6) 随机森林

接着是随机森林算法,对于随机森林算法的具体解说能够浏览 ShowMeAI 的文章 图解机器学习 | 随机森林分类模型详解

别离测试两个数据集,后果如下:

$ !python iris_classifier.py --model random_forest
加载数据中...
利用 'random_forest' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       1.00      0.83      0.91        12
   virginica       0.85      1.00      0.92        11

   micro avg       0.95      0.95      0.95        38
   macro avg       0.95      0.94      0.94        38
weighted avg       0.96      0.95      0.95        38
$ !python image_classifier.py --model random_forest
加载数据中...
利用 'random_forest' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.80      0.83      0.81        84
      forest       0.92      0.84      0.88        90
     highway       0.77      0.81      0.79        63

   micro avg       0.83      0.83      0.83       237
   macro avg       0.83      0.83      0.83       237
weighted avg       0.84      0.83      0.83       237

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

留神了,个别如果决策树算法的成果还不错的话,随机森林算法应该也会获得不错甚至更好的后果,这是因为随机森林实际上就是多棵决策树通过集成学习办法组合在一起进行分类预测。

(7) 多层感知机

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

$ !python iris_classifier.py --model mlp
加载数据中...
利用 'mlp' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       1.00      0.92      0.96        12
   virginica       0.92      1.00      0.96        11

   micro avg       0.97      0.97      0.97        38
   macro avg       0.97      0.97      0.97        38
weighted avg       0.98      0.97      0.97        38
$ !python image_classifier.py --model mlp
抽取图像特色中...
利用 'mlp' 模型建模...
评估模型成果...
              precision    recall  f1-score   support

       coast       0.72      0.91      0.80        86
      forest       0.92      0.89      0.90        79
     highway       0.79      0.58      0.67        72

   micro avg       0.80      0.80      0.80       237
   macro avg       0.81      0.79      0.79       237
weighted avg       0.81      0.80      0.80       237

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

(8) 神经网络

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

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

# 导入工具库
from keras.models import Sequential
from keras.layers.core import Dense
from keras.optimizers import SGD
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from 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)
model.compile(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 Sequential
from keras.layers.core import Dense
from keras.optimizers import SGD
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from 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)
model.compile(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 samples
Epoch 1/250
2022-02-08 10:28:19.104933: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 AVX512F FMA
112/112 [==============================] - 0s 2ms/step - loss: 1.1454 - acc: 0.3214 - val_loss: 1.1867 - val_acc: 0.2368
Epoch 2/250
112/112 [==============================] - 0s 48us/step - loss: 1.0828 - acc: 0.3929 - val_loss: 1.2132 - val_acc: 0.5000
Epoch 3/250
112/112 [==============================] - 0s 47us/step - loss: 1.0491 - acc: 0.5268 - val_loss: 1.0593 - val_acc: 0.4737
...
Epoch 248/250
112/112 [==============================] - 0s 46us/step - loss: 0.1319 - acc: 0.9554 - val_loss: 0.0407 - val_acc: 1.0000
Epoch 249/250
112/112 [==============================] - 0s 46us/step - loss: 0.1024 - acc: 0.9643 - val_loss: 0.1595 - val_acc: 0.8947
Epoch 250/250
112/112 [==============================] - 0s 47us/step - loss: 0.0795 - acc: 0.9821 - val_loss: 0.0335 - val_acc: 1.0000
评估模型成果...
             precision    recall  f1-score   support

     setosa       1.00      1.00      1.00         9
 versicolor       1.00      1.00      1.00        10
  virginica       1.00      1.00      1.00        19

avg / total       1.00      1.00      1.00        38

这里失去的是 100% 的准确率。

(9) CNN

最初咱们要利用卷积神经网络,咱们实现一下 basic_cnn.py 代码。

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

# 导入工具库
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dense
from keras.optimizers import Adam
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from PIL import Image
from imutils import paths
import numpy as np
import argparse
import 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.0
    data.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)
model.compile(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 samples
Epoch 1/50
711/711 [==============================] - 0s 629us/step - loss: 1.0647 - acc: 0.4726 - val_loss: 0.9920 - val_acc: 0.5359
Epoch 2/50
711/711 [==============================] - 0s 313us/step - loss: 0.9200 - acc: 0.6188 - val_loss: 0.7778 - val_acc: 0.6624
Epoch 3/50
711/711 [==============================] - 0s 308us/step - loss: 0.6775 - acc: 0.7229 - val_loss: 0.5310 - val_acc: 0.7553
...
Epoch 48/50
711/711 [==============================] - 0s 307us/step - loss: 0.0627 - acc: 0.9887 - val_loss: 0.2426 - val_acc: 0.9283
Epoch 49/50
711/711 [==============================] - 0s 310us/step - loss: 0.0608 - acc: 0.9873 - val_loss: 0.2236 - val_acc: 0.9325
Epoch 50/50
711/711 [==============================] - 0s 307us/step - loss: 0.0587 - acc: 0.9887 - val_loss: 0.2525 - val_acc: 0.9114
评估模型成果...
             precision    recall  f1-score   support

      coast       0.85      0.96      0.90        85
     forest       0.99      0.94      0.97        88
    highway       0.91      0.80      0.85        64

avg / total       0.92      0.91      0.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 自动化机器学习建模

正文完
 0