如何用机器学习进行多输出分类

1,002 阅读9分钟

用机器学习进行多输出分类

多输出分类是机器学习的一种类型,它可以同时预测多个输出。在多输出分类中,模型在做出任何预测后都会给出两个或多个输出。在其他类型的分类中,模型通常只预测一个输出。

多输出分类模型的一个例子是,一个模型同时预测水果的typecolortype of fruit 可以是,橙色、芒果和菠萝。color 可以是,红色、绿色、黄色和橙色。多输出分类解决了这个问题,并给出了两个预测结果。

在本教程中,我们将使用Netflix数据集建立一个多输出文本分类模型。该模型将把输入的文本分类为TV ShowMovie 。这将是第一个输出。该模型还将把评级分类为。TV-MA,TV-14,TV-PG,R,PG-13TV-Y 。评级将是第二个输出。我们将使用Scikit-LearnMultiOutputClassifier 算法来建立这个模型。

前提条件

为了理解本教程中的概念,读者应该。

  • 理解[Python编程]
  • 能够建立[机器学习模型。]
  • 理解[自然语言处理]
  • 知道如何使用[Scikit-learn]训练模型
  • 使用[谷歌Colab笔记本]来运行本教程中的Python代码。

Netflix数据集

我们将使用Netflix的数据集来建立我们的模型。下面的图片将显示我们的数据集是如何结构的。

Dataset image

从上面的图片来看,我们的数据集有四列。title,description,type, 和ratingtitle 列将是输入列,而typerating 将是输出列。我们现在需要在我们的机器上加载这个数据集。

加载数据集

有各种探索性数据分析(EDA)包,可以加载我们的数据集。让我们用下面的代码来导入它们。

import pandas as pd
import numpy as np

我们将使用Pandas来加载数据集。我们将使用Numpy来对我们的数据集进行计算操作。它也能很好地处理数组。

现在让我们加载你从上面的链接中下载的Netflix数据集。

df = pd.read_csv("netflix_titles_dataset.csv")

为了检查我们的数据集是否被成功加载,运行代码。

df.head()

这个命令将输出我们数据集的结构,它显示了我们数据集上的所有列。它的结构应该与你下载的数据集相同。输出结果如下所示。

Loaded dataset

现在我们已经成功加载了我们的数据集,让我们检查一下目标/输出列的分布。

输出列的分布

从我们的数据集中,我们有两个输出列:typerating 。列的分布是指在整个数据集中每一列的值计数。我们将从type 列开始。

type

df['type'].value_counts()

输出结果如下所示。

Movie      4788
TV Show    2143
Name: type, dtype: int64

在上面的输出中,我们有4788个movie 数据样本和2143个TV Show 数据样本。

rating

要获得rating 列的值计数,使用以下代码。

df['rating'].value_counts()

输出结果如下图所示。

TV-MA    2863
TV-14    1931
TV-PG     806
R         665
PG-13     386
TV-Y      280
Name: rating, dtype: int64

上面的输出显示了我们数据集中所有评分的分布。我们有七个评级。TV-MA,TV-14,TV-PG,R,PG-13TV-Y

在建立我们的模型之前,我们还需要清理我们的数据集。数据集清理涉及到正确格式化我们的数据集。

文本清理

对于文本清理,我们将把所有的文本数据转换成小写字母,并删除停顿词。我们将使用NeatText Python软件包来执行这一过程。我们将使用以下代码安装Neattext。

!pip install neattext

让我们导入我们将用于文本清理的Neattext函数。

import neattext.functions as nfx

要将文本数据转换为小写字母,请运行这个命令。

df['title'] = df['title'].nfx.lower()

让我们从我们的测试数据集中删除停止词。停止词是任何语言中最常见的词汇。在训练过程中,它们在模型中的权重很小。

删除止损词就可以删除权重小的词。这使得模型能够专注于在训练过程中会产生更大影响的词。

要删除停顿词,请运行这段代码。

df['title'] = df['title'].apply(nfx.remove_stopwords)

现在,我们已经删除了停顿词并正确地格式化了我们的数据集,让我们导入所有我们将用来建立模型的包。

导入重要包

要导入所有重要的包,请运行这段代码。

from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.multioutput import MultiOutputClassifier

让我们来解释一下这些我们已经导入的包。

LogisticRegression它是用来训练模型的算法。

CountVectorizer因为我们要处理的是文本,所以我们需要将输入的文本转换成数字向量。机器学习模型并不理解原始文本。转换后的数字向量是原始文本的代表。

CountVectorizer 是最常用的Python包,用于执行这一过程。

train_test_split它是用于数据集分割的Python包。在机器学习中,将一个数据集分成两组是非常必要的。一个集子用于训练,另一个集子用于测试。

accuracy_score用来计算训练后模型的准确度分数。

MultiOutputClassifier由于我们处理的是一个多输出的分类问题,我们需要一个更具体的算法。MultiOutputClassifier 是最常用的Scikit-learn算法,用于建立这个模型。

我们现在需要为我们的模型指定特征和标签。

添加特征和标签

特征和标签在任何机器学习标签中都是必不可少的。特征代表模型在训练期间作为输入使用的所有列。标签代表输出或目标列,是模型想要预测的。我们使用下面的代码来添加。

Xfeatures = df['title']
ylabels = df[['type','rating']]

从这段代码中,我们的特征是title ,我们将使用它作为我们模型的输入。标签是typerating ,是我们模型的输出。我们有两个标签,因为我们处理的是一个多输出的分类问题。

下一步是使用train_test_split 方法来分割我们的数据集。

数据集的拆分

要把数据集拆成两个,请使用这段代码。

x_train,x_test,y_train,y_test = train_test_split(Xfeatures,ylabels,test_size=0.3,random_state=7)

在上面的代码中,我们使用了一个test_size=0.3 。它将分割我们的数据集,使数据集的70% 用于训练,30% 用于测试。我们已经分割了我们的数据集,现在我们准备建立模型。

为了建立这个模型,我们将使用机器学习管道包来加快建立模型的过程。它将通过自动化建立模型的所有过程来加速这一过程。

机器学习管道将自动完成CountVectorizer 。它还将使用LogisticRegressionMultiOutputClassifier 算法自动完成模型训练的过程。

我们将导入Pipeline 包来实现这个管道过程。

导入管道

要导入Pipeline ,使用以下代码。

from sklearn.pipeline import Pipeline

为了使用这个Pipeline 包建立模型,我们需要初始化所有参与建立模型的进程。在我们的例子中,我们有两个进程。

第一个过程是CountVectorizer :将原始文本转换为数字向量。第二个进程在训练模型时使用LogisticRegressionMultiOutputClassifier 算法。

让我们来初始化这两个进程。

初始化进程

这些过程通常是按顺序进行的。一个进程的输出被用作下一个进程的输入,如下面的代码所示。

pipe_lr = Pipeline(steps=[('cv',CountVectorizer()),
                          ('lr_multi',MultiOutputClassifier(LogisticRegression()))])

现在我们已经初始化了这些过程,让我们把管道装入我们的训练数据集。这将使模型能够从数据集中学习。为了适应管道,使用下面的代码。

pipe_lr.fit(x_train,y_train)

在这个阶段,两个进程将自动运行,并产生一个训练好的模型,如下图所示。

Training process

我们可以使用下面的代码来计算这个模型的准确度分数。

pipe_lr.score(x_test,y_test)

准确率得分如下图所示。

0.8969221004536385

我们的模型的准确度得分是0.896922 。这表示89.6922% 。这是一个很好的准确性分数,我们可以使用这个训练好的模型来进行预测。

进行预测

为了进行预测,我们需要提取一个输入文本的样本。要提取一个样本文本,运行这个代码。

print(x_test.iloc[0])

这个样本文本的输出是the midnight sky 。让我们把这个文本保存在一个变量中。

pred1 = x_test.iloc[0]

模型将使用这个输入文本来进行预测。该模型应将输入的文本分类为MovieTV Show ,并提供其评级。

为了做出这个预测,运行这段代码。

pipe_lr.predict([pred1])

预测输出如下所示。

array([['Movie', 'TV-MA']], dtype=object)

从上面的输出来看,该模型已经产生了两个预测输出。它将输入的文本分类为Movie ,评级为TV-MA 。因此,我们已经成功建立了我们的多输出文本分类模型。

我们还可以计算出这些输出的预测概率。这使我们能够知道为什么该模型会做出这些预测。

预测概率

要计算概率,请使用以下代码。

print(pipe_lr.classes_)
pipe_lr.predict_proba([pred1])

输出显示如下。

[array(['Movie', 'TV Show'], dtype=object), array(['PG-13', 'R', 'TV-14', 'TV-MA', 'TV-PG', 'TV-Y'], dtype=object)]
[array([[0.74445483, 0.25554517]]),
 array([[0.12310188, 0.07038494, 0.21476461, 0.46916205, 0.10270243,
         0.01988409]])]

0.74445483 从上面的输出中,我们可以看到Movie 的概率比0.25554517TV Show 高。这就是为什么模型将该文本归类为Movie

在接下来的预测中,TV-MA 的概率比其他等级的0.46916205 要高。这就是为什么该模型将该评级归类为TV-MA 。使用这些预测概率,我们可以看到,我们的模型可以做出正确的预测。

总结

在本教程中,我们已经学会了如何建立一个多输出的分类模型。我们首先清理了Netflix的数据集,以确保我们在使用前正确格式化它。然后我们使用干净的数据集来建立多输出文本分类模型。

我们使用LogisticRegressionMultiOutputClassifier 算法来训练该模型。我们使用管道包实现了所有的机器学习过程。它加快了进程,使我们的工作更容易。

最后,我们用我们的模型进行预测,训练后的模型可以做出正确的预测。