> For the complete documentation index, see [llms.txt](https://codingling.gitbook.io/study/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codingling.gitbook.io/study/basic-know/yu-chu-li/14-yu-fa-fen-xi.md).

# \[1-4]语法分析

上下文无关文法（Context-Free Grammar, CFG）

```python
# toy CFG 
>>> from nltk import CFG
>>>toy_grammar = 
nltk.CFG.fromstring(
"""
  S -> NP VP  		 # S indicate the entire sentence   
  VP -> V NP              # VP is verb phrase the 
  V -> "eats" | "drinks"  # V is verb we are using only 2 verbs      in the example
  NP -> Det N   # NP is noun phrase (chunk that has noun in it)
  Det -> "a" | "an" | "the" # Det is determiner used in the sentences 
  N -> "president" |"Obama" |"apple"| "coke"  # N some example nouns 
   """)
>>> toy_grammar.productions()
```

语法分析器通过使用一组语法规则，处理输入字符串，形成构建语法概念的一个或多个规则。语法是一种声明句子结构的完整的规范。语法分析器对语法进行了程序性解释。语法分析器通过搜索各种树空间，找到给定句子的最优树。

概率CFG

```python
# similarly a PCFG also can be built 

>>> from nltk import PCFG
>>> toy_pcfg1 = PCFG.fromstring("""
	S -> NP VP [1.0]
	NP -> Det N [0.5] | NP PP [0.25] | 'John' [0.1] | 'I' [0.15]
	Det -> 'the' [0.8] | 'my' [0.2]
	N -> 'man' [0.5] | 'telescope' [0.5]
	VP -> VP PP [0.1] | V NP [0.7] | V [0.2]
	V -> 'ate' [0.35] | 'saw' [0.65]
	PP -> P NP [1.0]
	P -> 'with' [0.61] | 'under' [0.39]
	""")
# ref :http://www.nltk.org/howto/grammar.html
```

### 语法分析器

#### 递归下降的语法分析器

递归下降的语法分析是一种最简单的语法分析形式，这是一种自上而下的方法。当语法分析器从左至右读取字符串时，它试图验证输入流的语法是正确的。所需的基本操作涉及从输入流中读取字符，并将它们与语法中（描述输入句法）的终端符号进行匹配。当递归下降语法分析器获得正确的匹配时，会向前看一个字符，并将输入流的读取指针向前移动。

#### 移位归约语法分析器

一种简单的自上而下的语法分析器。移位归约语法分析器试图找到对应于文法产生式右侧的一系列单词和短语，并使用产生式左侧的内容取代它们，直到整个句子得到归约。

#### 图表语法分析器

应用动态规划的算法设计技术，保存中间结果，即存储语法分析任务的部分解决方案，然后在有必要时，允许我们查看这些中间结果，以便我们高效地得到完整的解决方案。

#### 正则表达式语法分析器

使用以语法形式定义的正则表达式，在标注了POS的字符串上工作。语法分析器使用这些正则表达式，分析给定的句子，生成相应的语法分析树。

```python
# Regex parser

>>> chunk_rules=ChunkRule("<.*>+","chunk everything")
>>> import nltk
>>> from nltk.chunk.regexp import *
>>> reg_parser = RegexpParser('''
 		NP: {<DT>? <JJ>* <NN>*} # NP
  		 P: {<IN>}              # Preposition
             V: {<V.*>}             # Verb
  	      PP: {<P> <NP>}          # PP -> P NP
   	      VP: {<V> <NP|PP>*}  # VP -> V (NP|PP)*
  ''')
>>> test_sent="Mr. Obama played a big role in the Health insurance bill" 
>>> test_sent_pos=nltk.pos_tag(nltk.word_tokenize(test_sent))
>>> paresed_out=reg_parser.parse(test_sent_pos)
```

### 依存分析

依存分析(Dependency Parsing, DP)是一种现代的语法分析机制。依存分析的主要概念是每个语言单位（单词）使用有向链路。在语言学上，这些链路称为依存(dependency)。

短语结构语法生成的分析树试图捕捉单词和短语之间的关系，并试图最终捕捉到短语之间的关系。然而，依存树只关注单词之间的依存性。

```python
# Stanford Parser [Very useful]

>>>from nltk.parse.stanford import StanfordParser
>>>english_parser = StanfordParser('stanford-parser.jar', 'stanford-parser-3.4-models.jar')
>>>english_parser.raw_parse_sents(("this is the english parser test")
```

### 组块化

组块化是浅层次的语法分析，在组块化过程中，我们不试图触及句子的深层结构，而是试图联合句子中具有意义的一些组块。

可以将组块(chunk)定义为可处理的最小单元。例如一句话可以分为两个组块：名词短语(NP)，动词短语(VP)。

```python
# Chunking 

>>>from nltk.chunk.regexp import *
>>>test_sent="The prime minister announced he had asked the chief government whip, Philip Ruddock, to call a special party room meeting for 9am on Monday to consider the spill motion."
>>>test_sent_pos=nltk.pos_tag(nltk.word_tokenize(test_sent))
>>>rule_vp = ChunkRule(r'(<VB.*>)?(<VB.*>)+(<PRP>)?', 'Chunk VPs')
>>>parser_vp = RegexpChunkParser([rule_vp],chunk_label='VP')
>>>print parser_vp.parse(test_sent_pos)    

>>>rule_np = ChunkRule(r'(<DT>?<RB>?)?<JJ|CD>*(<JJ|CD><,>)*(<NN.*>)+', 'Chunk NPs')
>>>parser_np = RegexpChunkParser([rule_np],chunk_label="NP")
>>>print parser_np.parse(test_sent_pos) 
```

### 信息抽取

原始文本——分句——分词——POS标注——输入检测——关系提取——关系

命名实体识别

```python
# NP chunking (NER)

>>>f=open(# absolute path for the file of text for which we want NER)
>>>text=f.read()
>>>sentences = nltk.sent_tokenize(text)
>>>tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
>>>tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
>>>for sent in tagged_sentences:
>>>		print nltk.ne_chunk(sent)
```

关系抽取

```python
# Relation Extraction 

>>>import re
>>>IN = re.compile(r'.*\bin\b(?!\b.+ing)')
>>>for doc in nltk.corpus.ieer.parsed_docs('NYT_19980315'):
>>>	for rel in nltk.sem.extract_rels('ORG', 'LOC', doc, corpus='ieer', pattern = IN):
>>>print(nltk.sem.rtuple(rel))
```

指定我们需要的关系模式，以及我们希望关系定义的NER类型。
