如何使用 NLP 预处理用于文本分类的大数据集

数据挖掘 Python nlp 文本分类
2021-09-27 11:33:06

TL;博士

我以前从来没有做过nlp,我觉得我做得不好。我想知道我是不是真的从一开始就做不好,还是还有希望解决后面提到的那些问题。

一些基本信息

我正在尝试为大学任务进行一些二进制文本分类,但我在分类方面遇到了困难,因为 NLP 的预处理并不是最好的。

首先,重要的是要注意在设计事物时我需要考虑效率,因为我正在处理加载在内存中的非常大的数据集(>1M 文本)。

该数据集包含与新文章相关的数据,带有title, summary, content, published_date, section, tags, authors...

此外,值得一提的是,由于这项任务是学习过程的一部分,我正在尝试自己创建所有内容,而不是使用外部库(仅用于无聊或复杂的任务)

程序

NLP预处理的基本过程是:

  1. 特征提取 -> str 变量title,summarycontent属性连接在同一个字符串中
  2. 词形还原 -> 与输入相同的 str 但具有词形还原的单词
  3. 停用词过滤
  4. 语料库生成 ->dict以词形还原词作为键并将它们插入字典中的索引作为值的对象。

在使用所有这些样本生成语料库之后,我们终于可以安全地对它们进行矢量化(这与上面的过程基本相同,但没有构建语料库的步骤)。

正如您可能猜到的那样,我并没有严格遵循基本bag of words (BOW)思想,因为我需要减少内存消耗,因此在尝试使用DecisionTreeClassifiersci-kit 等 AI 算法时会引发两个问题。

问题

到目前为止,我观察到的一些问题是:

  • 从这些文本生成的向量需要具有相同的维度Does padding them with zeroes make any sense?
  • 用于预测的向量也需要与训练中的向量具有相同的维度
  • 在预测阶段,那些没有添加到语料库中的词被忽略
  • 此外,矢量化没有多大意义,因为它们很相似,而且即使它们都包含相同的信息[0, 1, 2, 3, 4, 1, 2, 3, 5, 1, 2, 3],这也是不同的[1, 0, 2, 3, 4, 1, 2, 3, 5, 1, 2, 3]
1个回答

让我首先阐明用文本数据进行分类的一般原则。请注意,我假设您使用的是“传统”方法(如决策树),而不是深度学习 (DL) 方法。

正如您正确理解的那样,每个单独的文本文档(实例)都必须表示为特征向量,每个特征代表一个单词。但是有一个关键的约束:对于所有文档,每个特征/单词必须在向量中的相同位置这是因为这就是学习算法如何找到跨实例的模式。例如,决策树算法可能会创建一个对应于“文档是否包含单词'cat'?”的条件,并且模型正确检测是否满足此条件的唯一方法是是否一致表示单词'cat'在索引一世 在每个实例的向量中。

作为记录,这与单热编码非常相似:变量“单词”有许多可能的值,它们中的每一个都必须表示为不同的特征。

这意味着您不能像当前那样为每个实例使用不同的索引表示。

从这些文本生成的向量需要具有相同的维度 用零填充它们是否有意义?

正如您现在可能理解的那样,不,它没有。

用于预测的向量也需要与训练中的向量具有相同的维度

是的,它们不仅必须具有相同的维度,而且还必须以相同的顺序具有完全相同的特征/单词。

在预测阶段,那些没有添加到语料库中的词被忽略

绝对地,必须忽略任何超出词汇表的单词(未出现在训练数据中的单词)。无论如何它都将无法使用,因为模型不知道它与哪个类相关。

此外,矢量化没有多大意义,因为它们就像 [0, 1, 2, 3, 4, 1, 2, 3, 5, 1, 2, 3] 并且这与 [1, 0, 2 , 3, 4, 1, 2, 3, 5, 1, 2, 3] 即使它们都包含相同的信息

确实,您有正确的直觉,那里存在问题,与上述问题相同。

现在你当然要回到解决在内存中拟合这些非常长的向量的问题。所以理论上向量长度是完整的词汇量大小,但实际上有几个很好的理由不保留所有单词,更准确地说是删除最不常见的单词:

  • 模型很难使用最不常用的词。一个只出现一次的词(顺便说一句,它被称为hapax legomenon,以防你想用花哨的术语给人们留下深刻印象;))根本没有帮助,因为它可能会偶然出现在特定的类中。更糟糕的是,它可能会导致过度拟合:如果模型创建一个规则,将包含该单词的任何文档分类为 C 类(因为在训练中,包含该单词的文档 100% 都是 C 类,即使只有一个),结果是如果该词没有特定于 C 类的内容,则模型会出错。从统计学上讲,从小样本中得出结论是非常冒险的,因此最不常见的词通常是“不良特征”。
  • 你会喜欢这个的:自然语言文本遵循Zipf 分布这意味着在任何文本中都有少量的不同单词经常出现,而大量不同的单词很少出现。因此,删除最不常见的单词会很快减少词汇表的大小(因为有很多罕见的单词),但它不会删除大部分文本(因为最频繁出现的是频繁出现的单词)。例如,删除只出现一次的单词可能会使词汇量减少一半,而文本大小仅减少 3%。

所以实际上你需要做的是:

  1. 计算训练数据中所有文档中每个不同单词的词频(在训练数据中)。请注意,您只需要dict在内存中存储一​​个,因此它是可行的。按频率对其进行排序并将其存储在文件中的某个位置。
  2. 确定最低频率 ñ 为了通过删除所有频率低于的单词来获得减少的词汇量 ñ.
  3. 仅使用此预定义词汇表(当然还有固定索引)将每个文档表示为一个向量。现在您可以训练模型并在测试集上对其进行评估。

请注意,您可以尝试不同的值 ñ(2,3,4,...) 并观察哪一个性能最好(由于上述原因,它不一定是最低的)。如果你这样做,你通常应该使用不同于最终测试集的验证集,因为在测试集上多次评估就像“作弊”(这被称为数据泄漏)。