专栏首页SimpleAI【Hello NLP】CS224n笔记[4]:自然语言中的依存分析(Dependency Parsing)

【Hello NLP】CS224n笔记[4]:自然语言中的依存分析(Dependency Parsing)

相比于计算机视觉,NLP可能看起来没有那么有趣,这里没有酷炫的图像识别、AI作画、自动驾驶,我们要面对的,几乎都是枯燥的文本、语言、文字。但是,对于人工智能的征途来说,NLP才是皇冠上的那颗珍珠,它美丽却又难以摘取,当NLP的问题解决了,机器才真正具备了理解、思考的能力,我们才敢说实现了真正的“智能”。

SimpleAI 【HelloNLP】系列笔记,主要参考各知名网课(Stanford CS224n、DeepLearning.ai、李宏毅机器学习等等),并配合NLP的经典论文和研究成果、我的个人项目实践经验总结而成。希望能和各位NLP爱好者一起探索这颗AI皇冠的明珠!

CS224n笔记[4]:自然语言中的依存分析(Dependency Parsing)

作者:郭必扬

什么是依存分析

自然语言处理任务中,有很重要的一块,就是分析语言的结构。语言的结构,一般可以有两种视角:

  1. 组成关系(Constituency)
  2. 依赖关系(Dependency)

前者,主要关心的是句子是怎么构成的,词怎么组成短语。所以研究Constituency,主要是研究忽略语义的“语法”结构(context-free grammars)。

后者,依赖关系,则主要关心的是句子中的每一个词,都依赖于哪个其他的词。

比如下面这个句子:

“瞧这个可爱的小傻瓜!”

  • “傻瓜”,是“瞧”这个动作的对象,因此“傻瓜”是依赖于“瞧”的;
  • “可爱的”、“小”都是修饰“傻瓜”的,因此,这两个形容词都是依赖于“傻瓜”的;
  • “这个”,同样是指示“傻瓜”的,因此它也依赖于“傻瓜”。

这样,我们就清楚了这个句子中的所有依赖关系,画成依赖关系图则是这样:

依赖关系

注意,在图中我们增加了一个根节点“Root”,这是为了让“瞧”这个字也有依赖的对象。

当然,关系依存分析,还有很多的规则,里面比较复杂,我不太感兴趣,所以这里不多写了。

下面我们来介绍如何让机器自动地帮我们来分析句子的结构。

传统的基于转移的依存分析(Transition-based Parsing)

这里主要介绍Nivre在2003年提出的“Greedy Deterministic Transition-Based Parsing”方法,一度成为依存分析的标准方法。这里我简单地介绍一下它的工作原理。

我们构造一个三元组,分别是Stack、Buffer和一个Dependency Set。

  • Stack最开始只存放一个Root节点;
  • Buffer则装有我们需要解析的一个句子;
  • Set中则保存我们分析出来的依赖关系,最开始是空的。

我们要做的事情,就是不断地把Buffer中的词往Stack中推,跟Stack中的词判断是否有依赖关系,有的话则输出到Set中,直到Buffer中的词全部推出,Stack中也仅剩一个Root,就分析完毕了。

下面,我通过一个十分简单的例子,来演示这个过程。这次,我们分析的句子是:

分析的过程如下:

上面的过程怎么理解呢?比方从第二行,这个时候Stack中只有[Root,I],不构成依赖关系,所以我们需要从Buffer中“进货”了,因此采取的Action是Shift(把Buffer中的首个词,移动到Stack中),于是就到了第三行。

第三行,我们的Stack变成了[Root,I,love],其中I和Love构成了依赖关系,且是Love指向I,即“向左指”的依赖关系,因此我们将采取“Left Arc”的action,把被依赖的词(此时就是关系中的左边的词)给移除Stack,把这个关系给放入到Dependency Set中。

按照这样的方法,我们一直进行,不断地根据Stack和Buffer的情况,来从Shift、Left-arc、Right-arc三种动作中选择我们下一步应该怎么做,知道Stack中只剩一个Root,Buffer也空了,这个时候,分析就结束,我们就得到了最终的Dependency Set。

以上的过程,应该不难理解,但是相信大家此时一定会有疑问:

❝我怎么让机器去决定当前的Action呢?即机器怎么知道,Stack中是否构成了依赖关系? ❞

在Nivre的年代,这里使用是机器学习的方法,需要做繁重的特征工程。这里的特征,往往有个二值特征,即无数个指示条件作为特征,来训练模型,可以想象这么高纬度的特征是十分稀疏的。因此,这种模型的95%左右的解析时间,都花费在计算特征上。这也是传统方法的最要问题。

神经依存分析(Neural Dependency Parsing)

神经依存分析方法,是斯坦福团队2014年的研究成果,主要就是利用了神经网络的方法代替了传统机器学习方法、用低维分布式表示来代替传统方法的复杂的高维稀疏特征表示。而整个解析的过程,依然是根据之前的Transition-based方法。

首先明确,我们的预测任务,是「根据当前的状态,即Stack、Buffer、Set的当前状态,来构建特征,然后预测出下一步的动作」

在神经依存分析中,我们的特征是怎么构建的呢?我们可以利用的信息包括词(word)、词性(pos tag)和依赖关系的标签(label)。我们对这三者,都进行低维分布式表示,即通过Embedding的方法,把离散的word、label、tag都转化成低维向量表示。

对于一个状态,我们可以选取stack、Buffer、set中的某些词和关系,构成一个集合,然后把他们所有的embedding向量都拼接起来,这样就构成了该状态的特征表示。

至于选择哪些词、关系,这个就是一个「经验性」的东西了,在斯坦福的论文中可以详细了解。整个模型的网络结构也十分简洁:

A Fast and Accurate Dependency Parser using Neural Networks

对于Dependency Parsing的简单介绍就到此为止。依存分析,并不是我们NLP中最常见的任务之一,我们也很少看到直接将依存分析做应用的,我们更常见的是分类、实体识别、阅读理解、对话等任务。但是依存分析,作为自然语言处理的一项基础技术,试图让机器去理解语言的内部结构,理解了结构,NLU(Natural Language Understanding)才成为可能。


cs224n的Assignment3就是Neural Dependency Parsing的实现,代码见github:

https://github.com/beyondguo/CS224n-notes-and-codes/tree/master/assignment3

本文分享自微信公众号 - SimpleAI(SimpleAI_1),作者:郭必扬

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【Embedding】fastText:极快的文本分类工具

    今天我们来看 Mikolov 大佬 2016 年的另一大巨作——fastText。2013 年大佬在 Google 开源了 Word2Vec,2016 年刚就职...

    beyondGuo
  • PyTorch简明笔记[2]-Tensor的自动求导(AoutoGrad)

    构建深度学习模型的基本流程就是:搭建计算图,求得损失函数,然后计算损失函数对模型参数的导数,再利用梯度下降法等方法来更新参数。

    beyondGuo
  • 【DL碎片3】神经网络中的激活(Activation)函数及其对比

    从【DL笔记1】到【DL笔记N】以及【DL碎片】系列,是我学习深度学习一路上的点点滴滴的记录,是从Coursera网课、各大博客、论文的学习以及自己的实践中总结...

    beyondGuo
  • H3C交换机型号区分

    第一个5代表千兆交换机,如果是3代表千兆上行,百兆下行。如果是7代表高端箱式交换机。9代表核心箱式交换机

    py3study
  • P4:开创数据平面可编程时代

    现有的SDN解决方案将控制平面与转发平面分离,并为我们提供了控制平面的可编程能力。而事实上,目前通过软件编程实现的控制平面的功能,在传统的高级交换机和路由器上也...

    SDNLAB
  • leetcode-812-Largest Triangle Area

    chenjx85
  • Go 回答之如何阅读 Go 源码

    Go 的源码在安装包的 src/ 目录下。怎么看它的源码呢?直接看吧!没人教的情况下,只能自己撸了。当然,这种内容一般也不会有人教。

    波罗学
  • 如何创建Powershell持久隐蔽后门

    用户开机后每次运行特定的快捷方式文件时触发一段恶意的powershell 代码,原始应用程序仍然启动,原始图标保留,并且没有powershell.exe窗口弹出...

    FB客服
  • 【Go语言干货】从入门说起,你必须要知道的……

    Go作为专门为并发和大数据设计的语言,在编程界占据越来越重要的地位!不论是c/c++,php,java,重构首选语言就是Go~。就像ccmouse老师,在《20...

    用户3128938
  • 【Go 语言社区与】转-鲜为人知的Google go语言若干细节

    Google于不久前发布了一门全新的开源编程语言名为Go。Go语言的设计最早始于2007年9月,设计者包括Robert Griesemer, Rob Pike和...

    李海彬

扫码关注云+社区

领取腾讯云代金券