NLP记录

Edit

Overview

最近有一个项目想做chat bot,也就是在IM app上自动回答问题的机器人。要回答问题,就要对问题有所了解,于是最近看了一些NLP (Natural Language Process)方面的资料。没有过多的涉及基础理论以及模型方面的知识。因为是做项目,更多的是希望能从工程方面直接进行应用。本文主要涉及SyntaxNet和NLTK。前者是Google于2016年开源的NLP项目,其包含了基本模型以及基于TensorFlow的实现。而且其基于若干训练资料,已经有一个pre-trained English model。可以直接被加以利用。

SyntaxNet

安装

一些参考网页

安装完成后,运行一个demo程序如下:

echo 'Bob brought the pizza to Alice.' | syntaxnet/demo.sh

结果是一个树状结构

Input: Bob brought the pizza to Alice .
Parse:
brought VBD ROOT
+-- Bob NNP nsubj
+-- pizza NN dobj
| +-- the DT det
+-- to IN prep
| +-- Alice NNP pobj
+-- . . punct

SyntaxNet自带的pre-trained English parser叫Parsey McParseface。我们可以用这个parser来分析语句。根据How to Install and Use SyntaxNet and Parsey McParseface中所述,Parsey McParseface输出实为CoNLL table。这个table的格式在models/syntaxnet/syntaxnet/text_formats.cc,如下:

 50 // CoNLL document format reader for dependency annotated corpora.
51 // The expected format is described e.g. at http://ilk.uvt.nl/conll/#dataformat
52 //
53 // Data should adhere to the following rules:
54 // - Data files contain sentences separated by a blank line.
55 // - A sentence consists of one or tokens, each one starting on a new line.
56 // - A token consists of ten fields described in the table below.
57 // - Fields are separated by a single tab character.
58 // - All data files will contains these ten fields, although only the ID
59 // column is required to contain non-dummy (i.e. non-underscore) values.
60 // Data files should be UTF-8 encoded (Unicode).
61 //
62 // Fields:
63 // 1 ID: Token counter, starting at 1 for each new sentence and increasing
64 // by 1 for every new token.
65 // 2 FORM: Word form or punctuation symbol.
66 // 3 LEMMA: Lemma or stem.
67 // 4 CPOSTAG: Coarse-grained part-of-speech tag or category.
68 // 5 POSTAG: Fine-grained part-of-speech tag. Note that the same POS tag
69 // cannot appear with multiple coarse-grained POS tags.
70 // 6 FEATS: Unordered set of syntactic and/or morphological features.
71 // 7 HEAD: Head of the current token, which is either a value of ID or '0'.
72 // 8 DEPREL: Dependency relation to the HEAD.
73 // 9 PHEAD: Projective head of current token.
74 // 10 PDEPREL: Dependency relation to the PHEAD.

直接使用CoNLL table更易于被代码解析。如果需要CoNLL table输出,需要我们修改demo.sh。直接来个例子:

INFO:tensorflow:Processed 1 documents
1 What _ PRON WP _ 0 ROOT _ _
2 is _ VERB VBZ _ 1 cop _ _
3 a _ DET DT _ 5 det _ _
4 control _ NOUN NN _ 5 nn _ _
5 panel _ NOUN NN _ 1 nsubj _ _

这是对What is a control panel的输出。下图源于Inside Google SyntaxNet

CoNLL table中的所有tag缩写的含义在这里Universal Dependency Relations

针对CPOSTAG & POSTAG,可参考

NLTK

NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, wrappers for industrial-strength NLP libraries, and an active discussion forum.

我的想法是可以用NLTK来对SyntaxNet的输出做进一步Stemming/Lemmarization处理。

NLTK vs. spaCy

Stemming vs. Lemmatization

这两个词总是一起出现,作用很相像。区别是:

Lemmatisation is closely related to stemming. The difference is that a stemmer operates on a single word without knowledge of the context, and therefore cannot discriminate between words which have different meanings depending on part of speech. However, stemmers are typically easier to implement and run faster, and the reduced accuracy may not matter for some applications.

In computational linguistics, lemmatisation is the algorithmic process of determining the lemma for a given word. Since the process may involve complex tasks such as understanding context and determining the part of speech of a word in a sentence (requiring, for example, knowledge of the grammar of a language) it can be a hard task to implement a lemmatiser for a new language.

简而言之,就是Lemmarization是包含有上下文含义的,而Stemming只是对单个单词进行映射。

NLTK支持多种Stemmer,包括但不限于 Porter stemmer, Lancaster Stemmer, Snowball Stemmer。

>>> from nltk.stem import SnowballStemmer
>>> snowball_stemmer = SnowballStemmer(“english”)
>>> snowball_stemmer.stem(‘maximum’)
u’maximum’
>>> snowball_stemmer.stem(‘presumably’)
u’presum’
>>> snowball_stemmer.stem(‘multiply’)
u’multipli’

NLTK中的Lemarize:

>>> from nltk.stem import WordNetLemmatizer
>>> wordnet_lemmatizer = WordNetLemmatizer()
>>> wordnet_lemmatizer.lemmatize(‘dogs’)
u’dog’
>>> wordnet_lemmatizer.lemmatize(‘churches’)
u’church’
>>> wordnet_lemmatizer.lemmatize(‘is’, pos=’v’)
u’be’
>>> wordnet_lemmatizer.lemmatize(‘are’, pos=’v’)
u’be’
>>>
  • pos = Part Of Speech
%23NLP%u8BB0%u5F55%0A@%28myblog%29%5Bnlp%5D%0A%0A%5BTOC%5D%0A%0A%23%23Overview%0A%u6700%u8FD1%u6709%u4E00%u4E2A%u9879%u76EE%u60F3%u505Achat%20bot%uFF0C%u4E5F%u5C31%u662F%u5728IM%20app%u4E0A%u81EA%u52A8%u56DE%u7B54%u95EE%u9898%u7684%u673A%u5668%u4EBA%u3002%u8981%u56DE%u7B54%u95EE%u9898%uFF0C%u5C31%u8981%u5BF9%u95EE%u9898%u6709%u6240%u4E86%u89E3%uFF0C%u4E8E%u662F%u6700%u8FD1%u770B%u4E86%u4E00%u4E9BNLP%20%28Natural%20Language%20Process%29%u65B9%u9762%u7684%u8D44%u6599%u3002%u6CA1%u6709%u8FC7%u591A%u7684%u6D89%u53CA%u57FA%u7840%u7406%u8BBA%u4EE5%u53CA%u6A21%u578B%u65B9%u9762%u7684%u77E5%u8BC6%u3002%u56E0%u4E3A%u662F%u505A%u9879%u76EE%uFF0C%u66F4%u591A%u7684%u662F%u5E0C%u671B%u80FD%u4ECE%u5DE5%u7A0B%u65B9%u9762%u76F4%u63A5%u8FDB%u884C%u5E94%u7528%u3002%u672C%u6587%u4E3B%u8981%u6D89%u53CA%5BSyntaxNet%5D%28https%3A//github.com/tensorflow/models/tree/master/syntaxnet%29%u548CNLTK%u3002%u524D%u8005%u662FGoogle%u4E8E2016%u5E74%u5F00%u6E90%u7684NLP%u9879%u76EE%uFF0C%u5176%u5305%u542B%u4E86%u57FA%u672C%u6A21%u578B%u4EE5%u53CA%u57FA%u4E8ETensorFlow%u7684%u5B9E%u73B0%u3002%u800C%u4E14%u5176%u57FA%u4E8E%u82E5%u5E72%u8BAD%u7EC3%u8D44%u6599%uFF0C%u5DF2%u7ECF%u6709%u4E00%u4E2Apre-trained%20English%20model%u3002%u53EF%u4EE5%u76F4%u63A5%u88AB%u52A0%u4EE5%u5229%u7528%u3002%0A%0A%23%23%23SyntaxNet%0A%23%23%23%23%u5B89%u88C5%0A%u4E00%u4E9B%u53C2%u8003%u7F51%u9875%0A-%20%5BNLP%u521D%u7EA7%u9009%u624Bubuntu%20%u4E0B%u5B89%u88C5google%20SyntaxNet%5D%28%5D%28http%3A//blog.csdn.net/u012507864/article/details/51478060%29%29%0A-%20%5BHow%20to%20Install%20and%20Use%20SyntaxNet%20and%20Parsey%20McParseface%5D%28http%3A//www.whycouch.com/2016/07/how-to-install-and-use-syntaxnet-and.html%29%0A-%20%5BSyntaxNet%20Tutorial%5D%28https%3A//github.com/tensorflow/models/blob/master/syntaxnet/g3doc/syntaxnet-tutorial.md%29%0A-%20%5BSyntaxNet%3A%20Understanding%20the%20Parser%5D%28http%3A//jduelfer.github.io/syntaxnet%2C/tensorflow/2016/08/20/understanding-the-parser.html%29%0A%0A%u5B89%u88C5%u5B8C%u6210%u540E%uFF0C%u8FD0%u884C%u4E00%u4E2Ademo%u7A0B%u5E8F%u5982%u4E0B%uFF1A%0A%60%60%60%0Aecho%20%27Bob%20brought%20the%20pizza%20to%20Alice.%27%20%7C%20syntaxnet/demo.sh%0A%60%60%60%0A%u7ED3%u679C%u662F%u4E00%u4E2A%u6811%u72B6%u7ED3%u6784%0A%60%60%60%0AInput%3A%20Bob%20brought%20the%20pizza%20to%20Alice%20.%0AParse%3A%0Abrought%20VBD%20ROOT%0A%20+--%20Bob%20NNP%20nsubj%0A%20+--%20pizza%20NN%20dobj%0A%20%7C%20%20%20+--%20the%20DT%20det%0A%20+--%20to%20IN%20prep%0A%20%7C%20%20%20+--%20Alice%20NNP%20pobj%0A%20+--%20.%20.%20punct%0A%60%60%60%0ASyntaxNet%u81EA%u5E26%u7684pre-trained%20English%20parser%u53EBParsey%20McParseface%u3002%u6211%u4EEC%u53EF%u4EE5%u7528%u8FD9%u4E2Aparser%u6765%u5206%u6790%u8BED%u53E5%u3002%u6839%u636E%5BHow%20to%20Install%20and%20Use%20SyntaxNet%20and%20Parsey%20McParseface%5D%28http%3A//www.whycouch.com/2016/07/how-to-install-and-use-syntaxnet-and.html%29%u4E2D%u6240%u8FF0%uFF0CParsey%20McParseface%u8F93%u51FA%u5B9E%u4E3ACoNLL%20table%u3002%u8FD9%u4E2Atable%u7684%u683C%u5F0F%u5728%60models/syntaxnet/syntaxnet/text_formats.cc%60%uFF0C%u5982%u4E0B%uFF1A%0A%60%60%60%0A%2050%20//%20CoNLL%20document%20format%20reader%20for%20dependency%20annotated%20corpora.%0A%2051%20//%20The%20expected%20format%20is%20described%20e.g.%20at%20http%3A//ilk.uvt.nl/conll/%23dataformat%0A%2052%20//%0A%2053%20//%20Data%20should%20adhere%20to%20the%20following%20rules%3A%0A%2054%20//%20%20%20-%20Data%20files%20contain%20sentences%20separated%20by%20a%20blank%20line.%0A%2055%20//%20%20%20-%20A%20sentence%20consists%20of%20one%20or%20tokens%2C%20each%20one%20starting%20on%20a%20new%20line.%0A%2056%20//%20%20%20-%20A%20token%20consists%20of%20ten%20fields%20described%20in%20the%20table%20below.%0A%2057%20//%20%20%20-%20Fields%20are%20separated%20by%20a%20single%20tab%20character.%0A%2058%20//%20%20%20-%20All%20data%20files%20will%20contains%20these%20ten%20fields%2C%20although%20only%20the%20ID%0A%2059%20//%20%20%20%20%20column%20is%20required%20to%20contain%20non-dummy%20%28i.e.%20non-underscore%29%20values.%0A%2060%20//%20Data%20files%20should%20be%20UTF-8%20encoded%20%28Unicode%29.%0A%2061%20//%0A%2062%20//%20Fields%3A%0A%2063%20//%201%20%20ID%3A%20%20%20%20%20%20Token%20counter%2C%20starting%20at%201%20for%20each%20new%20sentence%20and%20increasing%0A%2064%20//%20%20%20%20%20%20%20%20%20%20%20%20%20by%201%20for%20every%20new%20token.%0A%2065%20//%202%20%20FORM%3A%20%20%20%20Word%20form%20or%20punctuation%20symbol.%0A%2066%20//%203%20%20LEMMA%3A%20%20%20Lemma%20or%20stem.%0A%2067%20//%204%20%20CPOSTAG%3A%20Coarse-grained%20part-of-speech%20tag%20or%20category.%0A%2068%20//%205%20%20POSTAG%3A%20%20Fine-grained%20part-of-speech%20tag.%20Note%20that%20the%20same%20POS%20tag%0A%2069%20//%20%20%20%20%20%20%20%20%20%20%20%20%20cannot%20appear%20with%20multiple%20coarse-grained%20POS%20tags.%0A%2070%20//%206%20%20FEATS%3A%20%20%20Unordered%20set%20of%20syntactic%20and/or%20morphological%20features.%0A%2071%20//%207%20%20HEAD%3A%20%20%20%20Head%20of%20the%20current%20token%2C%20which%20is%20either%20a%20value%20of%20ID%20or%20%270%27.%0A%2072%20//%208%20%20DEPREL%3A%20%20Dependency%20relation%20to%20the%20HEAD.%0A%2073%20//%209%20%20PHEAD%3A%20%20%20Projective%20head%20of%20current%20token.%0A%2074%20//%2010%20PDEPREL%3A%20Dependency%20relation%20to%20the%20PHEAD.%0A%60%60%60%0A%u76F4%u63A5%u4F7F%u7528CoNLL%20table%u66F4%u6613%u4E8E%u88AB%u4EE3%u7801%u89E3%u6790%u3002%u5982%u679C%u9700%u8981CoNLL%20table%u8F93%u51FA%uFF0C%u9700%u8981%u6211%u4EEC%u4FEE%u6539demo.sh%u3002%u76F4%u63A5%u6765%u4E2A%u4F8B%u5B50%uFF1A%0A%60%60%60%0AINFO%3Atensorflow%3AProcessed%201%20documents%0A1%20%20%20%20%20%20%20What%20%20%20%20_%20%20%20%20%20%20%20PRON%20%20%20%20WP%20%20%20%20%20%20_%20%20%20%20%20%20%200%20%20%20%20%20%20%20ROOT%20%20%20%20_%20%20%20%20%20%20%20_%0A2%20%20%20%20%20%20%20is%20%20%20%20%20%20_%20%20%20%20%20%20%20VERB%20%20%20%20VBZ%20%20%20%20%20_%20%20%20%20%20%20%201%20%20%20%20%20%20%20cop%20%20%20%20%20_%20%20%20%20%20%20%20_%0A3%20%20%20%20%20%20%20a%20%20%20%20%20%20%20_%20%20%20%20%20%20%20DET%20%20%20%20%20DT%20%20%20%20%20%20_%20%20%20%20%20%20%205%20%20%20%20%20%20%20det%20%20%20%20%20_%20%20%20%20%20%20%20_%0A4%20%20%20%20%20%20%20control%20_%20%20%20%20%20%20%20NOUN%20%20%20%20NN%20%20%20%20%20%20_%20%20%20%20%20%20%205%20%20%20%20%20%20%20nn%20%20%20%20%20%20_%20%20%20%20%20%20%20_%0A5%20%20%20%20%20%20%20panel%20%20%20_%20%20%20%20%20%20%20NOUN%20%20%20%20NN%20%20%20%20%20%20_%20%20%20%20%20%20%201%20%20%20%20%20%20%20nsubj%20%20%20_%20%20%20%20%20%20%20_%0A%60%60%60%0A%u8FD9%u662F%u5BF9What%20is%20a%20control%20panel%u7684%u8F93%u51FA%u3002%u4E0B%u56FE%u6E90%u4E8E%5BInside%20Google%20SyntaxNet%5D%28http%3A//andrewmatteson.name/index.php/2017/02/04/inside-syntaxnet/%29%0A%21%5BAlt%20text%5D%28./1499230365640.png%29%0A%u53EF%u89C1%u7B2C3%2C6%2C9%2C10%u5B57%u6BB5%uFF0CSytanxNet%u5E76%u6CA1%u6709%u8F93%u51FA%0A%0ACoNLL%20table%u4E2D%u7684%u6240%u6709tag%u7F29%u5199%u7684%u542B%u4E49%u5728%u8FD9%u91CC%5BUniversal%20Dependency%20Relations%5D%28http%3A//universaldependencies.org/u/dep/%29%0A%0A%u9488%u5BF9CPOSTAG%20%26%20POSTAG%uFF0C%u53EF%u53C2%u8003%0A-%20%5BAlphabetical%20list%20of%20part-of-speech%20tags%20used%20in%20the%20Penn%20Treebank%20Project%5D%28https%3A//www.ling.upenn.edu/courses/Fall_2003/ling001/penn_treebank_pos.html%29%0A-%20%5BWh-%20words%5D%28http%3A//www.ling.upenn.edu/histcorpora/annotation/pos-wh.htm%29%0A%0A%0A%0A%23%23%23NLTK%0A%3E**NLTK**%20is%20a%20leading%20platform%20for%20building%20**Python**%20programs%20to%20work%20with%20human%20language%20data.%20It%20provides%20easy-to-use%20interfaces%20to%20over%2050%20corpora%20and%20lexical%20resources%20such%20as%20WordNet%2C%20along%20with%20a%20suite%20of%20text%20processing%20libraries%20for%20classification%2C%20tokenization%2C%20stemming%2C%20tagging%2C%20parsing%2C%20and%20semantic%20reasoning%2C%20wrappers%20for%20industrial-strength%20NLP%20libraries%2C%20and%20an%20active%20discussion%20forum.%0A%0A%u6211%u7684%u60F3%u6CD5%u662F%u53EF%u4EE5%u7528NLTK%u6765%u5BF9SyntaxNet%u7684%u8F93%u51FA%u505A%u8FDB%u4E00%u6B65Stemming/Lemmarization%u5904%u7406%u3002%0A%0A%23%23%23%23%5BNLTK%20vs.%20spaCy%5D%28http%3A//blog.thedataincubator.com/2016/04/nltk-vs-spacy-natural-language-processing-in-python/%29%0A%0A%23%23%23%23Stemming%20vs.%20Lemmatization%0A%u8FD9%u4E24%u4E2A%u8BCD%u603B%u662F%u4E00%u8D77%u51FA%u73B0%uFF0C%u4F5C%u7528%u5F88%u76F8%u50CF%u3002%u533A%u522B%u662F%uFF1A%0A%3ELemmatisation%20is%20closely%20related%20to%20stemming.%20The%20difference%20is%20that%20**a%20stemmer%20operates%20on%20a%20single%20word%20without%20knowledge%20of%20the%20context**%2C%20and%20therefore%20cannot%20discriminate%20between%20words%20which%20have%20different%20meanings%20depending%20on%20part%20of%20speech.%20However%2C%20stemmers%20are%20typically%20easier%20to%20implement%20and%20run%20faster%2C%20and%20the%20reduced%20accuracy%20may%20not%20matter%20for%20some%20applications.%0A%0A%3EIn%20computational%20linguistics%2C%20lemmatisation%20is%20the%20algorithmic%20process%20of%20determining%20the%20lemma%20for%20a%20given%20word.%20**Since%20the%20process%20may%20involve%20complex%20tasks%20such%20as%20understanding%20context%20and%20determining%20the%20part%20of%20speech%20of%20a%20word%20in%20a%20sentence**%20%28requiring%2C%20for%20example%2C%20knowledge%20of%20the%20grammar%20of%20a%20language%29%20it%20can%20be%20a%20hard%20task%20to%20implement%20a%20lemmatiser%20for%20a%20new%20language.%0A%0A%u7B80%u800C%u8A00%u4E4B%uFF0C%u5C31%u662FLemmarization%u662F%u5305%u542B%u6709%u4E0A%u4E0B%u6587%u542B%u4E49%u7684%uFF0C%u800CStemming%u53EA%u662F%u5BF9%u5355%u4E2A%u5355%u8BCD%u8FDB%u884C%u6620%u5C04%u3002%0A%0ANLTK%u652F%u6301%u591A%u79CDStemmer%uFF0C%u5305%u62EC%u4F46%u4E0D%u9650%u4E8E%20Porter%20stemmer%2C%20Lancaster%20Stemmer%2C%20Snowball%20Stemmer%u3002%0A%60%60%60python%0A%3E%3E%3E%20from%20nltk.stem%20import%20SnowballStemmer%0A%3E%3E%3E%20snowball_stemmer%20%3D%20SnowballStemmer%28%u201Cenglish%u201D%29%0A%3E%3E%3E%20snowball_stemmer.stem%28%u2018maximum%u2019%29%0Au%u2019maximum%u2019%0A%3E%3E%3E%20snowball_stemmer.stem%28%u2018presumably%u2019%29%0Au%u2019presum%u2019%0A%3E%3E%3E%20snowball_stemmer.stem%28%u2018multiply%u2019%29%0Au%u2019multipli%u2019%0A%60%60%60%0ANLTK%u4E2D%u7684Lemarize%3A%20%0A%60%60%60python%0A%3E%3E%3E%20from%20nltk.stem%20import%20WordNetLemmatizer%0A%3E%3E%3E%20wordnet_lemmatizer%20%3D%20WordNetLemmatizer%28%29%0A%3E%3E%3E%20wordnet_lemmatizer.lemmatize%28%u2018dogs%u2019%29%0Au%u2019dog%u2019%0A%3E%3E%3E%20wordnet_lemmatizer.lemmatize%28%u2018churches%u2019%29%0Au%u2019church%u2019%0A%3E%3E%3E%20wordnet_lemmatizer.lemmatize%28%u2018is%u2019%2C%20pos%3D%u2019v%u2019%29%0Au%u2019be%u2019%0A%3E%3E%3E%20wordnet_lemmatizer.lemmatize%28%u2018are%u2019%2C%20pos%3D%u2019v%u2019%29%0Au%u2019be%u2019%0A%3E%3E%3E%0A%60%60%60%0A*%20pos%20%3D%20Part%20Of%20Speech