购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.1 数据集

为了构建我们的情感检测器,我们将使用一篇论文 [3] 中提供的数据集,该论文探讨了英语推文所表示的情感。与大多数情感分析数据集只涉及“正面”和“负面”这两种极性不同的是,这个数据集包含六种基本情感:anger(愤怒)、disgust(厌恶)、fear(恐惧)、joy(喜悦)、sadness(悲伤)和surprise(惊讶)。我们的任务是训练一个模型,将给定推文按其中一种情感进行分类。

2.1.1 初探Hugging Face Datasets库

我们将使用Hugging Face Datasets库从Hugging Face Hub( https://oreil.ly/959YT )下载数据。我们可以使用list_datasets()函数查看Hub上有哪些可用数据集。

我们可以看到每个数据集都有一个名称,因此让我们使用load_dataset()函数加载情感数据集:

emotions对象详情如下:

我们可以看到它类似于Python字典,每个键对应不同的数据集分割。我们可以使用常用的字典语法来访问某个数据集分割:

以上代码返回一个Dataset类的实例。Dataset对象是Hugging Face Datasets库的核心数据结构之一,在本书中我们将探索它的许多特性。首先,它的行为类似于普通的Python数组或列表,因此我们可以查询它的长度:

或者通过索引访问某个样本:

在这里我们可以看到,这行数据将表示成这样一个字典,其中键对应着列名:

值分别是推文和情感。这反映了Hugging Face Datasets库是基于 Apache Arrow https://arrow.apache.org )构建的。Apache Arrow定义了一种类型化的列格式,比原生的Python更有效地利用内存。我们可以通过访问Dataset对象的features属性来查看其背后使用了哪些数据类型。

在本例中,text列的数据类型为字符串,而label列是一个特殊的ClassLabel对象,它包含有关类名称及其映射到整数的信息。我们还可以使用切片查看几行数据:

请注意,这种情况下,字典的值是列表而不是某个元素。我们也可以通过名称获取整个列:

既然我们已经看到如何使用Hugging Face Datasets库加载和检查数据,那么让我们对推文的内容进行一些检查。

如果我的数据集不在Hub上那该怎么办?

在本书的大部分示例中,我们将使用Hugging Face Hub库下载数据集。但在许多情况下,你会发现自己处理的数据要么存储在你的笔记本电脑上,要么存储在你的组织的远程服务器上。Datasets提供了多个加载脚本来处理本地和远程数据集。最常见数据格式的示例参见表2-1。

表2-1:如何加载不同格式的数据集

你可以看到,对于每种数据格式,我们只需要将相关的加载脚本参数和数据文件data_files参数传给load_dataset()函数即可,其中data_files参数指定一个或多个文件的路径或URL。假如情感数据集的源文件实际上托管在Dropbox上,那么可以使用以下代码加载数据集:

如果你想知道为什么在前面的shell命令中会有一个!符号,那是因为我们在Jupyter notebook中运行这些命令。如果你想要在命令行终端下载和解压数据集,则只需删除前缀。现在,我们查看train.txt文件的第一行:

我们可以看到这里没有列标题,每个推文和情感之间用分号分隔。看起来与CSV文件非常相似,因此我们可以使用csv脚本并将data_files参数指向train.txt文件来将数据集加载到本地:

这里我们还指定了分隔符类型(sep参数)和列的名称(names参数)。更简单的方法是将data_files参数直接指向URL:

这个函数会自动下载和缓存数据集。正如你所看到的,load_dataset()函数非常灵活,有很多种用法。所以我们建议查看Datasets文档( https://oreil.ly/Jodu4 )以获得全面的概述。

2.1.2 从Datasets到DataFrame

尽管Hugging Face Datasets库提供了许多底层的功能供我们切分和处理数据,但我们通常将Dataset对象转换为Pandas DataFrame,这样我们就可以使用高级API来进行可视化,这样做将非常方便。Hugging Face Datasets库提供了set_format()方法,该方法允许我们更改数据集的输出格式以进行转换。请注意,它不会改变底层的数据格式(Arrow表),并且你可以随时切换到另一种格式。

你可以看到,列标题被保留,前几行与我们以前查看的数据相匹配。然而,标注(label列)表示为整数,因此我们需要使用int2str()方法在我们的DataFrame中创建一个包含相应标注名称的新列(label name列):

在构建分类器之前,我们仔细研究一下数据集。正如Andrej Karpathy在他著名的博客文章“A Recipe for Training Neural Networks”( https://oreil.ly/bNayo )中所指出的那样,与数据“融为一体”是训练出优秀模型的关键步骤!

2.1.3 查看类分布

对于处理文本分类问题,检查类的样本分布无论何时都是一个好主意。相对于类平衡的数据集来说,一个类分布不平衡的数据集可能需要在训练损失和度量指标方面采取不同的处理方法。

我们可以使用Pandas和Matplotlib快速地可视化类分布:

我们可以看到数据集严重不平衡;joy和sadness类频繁出现,大约是love和surprise类的5~10倍。处理不平衡数据的方法包括:

●随机对少数类进行过采样(oversample)。

●随机对多数类进行欠采样(undersample)。

●收集更多来自未被充分表示的类的标注数据。

为了保持本章简单,我们不使用以上的任何方法,而将使用原始的、不平衡的类。如果你想了解更多关于这些采样技术的内容,我们建议你查看Imbalanced-learn库( https://oreil.ly/5XBhb )。需要注意的是,在将数据集分割成训练/测试集之前不要应用采样方法,否则会在两者之间造成大量泄漏!

现在我们已经查看了这些类,接下来我们看看这些推文本身。

2.1.4 这些推文有多长

Transformer模型的输入序列长度有一个最大限制,称为最大上下文大小(maximum context size)。对于使用DistilBERT的应用程序,最大上下文大小为512个词元,只有几段文本长。正如我们将在2.2节中看到的,词元是指一段文本的原子单元,这里为简单起见我们将词元视为一个单词。我们可以通过查看每个推文中单词的分布来对每种情感的推文长度进行大致估计:

从图中可以看出,对于每种情感,大多数推文长度为15个单词,最长的推文远远低于DistilBERT的最大上下文大小。超过模型上下文大小的文本需要被截断,如果被截断的文本包含关键信息,则可能会导致性能下降。就我们的示例而言,应该不会有这方面的问题。

接下来我们将原始文本转换为Hugging Face Transformers库支持的格式,首先我们需要重置数据集的输出格式,因为我们不再需要DataFrame格式了: P3xb42LCHbgBUZ/o9uL6jxxmR9StDzFUZ4AKTx6Pf9RmvjMAEGDVJMEqxMhhdbuu

点击中间区域
呼出菜单
上一章
目录
下一章
×