使用 Python 对单词进行词干提取

2024 年 8 月 29 日 | 阅读 6 分钟

在接下来的教程中,我们将了解使用 Python 编程语言中的 NLTK (Natural Language Toolkit) 包进行词干提取的过程。

词干提取简介

词干提取是自然语言处理流水线过程中的重要组成部分。词干提取是指生成词根/基本词的形态学修改的过程。词干提取程序通常被认为是词干提取算法或词干提取器。一个词干提取算法可以将“retrieves”、“retrieved”、“retrieval”等词缩减为词根“retrieve”,将“Choco”、“Chocolatey”、“Chocolates”缩减为词干“chocolate”。词干提取器的输入是分词后的词。那么,这些分词后的词从哪里来呢?分词包括将文档分解成独立的词。要了解更多关于分词的信息,可以参考“Python 中的分词”教程。

现在让我们来理解词干提取中的错误。

理解词干提取中的错误

词干提取中的错误主要分为两类:

  1. 过度词干提取 (Over-stemming): 当两个源自不同词根的词被提取到同一个词根时,就会出现此错误。过度词干提取也可视为假阳性。
  2. 不足词干提取 (Under-stemming): 当两个源自同一词根但词根不同的词被提取到同一个词根时,就会出现此错误。不足词干提取也可视为假阴性。

现在让我们看看词干提取的一些应用。

理解词干提取的应用

词干提取的一些应用如下:

  1. 我们可以在信息检索系统中使用词干提取作为搜索引擎。
  2. 我们还可以使用词干提取来确定领域分析中的领域词汇。
  3. 一个有趣的 M.M. 是,谷歌在 2003 年采用了“词干提取”这个词。以前搜索“fish”不会返回“fishes”或“fishing”。

理解词干提取算法

一些词干提取算法如下:

  1. Porter 词干提取算法
  2. Lovins 词干提取器
  3. Dawson 词干提取器
  4. Krovetz 词干提取器
  5. Xerox 词干提取器
  6. N-Gram 词干提取器
  7. Snowball 词干提取器
  8. Lancaster 词干提取器

现在,让我们简要讨论这些词干提取算法。

Porter 词干提取算法

Porter 词干提取算法是 1980 年提出的著名词干提取方法之一。该概念基于这样一个原理:英语中的后缀由更小的简单后缀组合而成。该词干提取器以其速度和简洁性而闻名。Porter 词干提取器的主要应用涉及数据挖掘和数据恢复。然而,这些应用仅限于英语单词。此外,一组词干被映射到同一个词干,并且输出的词干不一定是具有意义的单词。这些算法相当冗长,并且被称为最古老的词干提取器。

假设 EED -> EE 意思是“如果单词至少有一个元音和一个辅音加上 EED 结尾,则将结尾更改为 EE”,例如“agreed”变成“agree”。

优点:与其他词干提取器相比,它能产生更好的输出,错误率更低。

局限性:产生的形态学修改不总是实际单词。

Lovins 词干提取器

Lovins 于 1968 年提出,它从一个单词中删除最长的后缀,然后记录该单词以将此词干转换为有效单词。

例如,sitting -> sitt -> sit

优点:Lovins 词干提取器速度快,并且可以处理不规则的复数。例如,“teeth”和“tooth”等。

局限性:该过程耗时,并且经常无法从词干生成单词。

Dawson 词干提取器

它是 Lovins 词干提取器的扩展,其中后缀按长度和最后一个字母的倒序累积索引。

优点:Dawson 词干提取器的执行速度快,并且覆盖更多后缀。

局限性:实现非常复杂。

Krovetz 词干提取器

Krovetz 词干提取器由 Robert Krovetz 于 1993 年提出。该词干提取算法遵循以下一些步骤:

  1. 将单词的复数形式转换为单数形式。
  2. 将单词的过去式转换为现在式,并删除后缀“ing”。

例如,“children”->“child”

优点:Krovetz 词干提取器轻量级,我们可以将其用作其他词干提取器的预词干提取器。

局限性:在处理大型文档时,此词干提取算法效率不高。

Xerox 词干提取器

Xerox 词干提取器能够处理大量数据并生成有效单词。然而,由于其对词典的依赖性使其具有语言依赖性,过度词干提取的比例很高。因此,此词干提取算法的主要限制是它是语言特定的。

例如

children -> child

understood -> understand

whom -> who

best -> good

N-Gram 词干提取器

N-Gram 是从单词中提取的 n 个连续字符的集合,其中相似的单词通常具有高比例的 n-gram。

例如,对于 n = 2 的“INTRODUCTIONS”变成:*I, IN, NT, TR, RO, OD, DU, UC, CT, TI, IO, ON, NS, S*

优点:此词干提取算法基于字符串比较,并且具有语言依赖性。

局限性:它需要空间来创建和索引 n-gram,这在时间效率上不高。

Snowball 词干提取器

与 Porter 词干提取器不同,Snowball 词干提取器也可以映射非英语单词。由于此词干提取算法支持多种语言,因此我们可以称 Snowball 词干提取器为多语言词干提取器。Snowball 词干提取器也从 NLTK 包中导入。该算法基于一种名为“Snowball”的编程语言,该语言处理小的字符串,并且是最广泛使用的词干提取器。该词干提取算法比 Porter 词干提取器更具侵略性,也被称为 Porter2 词干提取器。由于与 Porter 词干提取器相比包含的改进,Snowball 词干提取器具有很高的计算速度。

Lancaster 词干提取器

Lancaster 词干提取器比其他两种算法更具侵略性和动态性。该词干提取算法速度很快;然而,在处理小单词时会产生混淆。然而,它们不如 Snowball 词干提取器高效。Lancaster 词干提取器将规则外部保存,并基本利用迭代算法。

现在,让我们看看在 Python 编程语言中使用 **NLTK** 包实现词干提取。

Python 中的词干提取实现

让我们看下面的例子,演示使用 Python 中的 **NLTK** 包实现词干提取。

示例

输出

consult: consult
consultant: consult
consulting: consult
consultantative: consult
consultants: consult
consulting: consult

说明

在上面的代码片段中,我们导入了所需的模块。然后,我们创建了 **NLTK** 包的 **PorterStemmer** 类的对象。然后,我们创建了一个需要进行词干提取的单词列表。最后,我们使用 **for** 循环遍历列表中的单词,并使用 **stem()** 函数对它们进行词干提取。

正如我们所观察到的,我们在上面的示例中没有使用 **word_tokenize()** 函数。让我们看另一个演示词干提取以及 **word_tokenize()** 函数的例子。

示例

输出

People  :  peopl
comes  :  come
to  :  to
consultants  :  consult
office  :  offic
to  :  to
consult  :  consult
the  :  the
consultant  :  consult

说明

在上面的代码片段中,我们导入了所需的模块并创建了 **PorterStemmer** 类的对象。然后,我们定义了一个需要进行词干提取的字符串。然后,我们使用 **word_tokenize()** 函数来分词。最后,我们使用 **for** 循环遍历单词列表,并使用 **stem()** 函数对它们进行词干提取。