NLP:有哪些流行的多词标记化包?

数据挖掘 nlp nltk 标记化
2021-09-22 09:40:02

我打算标记一些职位描述文本。我已经尝试使用空格作为分隔符的标准标记化。但是我注意到有一些多词表达式被空格分割,这很可能会导致后续处理的准确性问题。所以我想在这些文本中获得所有最有趣/信息最丰富的搭配。

无论特定的编程语言如何,是否有任何用于进行多词标记化的好包?例如,“他学习信息技术”===>“他”“学习”“信息技术”。

我注意到 NLTK (Python) 有一些相关的功能。

这两者有什么区别?

nltk.tokenize.mwe 模块中的 MWETokenizer 类似乎朝着我的目标努力。但是 MWETokenizer 似乎需要我使用它的构造方法和 .add_mwe 方法来添加多词表达式。有没有办法使用外部多词表达词典来实现这一点?如果是这样,是否有任何多词词典?

谢谢!

4个回答

多字标记器“nltk.tokenize.mwe”基本上根据我从 API 文档中理解的词典,将已经划分为标记的字符串合并。

您可以做的一件事是使用相关的词性 (PoS) 标记对所有单词进行标记和标记,然后根据 PoS 标记定义正则表达式以提取有趣的关键短语。

例如,改编自NLTK 书第 7 章和这篇 文的示例:

def extract_phrases(my_tree, phrase):
   my_phrases = []
   if my_tree.label() == phrase:
      my_phrases.append(my_tree.copy(True))

   for child in my_tree:
       if type(child) is nltk.Tree:
            list_of_phrases = extract_phrases(child, phrase)
            if len(list_of_phrases) > 0:
                my_phrases.extend(list_of_phrases)

    return my_phrases



def main():
    sentences = ["The little yellow dog barked at the cat",
                 "He studies Information Technology"]

    grammar = "NP: {<DT>?<JJ>*<NN>|<NNP>*}"
    cp = nltk.RegexpParser(grammar)

    for x in sentences:
        sentence = pos_tag(tokenize.word_tokenize(x))
        tree = cp.parse(sentence)
        print "\nNoun phrases:"
        list_of_noun_phrases = extract_phrases(tree, 'NP')
        for phrase in list_of_noun_phrases:
            print phrase, "_".join([x[0] for x in phrase.leaves()])

您基于 PoS 标记上的正则表达式定义了一个语法:

grammar = "NP: {<DT>?<JJ>*<NN>|<NNP>*}"
cp = nltk.RegexpParser(grammar)

然后将其应用于标记化和标记的句子,生成树:

sentence = pos_tag(tokenize.word_tokenize(x))
tree = cp.parse(sentence)

然后您使用extract_phrases(my_tree, phrase)递归解析树并提取标记为 NP 的子树。上面的示例将提取以下名词短语:

Noun phrases:
(NP The/DT little/JJ yellow/JJ dog/NN) The_little_yellow_dog
(NP the/DT cat/NN) the_cat

Noun phrases:
(NP Information/NNP Technology/NNP) Information_Technology

Burton DeWilde 有一篇很棒的博客文章,介绍了更多提取有趣关键词的方法:自动关键词提取简介

对于您的问题,我认为 gensim 可能非常有用,可以使用 Gensim 库实现的是短语检测。它类似于 n-gram,但不是通过滑动窗口来获取所有 n-gram,而是检测常用短语并将它们粘在一起。它在统计上遍历文本语料库并识别常见的并排出现的单词。
以下是它计算最合适的多词标记的方式。 在此处输入图像描述

以下是使用它的代码。它计算两个单词标记。

from gensim.models.phrases import Phrases, Phraser

tokenized_train = [t.split() for t in x_train]
phrases = Phrases(tokenized_train)
bigram = Phraser(phrases)

这就是你将如何使用它

在此处输入图像描述

注意连接的单词“new_york”,因为在语料库中,“new”和“york”两个词结合在一起的统计证据很重要。

此外,您可以为此使用 n-gram,而不仅仅是 bi-gram。这是详细解释它的文章。

即使您对多个单词感兴趣,也不应更改标记化过程。毕竟,单词仍然是基本的令牌。你应该怎么做才能找到一种将正确的单词组合成术语的方法。

一个简单的方法是寻找词项的概率高于独立标记的概率的词项。例如 P("Whitehouse") > P("White")*P("House") 如果您有来自领域的术语数据集,则可以推断出需要提升、出现次数和术语分类的适当值. 如果您没有这样的域,则要求至少出现 10 次,并且提升至少 2 次(通常它要高得多,因为每个令牌概率很低)会很好地工作。

在您的情况下,还可以通过组合与您的域相关的上下文来提取术语(例如,“学习 X”、“实践 Y”)。

同样,您可以为此构建复杂而优雅的模型,但通常,在上下文指示符之后寻找几个下一个单词将非常有益。

斯坦福 CoreNLP的这种扩展以捕获多词表达式(MWE)对我的一项任务来说就像一个魅力。对于 Python 用户,准备好编写一些连接器代码或破解 Java 代码。