将未知单词解析为已知单词的有效方法?

时间:2012-06-13 18:48:16

标签: python language-agnostic machine-learning nlp oov

我正在设计一个文本处理程序,它将从一个长的逐项文本文档中生成一个关键字列表,并组合相似词义的词条。有指标,但我有一个新的问题,处理我正在使用的字典中没有的单词。

我目前正在使用nltk和python,但我在这里的问题更具抽象性。给定一个不在字典中的单词,将它解析为字典内的单词的有效方法是什么?我目前唯一的解决方案是通过字典中的单词并从输入的单词中选择最短的Levenshtein距离(编辑距离)。

显然这是一个非常缓慢且不切实际的方法,我实际上并不需要字典中的绝对最佳匹配,只要它是一个包含的单词并且非常接近。在解决方案中,效率对我来说更重要,但也需要基本的准确度。

关于如何将一些未知单词解析为字典中已知单词的任何想法?

4 个答案:

答案 0 :(得分:1)

您似乎需要使用拼写纠正器来匹配词典中的单词。 下面的代码可以直接从Peter Norvig撰写的博客http://norvig.com/spell-correct.html中获取,

import re, collections

def words(text): return re.findall('[a-z]+', text.lower()) 

def train(features):
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1
    return model

NWORDS = train(words(file('big.txt').read()))

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits1(word):
    splits     = [(word[:i], word[i:]) for i in range(len(word) + 1)]
    deletes    = [a + b[1:] for a, b in splits if b]
    transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
    replaces   = [a + c + b[1:] for a, b in splits for c in alphabet if b]
    inserts    = [a + c + b     for a, b in splits for c in alphabet]
    return set(deletes + transposes + replaces + inserts)

def known_edits2(word):
    return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

def known(words): return set(w for w in words if w in NWORDS)

def correct(word):
    candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
    return max(candidates, key=NWORDS.get)

big.txt是包含已知单词的词典。

答案 1 :(得分:0)

你的任务听起来真的只是非单词拼写纠正,所以一个相对直接的解决方案是使用现有的拼写检查器,如aspell和自定义词典。

快速而肮脏的方法是使用像metaphone这样的语音映射(这是aspell使用的算法之一)。对于从您的词典派生的每个可能的代码,选择代表性单词(例如,组中最常用的单词)作为校正建议,并针对未找到匹配的情况选择默认校正。但是使用aspell你可能会得到更好的结果。

如果您确实想要计算编辑距离,可以通过在尝试中存储字典和可能的编辑操作来相对快速地完成,请参阅Brill and Moore (2000)。如果你有一个体面大小的拼写错误及其修正语料库并且可以实现Brill和Moore的整个方法,你可能会相当多地击败aspell,但它听起来像aspell(或任何拼写检查器,可以让你创建自己的字典)足以完成你的任务。

答案 2 :(得分:0)

希望这个答案不是太模糊:

1)听起来你可能需要首先查看你的标记化和短语分块层。在将它们提交给任何模糊拼写检查之前,您应该丢弃符号短语块。

2)之后我仍然会建议编辑距离以找出任何“拼写错误”的令牌的替代品,但这可能会返回一个同样接近的可能列表。

3)当你有可能的列表时,你可以使用共生算法从这个列表中选择最喜欢的候选者。我只有一些可以提供帮助的软件的例子(http://www.linguatools.de/disco/disco_en.html#was)。您可以提交一个单词,这将返回该单词的不同共现单词。然后,您可以将此列表与“拼写错误”字词的上下文进行比较,并从所有可能的编辑距离字词中选择重叠最多的字词。

答案 3 :(得分:0)

我认为没有理由使用Levenshtein距离在意义中找到类似的单词。 LD看表格(你想把“公共汽车”映射到“卡车”而不是“灌木”)。

正确的解决方案取决于您接下来要做什么。

除非你真的需要那些未知单词中的信息,否则我只需将它们全部映射到一个通用的“UNKNOWN_WORD”项。

显然,您可以根据其上下文和其他功能对未知单词进行聚类(例如,它们是以大写字母开头)。对于上下文聚类:因为你对意义感兴趣,我会使用一个更大的窗口来表示这些单词(比如+/- 50个单词),并且可能使用一个简单的单词包模型。然后,您只需使用一些距离度量(例如余弦)找到一个已知单词,其空间中的向量最接近未知单词。如果您需要更多相关信息,请与我们联系。