运行 StanfordPOSTagger with NLTK for Chinese 时的意外格式
Unexpected format when running StanfordPOSTagger with NLTK for Chinese
我已经安装了Python 3.6.0、NLTK 3.2.4,并下载了Stanford POS Tagger 3.8.0。
然后我尝试了运行以下脚本:
#!/usr/bin/env python3
from nltk.tag import StanfordPOSTagger
st = StanfordPOSTagger('chinese-distsim.tagger')
print(st.tag('这 是 斯坦福 中文 分词器 测试'.split()))
并且输出格式不正确:
[('', '这#PN'), ('', '是#VC'), ('', '斯坦福#NR'), ('', '中文#NN'), ('', '分词器#NN'), ('', '测试#NN')]
标注器确实完成了它的工作,但是单词和它们的词性不是成对分开的,而是用“#”连接形成单个字符串。这是专门针对中文的格式,还是哪里有问题?
TL;DR
设置不同的 _SEPARATOR
:
from nltk.tag import StanfordPOSTagger
st = StanfordPOSTagger('chinese-distsim.tagger')
st._SEPARATOR = '#'
print(st.tag('这 是 斯坦福 中文 分词器 测试'.split()))
更好的解决方案
稍等片刻,等待 NLTK v3.2.5,届时将有一个非常简单的 Stanford 分词器接口,这些分词器是跨不同语言标准化的。
不会涉及分隔符,因为标签和令牌是通过 json 从 REST 接口传输的 =)
此外,StanfordSegmenter
和 StanfordTokenizer
类 将在 v3.2.5 中弃用,请参阅
- https://github.com/nltk/nltk/pull/1735#issuecomment-306137326
- https://github.com/nltk/nltk/pull/1771
首先升级您的 nltk
版本:
pip install -U nltk
下载并启动 Stanford CoreNLP 服务器:
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
然后在 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')]
我已经安装了Python 3.6.0、NLTK 3.2.4,并下载了Stanford POS Tagger 3.8.0。
然后我尝试了运行以下脚本:
#!/usr/bin/env python3
from nltk.tag import StanfordPOSTagger
st = StanfordPOSTagger('chinese-distsim.tagger')
print(st.tag('这 是 斯坦福 中文 分词器 测试'.split()))
并且输出格式不正确:
[('', '这#PN'), ('', '是#VC'), ('', '斯坦福#NR'), ('', '中文#NN'), ('', '分词器#NN'), ('', '测试#NN')]
标注器确实完成了它的工作,但是单词和它们的词性不是成对分开的,而是用“#”连接形成单个字符串。这是专门针对中文的格式,还是哪里有问题?
TL;DR
设置不同的 _SEPARATOR
:
from nltk.tag import StanfordPOSTagger
st = StanfordPOSTagger('chinese-distsim.tagger')
st._SEPARATOR = '#'
print(st.tag('这 是 斯坦福 中文 分词器 测试'.split()))
更好的解决方案
稍等片刻,等待 NLTK v3.2.5,届时将有一个非常简单的 Stanford 分词器接口,这些分词器是跨不同语言标准化的。
不会涉及分隔符,因为标签和令牌是通过 json 从 REST 接口传输的 =)
此外,StanfordSegmenter
和 StanfordTokenizer
类 将在 v3.2.5 中弃用,请参阅
- https://github.com/nltk/nltk/pull/1735#issuecomment-306137326
- https://github.com/nltk/nltk/pull/1771
首先升级您的 nltk
版本:
pip install -U nltk
下载并启动 Stanford CoreNLP 服务器:
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
然后在 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')]