4

我正在尝试通过使用以下方法word_tokenize法语文本上使用 NLTK :

txt = ["Le télétravail n'aura pas d'effet sur ma vie"]
print(word_tokenize(txt,language='french'))

它应该打印:

['Le', 'télétravail', 'n'','aura', 'pas', 'd'','effet', 'sur', 'ma', 'vie','.']

但我得到:

['Le', 'télétravail', "n'aura", 'pas', "d'effet", 'sur', 'ma', 'vie','.']

有谁知道为什么在法语中没有正确拆分令牌以及在法语中进行 NLP 时如何克服这个(和其他潜在问题)?

4

3 回答 3

2

我认为没有明确的法语模型word_tokenize(这是用于英语 Penn Treebank 的修改后的树库标记器)。'

该函数在实际单词标记化之前word_tokenize使用该函数执行句子标记化。sent_tokenizein的language参数word_tokenize仅用于该sent_tokenize部分。

或者,您可以使用MosesTokenizer具有某些语言相关正则表达式的 (并且它确实支持法语):

>>> from nltk.tokenize.moses import MosesTokenizer
>>> moses = MosesTokenizer(lang='fr')
>>> sent = u"Le télétravail n'aura pas d'effet sur ma vie"
>>> moses.tokenize(sent)
[u'Le', u't\xe9l\xe9travail', u'n'', u'aura', u'pas', u'd'', u'effet', u'sur', u'ma', u'vie']

如果你不喜欢 Moses 转义特殊的 XML 字符,你可以这样做:

>>> moses.tokenize(sent, escape=False)
[u'Le', u't\xe9l\xe9travail', u"n'", u'aura', u'pas', u"d'", u'effet', u'sur', u'ma', u'vie']

解释为什么拆分n'd'在法语 NLP 中很有用。

从语言上讲,将n'and分开d'确实是有意义的,因为它们是具有自己的句法和语义属性但与根/主机绑定的小团。

在法语中,ne ... pas将是表示否定的不连续成分,negoing to的小结性质n'是因为以下单词中的元音开始ne,因此将 then'与 the分开aura确实更容易识别ne ... pas

在 的情况下d',它与以下单词中元音开头的语音动机相同,从de effet->开始d'effet

于 2017-11-20T01:48:56.497 回答
2

查看来源word_tokenize显示,该language参数仅用于确定如何将输入拆分为句子。对于单词级别的标记化,使用 a (稍作修改)TreebankWordTokenizer,它最适合英语输入和类似don't的缩略词。来自nltk/tokenize/__init__.py

_treebank_word_tokenizer = TreebankWordTokenizer()
# ... some modifications done
def word_tokenize(text, language='english', preserve_line=False):
    # ...
    sentences = [text] if preserve_line else sent_tokenize(text, language)
    return [token for sent in sentences
            for token in _treebank_word_tokenizer.tokenize(sent)]

要获得所需的输出,您可能需要考虑使用不同的标记器RegexpTokenizer,如下所示:

txt = "Le télétravail n'aura pas d'effet sur ma vie"
pattern = r"[dnl]['´`]|\w+|\$[\d\.]+|\S+"
tokenizer = RegexpTokenizer(pattern)
tokenizer.tokenize(txt)
# ['Le', 'télétravail', "n'", 'aura', 'pas', "d'", 'effet', 'sur', 'ma', 'vie']

我的法语知识有限,这只能解决上述问题。对于其他情况,您将不得不调整模式。您还可以查看实现TreebankWordTokenizer更复杂解决方案的想法。另请记住,如果需要,您需要事先拆分句子。

于 2017-11-19T15:20:33.010 回答
0

在这里我们看到法语省略的处理并不令人满意。因此,我建议通过 NLTKword_tokenize输出中的省略后处理来纠正问题。

compiled_pattern = re.compile(r"([a-zA-ZÀ-Ÿ]+['’])([a-zA-ZÀ-Ÿ]*)")

def split_in_words_fr(text):
    tokens = word_tokenize(text)
    new_tokens = []
    for token in tokens:
        search_results = re.findall(r"['’]",token)
        if search_results and len(search_results) == 1:
            new_tokens.extend(re.split(compiled_pattern,token)[1:3])
        else:
            new_tokens.append(token)
    return new_tokens

然后:

print(split_in_words_fr("Le télétravail n'aura pas d'effet sur ma vie"))

给出:

['Le', 'télétravail', "n'", 'aura', 'pas', "d'", 'effet', 'sur', 'ma', 'vie']

一个不太令人满意的解决方案是使用 wordpunct_tokenize 拆分每个非字母字符。

from nltk.tokenize import wordpunct_tokenize

print(wordpunct_tokenize("Le télétravail n'aura pas d'effet sur ma vie"))

这使

['Le', 'télétravail', 'n', "'", 'aura', 'pas', 'd', "'", 'effet', 'sur', 'ma', 'vie']
于 2020-05-04T06:49:24.553 回答