用机器学习进行多输出分类
多输出分类是机器学习的一种类型,它可以同时预测多个输出。在多输出分类中,模型在做出任何预测后都会给出两个或多个输出。在其他类型的分类中,模型通常只预测一个输出。
多输出分类模型的一个例子是,一个模型同时预测水果的type 和color 。type of fruit 可以是,橙色、芒果和菠萝。color 可以是,红色、绿色、黄色和橙色。多输出分类解决了这个问题,并给出了两个预测结果。
在本教程中,我们将使用Netflix数据集建立一个多输出文本分类模型。该模型将把输入的文本分类为TV Show 或Movie 。这将是第一个输出。该模型还将把评级分类为。TV-MA,TV-14,TV-PG,R,PG-13 和TV-Y 。评级将是第二个输出。我们将使用Scikit-LearnMultiOutputClassifier 算法来建立这个模型。
前提条件
为了理解本教程中的概念,读者应该。
- 理解[Python编程]
- 能够建立[机器学习模型。]
- 理解[自然语言处理]
- 知道如何使用[Scikit-learn]训练模型
- 使用[谷歌Colab笔记本]来运行本教程中的Python代码。
Netflix数据集
我们将使用Netflix的数据集来建立我们的模型。下面的图片将显示我们的数据集是如何结构的。

从上面的图片来看,我们的数据集有四列。title,description,type, 和rating 。title 列将是输入列,而type 和rating 将是输出列。我们现在需要在我们的机器上加载这个数据集。
加载数据集
有各种探索性数据分析(EDA)包,可以加载我们的数据集。让我们用下面的代码来导入它们。
import pandas as pd
import numpy as np
我们将使用Pandas来加载数据集。我们将使用Numpy来对我们的数据集进行计算操作。它也能很好地处理数组。
现在让我们加载你从上面的链接中下载的Netflix数据集。
df = pd.read_csv("netflix_titles_dataset.csv")
为了检查我们的数据集是否被成功加载,运行代码。
df.head()
这个命令将输出我们数据集的结构,它显示了我们数据集上的所有列。它的结构应该与你下载的数据集相同。输出结果如下所示。

现在我们已经成功加载了我们的数据集,让我们检查一下目标/输出列的分布。
输出列的分布
从我们的数据集中,我们有两个输出列:type 和rating 。列的分布是指在整个数据集中每一列的值计数。我们将从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-13 和TV-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 ,我们将使用它作为我们模型的输入。标签是type 和rating ,是我们模型的输出。我们有两个标签,因为我们处理的是一个多输出的分类问题。
下一步是使用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 。它还将使用LogisticRegression 和MultiOutputClassifier 算法自动完成模型训练的过程。
我们将导入Pipeline 包来实现这个管道过程。
导入管道
要导入Pipeline ,使用以下代码。
from sklearn.pipeline import Pipeline
为了使用这个Pipeline 包建立模型,我们需要初始化所有参与建立模型的进程。在我们的例子中,我们有两个进程。
第一个过程是CountVectorizer :将原始文本转换为数字向量。第二个进程在训练模型时使用LogisticRegression 和MultiOutputClassifier 算法。
让我们来初始化这两个进程。
初始化进程
这些过程通常是按顺序进行的。一个进程的输出被用作下一个进程的输入,如下面的代码所示。
pipe_lr = Pipeline(steps=[('cv',CountVectorizer()),
('lr_multi',MultiOutputClassifier(LogisticRegression()))])
现在我们已经初始化了这些过程,让我们把管道装入我们的训练数据集。这将使模型能够从数据集中学习。为了适应管道,使用下面的代码。
pipe_lr.fit(x_train,y_train)
在这个阶段,两个进程将自动运行,并产生一个训练好的模型,如下图所示。

我们可以使用下面的代码来计算这个模型的准确度分数。
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]
模型将使用这个输入文本来进行预测。该模型应将输入的文本分类为Movie 或TV 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.25554517 的TV Show 高。这就是为什么模型将该文本归类为Movie 。
在接下来的预测中,TV-MA 的概率比其他等级的0.46916205 要高。这就是为什么该模型将该评级归类为TV-MA 。使用这些预测概率,我们可以看到,我们的模型可以做出正确的预测。
总结
在本教程中,我们已经学会了如何建立一个多输出的分类模型。我们首先清理了Netflix的数据集,以确保我们在使用前正确格式化它。然后我们使用干净的数据集来建立多输出文本分类模型。
我们使用LogisticRegression 和MultiOutputClassifier 算法来训练该模型。我们使用管道包实现了所有的机器学习过程。它加快了进程,使我们的工作更容易。
最后,我们用我们的模型进行预测,训练后的模型可以做出正确的预测。