PCFG parser及实现

句法分析学习笔记 句法分析能够帮助我们更好的理解句子,说白了就是从语法的角度来理解句子的含义。 句法分析难点与方法学习笔记: 此张PPT主要就是说明了由于中文的特性,使得中文的句法分析成熟度不高,较于词法分析的成熟度低。 此张PPT主要在说树库起到的作用,有了树库才有统计学应用于句法分析,即PCFG。 而树库就是用来给候选树打分的基础,有了大规模树库才能够对正确的句法树打一个高分值,而不合理的句法树则会得一个... 阅读详情

原文

源代码点击下载

背景介绍:
PCFG是ProbabilisticContext Free Grammar的简写,是Chomsky范式中的2型文法。句法分析就是解析出句子的词之间的结构关系,对于什么是句法分析,我们并不陌生,因为我们从上小学开始就经过了句法分析的“严酷”训练,回想一下,语文老师教我们怎么解析一个句子的主谓宾定状补。

为了便于科学描述和交流,把一个句法表示成四元组:

         G= (N,T,N1, R)

而PCFG是多了概率的句法:

         PCFG= (N,T,N1,R,P)

其中,

N代表非终结符集合

T代表终结符集合

N1代表初始非终结符

R代表产生规则集

P 代表每个产生规则的统计概率

 

如下为一个PCFG规则集以及概率

S -> NP VP   0.7;

S -> VP      0.2;

S -> NP      0.1;

S -> VC      0.1;

NP -> noun   0.3;

NP -> adj noun 0.2;

NP -> DJ       0.2;

NP -> DJ NP    0.3;

DJ -> VP de    0.4;

DJ -> NP de    0.6;

VP -> VC NP    1.0;

VC -> vt adj   0.3;

VC -> VC utl   0.5;

VC -> vt       0.2;
                                                             Grammar 1


 

对于非科班出身的同学,理解这些可能有些难度。举个例子来说:咬死了猎人的狗(这是一个歧义句,分词结果:咬/vt 死/adj 了/utl 猎人/noun 的/de 狗/noun)它的句法结构树如下:

如上图所示,“咬死了猎人的狗”每个词可以理解为T的一个子集。其他的英文字符理解为N的一个子集。S即是N1。

从句法树中可以看出,句法树1是一个NP结构,着重强调名词短语-狗,可理解为有条狗咬死了猎人,这句话描述的就这个凶手---狗。句法树2是一个 VP结构,猎人的狗作为一个名词短语,说明猎人的狗被咬死了。

PCFG的三个问题:
(1)给定一个句子,估计产生句子的概率;

(2)在语句句法结构有歧义的情况下,如何快速选择最佳的句法分析;

(3)如何从语料库中训练文法的参数。 

 

问题1解答:
问题1是计算给定的句子,按照句法规则计算所有可能句法树,并求出其概率之和。用w(p,q)表示句子中从下标为p到下标为q(包括q)的词。句子分词后,第一个词标记为1,第二个标记成2,以此类推。那么”咬死猎人的狗”为例,对应的分词和下标是:

         咬    死   了   猎人  的   狗

         1     2    3       4        5    6

那么w(1,3)  = 咬死了;w(2,4) = 死了猎人;w(1,6)=咬死了猎人的狗。所以求解问题1,对于这句话来说,相当于求解w(1,6)所有句法树的概率之和,也就是图1中句法树1和句法树2的概率之和。

用P(NJpq)表示从p开始到q的所有符合Nj的产生式的概率。那么产生” 咬死了猎人的狗”的概率就是P(N11,6)。

计算这个概率的方法有两种,一种是从内部计算,另外一种是外部计算。

内部算法
要计算P(NJpq),我们可以从内部把pq字符串一分为2(这里假设所有产生式都是规范的Chomsky产生式,Nf- > Nr Ns) , 分割点为e,那么只要看看w(p,e) 是否符合Nr,且w(e+1, q)符合Ns,然后把所有符合规则的概率相加,就计算出来了P(NJpq)。内部算法公式如下:

 

举例来说吧,我们来计算”咬死了”是VC的概率。对于我们的语法Grammar 1, 由VC发出的规则有三条:

VC -> vtadj   0.3;

VC -> VCutl   0.5;

VC -> vt       0.2;

咬/vt 死/adj 了/utl。这里假设P(咬|vt) = 1.0, P(死|adj) = 1.0, P(了|utl) = 1.0。

对于第一条规则,VC -> vtadj   0.3; 我们分别要计算P(咬|vt)*P(死了|adj) + P(咬死|vt)*P(了|adj)的概率,发现都不符合,所以这条概率为0。

对于第二条规则,VC -> VCutl  0.5;我们分别要计算 P(咬|VC)*P(死了|utl) + P(咬死|VC)*P(了|utl)的概率。P(死了|utl) = 0, P(咬死|VC) = 0.3(只符合第一条规则),P(了|utl) = 1.0。故此条的概率为 (0 +0.3) * 0.5 = 0.15

对于第三条规则,VC ->vt       0.2;我们要计算P(咬死了|vt)的概率,为0。

那么“咬死了”为VC的概率 = 0 + 0.15 + 0 = 0.15;

 

         由公式我们可知这是一个递归过程,我们简单的交给递归函数去实现就可以了。我们定义GetBeta(double *** beta, p, q, j)为计算Nj->W(p,q)的概率,那么其核心算法就可以表示成如下的递归式调用:

GetBeta(……){
//……..
         for(intd = p; d< q ; d ++){
                   prob+= GetBeta(beta, p, d, rule_id_table[it->r1]) * GetBeta(beta, d+1, q, rule_id_table[it->r2]);
         }
         prob*= it->prob;
//……
}
 
//详细代码在下载包内。

最后,如果要计算整条词串的概率,只需要计算N1 –> w(1,n)的概率即可。

外部算法
外部算法的思想是对于计算W(p,q)为Nj的概率,假设已知其父串Nf的概率(Nf -> Nj Ng 或 Nf->Ng Nj),只要计算除去串中w(p,q)部分,其他部分为Ng的概率。举例来说,假设我们已知了”咬死了”为VC的概率,对于产生式VC->VC utl, 我们要计算”咬死”为VC的概率,等同于我们计算”了”为utl的概率。”了”为utl的概率我们可以用内部算法计算获得。外部算法的公式如下:

核心算法:

GetAlpha(.....){
//.......
for(int e = q + 1; e <= m; e++ ){
         al= GetAlpha(alpha, p, e, rule_id_table[rule->first], m, beta);
         be=  GetBeta(beta, q+1,e,rule_id_table[probrule->r2]);
         prob+= al * be;
         //cout<<"alpha["<<rule->first<<"]["<<p<<","<<e<<"]="<<al<<"beta["
         //<<probrule->r2<<"]"<<"["<<q+1<<","<<e<<"]="<<be<<"prob="<<prob<<endl;
}
prob *= probrule->prob;
//......
}

问题2解答
问题2的解答使用经典的Viterbi算法。即每次都找最优的,通过回溯的方法,找到最佳解。其核心部分也是一个递归调用的方法。这里的Viterbi的实现和HMM的Viterbi实现方式上有所不同(HMM的代码将来会贴出来),HMM中使用循环迭代方式。公式如下:

GetDeta(....){
// .......
 for(inte = p; e < q; e ++){
                   prob= it->prob * GetDeta(deta, p, e, rule_id_table[it->r1], bestpath)
                            *GetDeta(deta, e+1, q, rule_id_table[it->r2], bestpath);
                   if(prob> maxprob){
                            maxprob= prob;
                            best.e= e;
                            best.r1= rule_id_table[it->r1];
                            best.r2= rule_id_table[it->r2];
                   }
         }
//.........
}

问题3解答
对于有标注好的训练语料,解决问题3就比较简单了,可以使用最大似然概率法来统计各条产生规则的概率,最后保证每条sum{Nf-> Nj Ng} = 1.0即可。

对于从生语料中学习,可以使用概率期望算法,分别计算出整条句子的期望概率,然后计算每个产生式的期望值,做商。最后迭代到误差小于某一值。

代码就不再写了,因为所有需要的元素都已经实现了,只要调用下就能求得。

 

小结
在代码编写过程中,遇到两个bug,总共浪费了10多个小时找出来。

第一个bug是在写内部算法时,把除了W(k,k)除了词性以外的其他非终结符概率都设置成了0,导致对于单产生式的语法结果都变成了0.举例来说,如咬/vt,我初始化的时候,把beta[0][0][vt] = 1.0, beta[0][0][i] = 0, i!= vt; 那么在获取产生式VC->vt的概率时,就查到概率为0,直接返回,最后结果当然就不对了。对于这种bug,目前还真没有什么好办法避免,除非花大量时间去弄明白每条公式的意义,以及每个细节的详细流程。不过这又不太现实,人总是会被某些思维定式给影响住。这种只好遇到bug,进行打log分析吧。

第二个bug花的时间比较长,写完代码是正好周五下午,搞到很晚没解决掉,周一上午才发现问题。这个bug是在写外部算法时两次初始化beta时产生的。还记得写这段代码时我从内部算法中拷贝了代码过来,发现初始化beta有两处代码调用,于是把这段代码重构成了一个函数,等函数抽取完,竟然忘了把copy的代码beta改成alpha,这样在初始化alpha的地方又初始化了一遍beta...就是这一处bug,弄的我百思不得骑姐!将来如何避免这种bug呢,一是写伪代码,二copy代码时要彻底,甚至不copy,三不要同时做两件事情!

参考
[1] 统计自然语言处理基础,Christopher.D.Manning,Hinrich Schutze.

[2] 一个简单的PCFG分析器 http://www.pudn.com/downloads156/sourcecode/compiler/detail694248.html
 

PCFG parser 1. 实现了PCFG算法的内向和外向算法,以及Viterbi算法的源代码(500 lines) 2. 内部还有一个基于字符匹配的聊天机器人小程序(300 lines) 立即下载

相关推荐

PyPI 官网下载 | pcfg-0.1.0.tar.gz

资源来自pypi官网。 资源全名:pcfg-0.1.0.tar.gz

【Python自然语言处理】概率上下文无关文法(PCFG)及神经网络句法分析讲解(图文解释 超详细)

【Python自然语言处理】概率上下文无关文法(PCFG)及神经网络句法分析讲解(图文解释 超详细)

showswoller的博客 3489

TwinCAT 3 实战:手把手教你用PLC和C++读写第三方伺服驱动器的CoE参数

本文详细介绍了在TwinCAT 3环境中通过PLC和C++两种技术路线实现对第三方伺服驱动器CoE参数的精准操控。从环境准备到具体实现,包括硬件配置、核心函数使用及性能优化策略,为工程师提供了全面的实战指南。特别针对CoE参数访问的效率和稳定性问题,给出了实用的调试技巧和异常处理方案。

weixin_33743248的博客 443

句法分析(PCFG,Transition-based parsing)

句法分析的基本任务是确定句子的句法结构或者句子中词汇之间的依存关系。   句法分析分为句法结构分析(syntactic structure parsing)和依存关系分析(dependency parsing)。以获取整个句子的句法结构或者完全短语结构为目的的句法分析,被称为成分结构分析(constituent structure parsing)或者短语结构分析(phrase s...

wwx123521的博客 9572

ZLMediaKit源码分析(二)推流创建

ZLMediaKit推流结构体创建是在RtspSession::onRecv()之后。如何触发onRecv()请参考上一篇文章这里不在赘述。

cliffordl的专栏 5074

ABAP 7.40+新语法实战:用VALUE和REDUCE五分钟搞定复杂内表统计

本文详细介绍了ABAP 7.40+新语法中的VALUE和REDUCE操作符,如何高效处理复杂内表统计任务。通过实战案例展示,这些新语法能将代码量减少70%以上,显著提升开发效率和可读性,特别适合大数据量下的销售数据分析、分组统计等场景。

weixin_27219587的博客 207

中文 NLP(11) -- stanfordNLP 生成文法之 PCFG 模型

在短语结构文法中,也就是转换生成语法,目前最成熟、精度最高的算法就是 PCFG 算法。 另一种基于依存句法理论的分析方法,最高效的是深度学习算法(Trainsition-Based LSTM) PCFG 即 Probabilistic CFG ,也就是基于概率的短语结构分析。也就是在 G = (X,V,S,R) 的基础上加一个 P 表示概率,变成 G= (X,V,S,R,P) 约束如下: ...

ouprince 7490

基于Matlab-Simulink的大林算法控制系统设计与振铃消除实验

本文详细介绍了基于Matlab-Simulink的大林算法控制系统设计与振铃消除实验。通过分析纯滞后系统的控制难题,探讨大林算法在工业控制中的应用优势,并提供Matlab-Simulink环境搭建、控制器D(z)设计、振铃消除及仿真实验的完整流程。文章还对比了大林算法与PID控制的性能差异,为工程实践提供参考。

dropout6artist的博客 796

PCFG Parser的简单实现 -- Java版

该代码是一个句法分析器的简单的实现逻辑,未经过优化,主要帮助理解分析器主要原理和算法,有了一定基础后参考Stanford Parser的源码(经过了高度的优化)。 下面是文件的大概预览 下面是运行的结果 下面是各个类的代码 package com.sample; import java.util.Arrays; import java.util.List; /** * ...

duduhonghong的博客 448

【RT-DETR涨点改进】独家Conv改进篇 | 来自TIP 2024顶刊| 引入 DEConv细节增强卷积模块, 能够恢复更多细节信息,提升小目标检测精度、含多种不同模型改进点

本文提出了一种细节增强卷积(DEConv)模块,通过融合多种差异卷积(CDC、ADC、HDC、VDC)来增强图像特征表示能力,特别在边缘和纹理细节提取方面表现突出。该模块采用重参数化技术,在不增加计算成本的情况下,将先验信息融入常规卷积层,显著提升了RT-DETR模型在模糊或遮挡场景下的目标检测精度。实验验证了DEConv在多种骨干网络(ResNet18/50、HGNet等)中的有效性,为实时目标检测系统提供了轻量高效的改进方案。

Ai缝合怪、助力小伙伴高效发论文 452

Python 爬虫进阶技巧:新手必学的反爬突破与效率优化

本文系统总结了爬虫进阶的核心技巧,针对新手常见的反爬拦截、效率低下、动态页面解析等痛点问题,提出了可落地的解决方案。主要内容包括:通过随机UA池、代理IP池和Cookie池突破常见反爬机制;利用多线程/异步请求提升爬取效率;使用Selenium解析动态渲染页面;以及数据清洗方法提升数据质量。文中提供了完整的代码示例和实战对比数据,并强调爬虫开发应遵守合规性要求。这些技巧能帮助开发者快速提升爬虫实战能力,应对80%以上的常见爬取需求。

2503_91057718的博客 1436

分词、语法树

######Jieba分词###### import jieba string='如果一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义的' print(string) seg_list=jieba.cut(string,cut_all=False,HMM=True) seg_str=' '.join(seg_list) ######PCFG句法分析###### from nltk.p...

qianjin_w的专栏 504

Python 爬虫进阶:爬取 APP 数据(Charles 抓包 + Requests)

本文详细介绍了APP数据爬取的完整技术方案。首先通过Charles抓包工具配置HTTPS代理和证书,解析APP通信协议;然后分析请求参数、反爬机制和动态签名生成规则;接着使用Python的Requests库实现模拟请求、分页爬取和数据存储;最后针对证书问题、Token失效等常见问题提供解决方案。文章强调抓包分析、参数逆向和请求模拟三大核心技术,同时提醒开发者需遵守法律法规,合理控制爬取频率。该方案适用于移动端数据采集场景,为无法直接获取网页数据的情况提供了有效解决方案。

2503_91057718的博客 2120

python自然语言处理实战核心技术与算法——基于PCFG的中文句法分析实战

在本书中这一篇章就写的略显单薄,不过作者也说明了,本书是NLP入门实践书籍,句法分析又属于NLP中较为高阶的问题,所以并没有深入讲解,我学习本书也是入门NLP,学习完本书后会学习《统计自然语言处理》。 由于本章实战内容很少,而且也没有特别晦涩的代码,所以在本文中更多的是讲解windows配置等问题。 目录一、JDK安装与配置二、PCFG文件下载三、代码四、总结五、参考 一、JDK安装与配置 因为stanford parser是基于统计概率句法分析的一个java实现,所以需要安装JDK,JDK下载链接在这.

LiQZ的博客 3934

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

斯坦福 stanford coreNLP 中的PCFG parser-lexparser

PCFG模型训练Java -Xmx7g edu.stanford.nlp.parser.lexparser.LexicalizedParser -tLPP edu.stanford.nlp.parser.lexparser.ChineseTreebankParserParams -train data/source/dataCTBZh//bracketed -saveToSerializ...

一休哥的专栏 3244

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Stanford Dependency-Parser 分享

<br />今天对Stanford Dependency Parser全面进行了调试。经过参看FAQ,得到Dep分析代码如下<br />   TreebankLanguagePack tlp = new ChineseTreebankLanguagePack();<br />   GrammaticalStructureFactory gsf = tlp.grammaticalStructureFactory();<br />   GrammaticalStructure gs = gsf.newGr

伏龙的专栏 6763

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

自然语言处理:基于PCFG的中文句法分析样例

1、下载 https://nlp.stanford.edu/software/lex-parser.shtml#Download 解压缩 复制stanford-parser.jar和stanford-parser-3.9.2-models.jar到python程序文件同目录下 2、python程序 #coding=utf-8 # 分词 import jieba # PCFG句法分析 fr...

程裕强的专栏 2863

stanford parser 使用说明

preface: 最近忙着的项目想试着用斯坦福的parser,来解析句子生成句法分析树,然后分析子树,与treekernal结合起来,训练。stanford parser神器下载下来了,可使用却是蛋疼。一大堆说明,却没个方便快捷关于总的介绍。 一、必先利其器 stanford parser主页:http://nlp.stanford.edu/software/lex-parser.sh

无限大地NLP_空木的专栏 2万+

stanford parser的python使用

前提知识: StanfordParser(短语结构句法), StanfordDependencyParser(依存结构句法)StanfordParser 和 StanfordDependencyParser 都继承自 GenericStanfordParser ,使用 stanford-parser.jar 来提供句法分析功能。   Python 调用 Stanford Parser 两种方...

ccbrid的博客 7048

Python与自然语言处理——句法分析

Python与自然语言处理——句法分析句法分析句法分析简介数据集与评测方法数据集评测方法句法分析的常用方法 句法分析 句法分析是机器翻译的核心数据结构,是对语言进行深层次理解的基石。 句法分析简介 主要任务 识别句子中所包含的句法成分以及这些成分之间的关系,一般以句法树来表示句法分析的结果。 主要难点 歧义 搜索空间 句法分析分类 完全句法分析:企图获取整个句子的句法结构 部分句法分析:...

wk19951125的博客 7329

PCFG与CYK算法实战:从ATIS数据集解析到语法树生成(附Python 3.11代码)

本文详细介绍了如何利用PCFG与CYK算法从ATIS航空旅行数据集中解析并生成语法树。通过Python 3.11代码实现,涵盖数据预处理、概率估计、解析算法及可视化全流程,帮助开发者掌握自然语言处理中的句法分析技术。

weixin_33713707的博客 383

自然语言处理系列之: 句法分析

大纲 句法分析及其难点; 句法分析相关数据和技术; 基于Stanford Parser的句法分析实战 6.1 句法分析概述 句法分析(Parsing)定义 从单词串获取句法结构的过程,实现该过程的工具或程序叫做句法分析器(Parser)。分为完全句法分析和局部句法分析,完全句法分析以获取整个句子的句法结构为目的,而局部句法分析只关注局部成分,依存句法分析即为局部分析法的一种; 句法分析难点 歧义 搜索空间 方法分类 基于规则 处理大规模真实文本时,存在语法规则覆盖有限、系统可迁移差

Viper的程序员修炼手册 1465

stanford parser使用

stanford parser是一个可进行短语结构和依存结构分析的parser,网络上的资料很多,而且在stanford nlp的网站上也有很多说明,代码中的readme文件数的也很详细。在这里简要记录一下我学习的一些过程。     stanford parser的源代码下载后可直接使用,不需要做任何修改。训练语料默认是英文的wsj语料。在使用中文训练时需要在参数中指定: 训练:使用中文训

一个菜鸟 6096

NLP学习(七)使用stanford实现句法分析-Python3实现

句法分析 句法分析是机器翻译的核心数据结构,是对语言进行深层次理解的基石。 句法分析简介 1.主要任务 识别句子中所包含的句法成分以及这些成分之间的关系,一般以句法树来表示句法分析的结果。 2.主要难点 歧义 搜索空间 3.句法分析分类 完全句法分析:企图获取整个句子的句法结构 部分句法分析:只关注局部的一些成分 4.相关方法 基于规则 存在着语法规则覆盖有限、系统可迁移差等缺陷 基于统计(主流) 数据集与评测方法 数据集 与别的语言处理所需要的数据集不同,句法分析需要的是一种树形的标注结构,又称为树库,如

qq_30868737的博客 5003
上一篇: PCFG CKY实现--python版本
下一篇: 微信小程序之购物车功能
CopperDong
博客等级 码龄14年 1205粉丝 466原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值