2017-08-07 2 views
2

J'ai installé Python 3.6.0, NLTK 3.2.4 et téléchargé Stanford POS Tagger 3.8.0.Format inattendu lors de l'exécution de StanfordPOSTagger avec NLTK pour le chinois

Alors j'ai essayé d'exécuter le script suivant:

#!/usr/bin/env python3 

from nltk.tag import StanfordPOSTagger 


st = StanfordPOSTagger('chinese-distsim.tagger') 
print(st.tag('这 是 斯坦福 中文 分词器 测试'.split())) 

et la sortie est dans un format inattendu:

[('', '这#PN'), ('', '是#VC'), ('', '斯坦福#NR'), ('', '中文#NN'), ('', '分词器#NN'), ('', '测试#NN')] 

Le tagueur fait faire son travail, mais les mots et leurs parties du discours ne sont pas séparés en tant que paire, mais joints par un '#' pour former des chaînes uniques. Est-ce le format spécialement pour le chinois, ou est-ce qu'il y a quelque chose qui ne va pas?

Répondre

1

TL; DR

Définir un autre _SEPARATOR:

from nltk.tag import StanfordPOSTagger 

st = StanfordPOSTagger('chinese-distsim.tagger') 
st._SEPARATOR = '#' 
print(st.tag('这 是 斯坦福 中文 分词器 测试'.split())) 

meilleure solution

Tenir pendant un certain temps, attendez NLTK v3.2.5 où il y aura une très interface simple aux tokenizers de Stanford qui sont standardisés dans différentes langues.

Il n'y aura pas delimiter impliqué depuis les balises et les jetons sont transférés par un JSON à partir d'une interface REST =)

En outre, les classes StanfordSegmenter et StanfordTokenizer seront dépréciés en v3.2.5, voir

Première mise à jour de votre nltk Version:

Téléchargez et démarrez le serveur CoreNLP Stanford:

wget http://nlp.stanford.edu/software/stanford-corenlp-full-2016-10-31.zip 
unzip stanford-corenlp-full-2016-10-31.zip && cd stanford-corenlp-full-2016-10-31 
wget http://nlp.stanford.edu/software/stanford-chinese-corenlp-2016-10-31-models.jar 
wget https://raw.githubusercontent.com/stanfordnlp/CoreNLP/master/src/edu/stanford/nlp/pipeline/StanfordCoreNLP-chinese.properties 

java -Xmx4g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer \ 
-serverProperties StanfordCoreNLP-chinese.properties \ 
-preload tokenize,ssplit,pos,lemma,ner,parse \ 
-status_port 9001 -port 9001 -timeout 15000 

Puis, en NLTK v3.2.5:

>>> from nltk.tag.stanford import CoreNLPPOSTagger, CoreNLPNERTagger 
>>> from nltk.tokenize.stanford import CoreNLPTokenizer 
>>> stpos, stner = CoreNLPPOSTagger('http://localhost:9001'), CoreNLPNERTagger('http://localhost:9001') 
>>> sttok = CoreNLPTokenizer('http://localhost:9001') 

>>> sttok.tokenize(u'我家没有电脑。') 
['我家', '没有', '电脑', '。'] 

# Without segmentation (input to`raw_string_parse()` is a list of single char strings) 
>>> stpos.tag(u'我家没有电脑。') 
[('我', 'PN'), ('家', 'NN'), ('没', 'AD'), ('有', 'VV'), ('电', 'NN'), ('脑', 'NN'), ('。', 'PU')] 
# With segmentation 
>>> stpos.tag(sttok.tokenize(u'我家没有电脑。')) 
[('我家', 'NN'), ('没有', 'VE'), ('电脑', 'NN'), ('。', 'PU')] 

# Without segmentation (input to`raw_string_parse()` is a list of single char strings) 
>>> stner.tag(u'奥巴马与迈克尔·杰克逊一起去杂货店购物。') 
[('奥', 'GPE'), ('巴', 'GPE'), ('马', 'GPE'), ('与', 'O'), ('迈', 'O'), ('克', 'PERSON'), ('尔', 'PERSON'), ('·', 'O'), ('杰', 'O'), ('克', 'O'), ('逊', 'O'), ('一', 'NUMBER'), ('起', 'O'), ('去', 'O'), ('杂', 'O'), ('货', 'O'), ('店', 'O'), ('购', 'O'), ('物', 'O'), ('。', 'O')] 
# With segmentation 
>>> stner.tag(sttok.tokenize(u'奥巴马与迈克尔·杰克逊一起去杂货店购物。')) 
[('奥巴马', 'PERSON'), ('与', 'O'), ('迈克尔·杰克逊', 'PERSON'), ('一起', 'O'), ('去', 'O'), ('杂货店', 'O'), ('购物', 'O'), ('。', 'O')] 
+0

OK il fonctionne maintenant, merci. Mais pourquoi cela n'est-il pas mentionné dans la documentation? Modifier une variable en commençant par un trait de soulignement semble plutôt hacky. – yhylord

+0

En fait, le 'StanfordPOSTagger' sera obsolète dans la prochaine version NLTK, s'il vous plaît utiliser le nouveau' CoreNLPPOSTagger', voir https://github.com/nltk/nltk/pull/1735 – alvas

+0

Spécifiquement pour les chinois https://github.com/nltk/nltk/pull/1735 # issuecomment-306137326 – alvas