代码之家  ›  专栏  ›  技术社区  ›  yhylord

使用中文NLTK运行StanfordPOSTagger时出现意外格式

  •  2
  • yhylord  · 技术社区  · 9 年前

    我已经安装了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')]
    

    标记器完成了它的工作,但是单词和它们的词性不是成对分开的,而是由一个“#”连接起来形成单个字符串。这是专为中文设计的格式吗?还是有什么地方不对?

    1 回复  |  直到 9 年前
        1
  •  1
  •   alvas    9 年前

    TL;博士

    _SEPARATOR :

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

    更好的解决方案

    请稍等,等待NLTK v3.2.5版本,其中将有一个非常简单的斯坦福标记器接口,该接口跨不同语言标准化。

    由于标记和令牌是通过json从REST接口传输的,因此不涉及分隔符 =)

    StanfordSegmenter StanfordTokenizer 在v3.2.5中,类将被弃用,请参阅

    nltk 版本:

    pip install -U nltk
    

    下载并启动斯坦福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
    

    >>> 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')]