技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 算法 --> 漫话中文自动分词和语义识别(下):句法结构和语义结构

漫话中文自动分词和语义识别(下):句法结构和语义结构

浏览:3388次  出处信息

     这篇文章是漫话中文分词算法的续篇。在这里,我们将紧接着上一篇文章的内容继续探讨下去:如果计算机可以对一句话进行自动分词,它还能进一步整理句子的结构,甚至理解句子的意思吗?这两篇文章的关系十分紧密,因此,我把前一篇文章改名为了《漫话中文自动分词和语义识别(上)》,这篇文章自然就是它的下篇。我已经在很多不同的地方做过与这个话题有关的演讲了,在这里我想把它们写下来,和更多的人一同分享。

     什么叫做句法结构呢?让我们来看一些例子。“白天鹅在水中游”,这句话是有歧义的,它可能指的是“白天有一只鹅在水中游”,也可能指的是“有一只白天鹅在水中游”。不同的分词方案,产生了不同的意义。有没有什么句子,它的分词方案是唯一的,但也会产生不同的意思呢?有。比如“门没有锁”,它可能是指的“门没有被锁上”,也有可能是指的“门上根本就没有挂锁”。这个句子虽然只能切分成“门/没有/锁”,但由于“锁”这个词既有可能是动词,也有可能是名词,因而让整句话产生了不同的意思。有没有什么句子,它的分词方案是唯一的,并且每个词的词义也都不再变化,但整个句子仍然有歧义呢?有可能。看看这句话:“咬死了猎人的狗”。这句话有可能指的是“把猎人的狗咬死了”,也有可能指的是“一只咬死了猎人的狗”。这个歧义是怎么产生的呢?仔细体会两种不同的意思后,你会发现,句子中最底层的成分可以以不同的顺序组合起来,歧义由此产生。

         在前一篇文章中,我们看到了,利用概率转移的方法,我们可以有效地给一句话分词。事实上,利用相同的模型,我们也能给每一个词标注词性。更好的做法则是,我们直接把同一个词不同词性的用法当作是不同的词,从而把分词和词性标注的工作统一起来。但是,所有这样的工作都是对句子进行从左至右线性的分析,而句子结构实际上比这要复杂多了,它是这些词有顺序有层次地组合在一起的。计算机要想正确地解析一个句子,在分词和标注词性后,接下来该做的就是分析句法结构的层次。

     在计算机中,怎样描述一个句子的句法结构呢? 1957 年, Noam Chomsky 出版了《句法结构》一书,把这种语言的层次化结构用形式化的方式清晰地描述了出来,这也就是所谓的“生成语法”模型。这本书是 20 世纪为数不多的几本真正的著作之一,文字非常简练,思路非常明晰,震撼了包括语言学、计算机理论在内的多个领域。记得 Quora 上曾经有人问 Who are the best minds of the world today ,投出来的答案就是 Noam Chomsky 。

     随便取一句很长很复杂的话,比如“汽车被开车的师傅修好了”,我们总能至顶向下地一层层分析出它的结构。这个句子最顶层的结构就是“汽车修好了”。汽车怎么修好了呢?汽车被师傅修好了。汽车被什么样的师傅修好了呢?哦,汽车被开车的师傅修好了。当然,我们还可以无限地扩展下去,继续把句子中的每一个最底层的成分替换成更详细更复杂的描述,就好像小学语文中的扩句练习那样。这就是生成语法的核心思想。

     熟悉编译原理的朋友们可能知道“上下文无关文法”。其实,上面提到的扩展规则本质上就是一种上下文无关文法。例如,一个句子可以是“什么怎么样”的形式,我们就把这条规则记作

    句子 → 名词性短语+动词性短语

     其中,“名词性短语”指的是一个具有名词功能的成分,它有可能就是一个名词,也有可能还有它自己的内部结构。例如,它有可能是一个形容词性短语加上“的”再加上另一个名词性短语构成的,比如“便宜的汽车”;它还有可能是由“动词性短语+的+名词性短语”构成的,比如“抛锚了的汽车”;它甚至可能是由“名词性短语+的+名词性短语”构成的,比如“老师的汽车”。我们把名词性短语的生成规则也都记下来:

    名词性短语 → 名词

           名词性短语 → 形容词性短语+的+名词性短语

           名词性短语 → 动词性短语+的+名词性短语

           名词性短语 → 名词性短语+的+名词性短语

           ・・・・・・

     类似地,动词性短语也有诸多具体的形式:

    动词性短语 → 动词

           动词性短语 → 动词性短语+了

           动词性短语 → 介词短语+动词性短语

           ・・・・・・

     上面我们涉及到了介词短语,它也有自己的生成规则:

    介词短语 → 介词+名词性短语

           ・・・・・・

     我们构造句子的任务,也就是从“句子”这个初始结点出发,不断调用规则,产生越来越复杂的句型框架,然后从词库中选择相应词性的单词,填进这个框架里:

    

     而分析句法结构的任务,则是已知一个句子从左到右各词的词性,要反过来求出一棵满足要求的“句法结构树”。这可以用 Earley parser 来实现。

     这样看来,句法结构的问题似乎就已经完美的解决了。其实,我们还差得很远。生成语法有两个大问题。首先,句法结构正确的句子不见得都是好句子。 Chomsky 本人给出了一个经典的例子: Colorless green ideas sleep furiously 。形容词加形容词加名词加动词加副词,这是一个完全符合句法要求的序列,但随便拼凑会闹出很多笑话――什么叫做“无色的绿色的想法在狂暴地睡觉”?顺便插播个广告,如果你还挺喜欢这句话的意境的,欢迎去我以前做的 IdeaGenerator 玩玩。不过,如果我们不涉及句子的生成,只关心句子的结构分析,这个缺陷对我们来说影响似乎并不大。生成语法的第二个问题就比较麻烦了:从同一个词性序列出发,可能会构建出不同的句法结构树。比较下面两个例子:

    老师 被 迟到 的 学生 逗乐 了

           电话 被 窃听 的 房间 找到 了

     它们都是“名词+介词+动词+的+名词+动词+了”,但它们的结构并不一样,前者是老师被逗乐了,“迟到”是修饰“学生”的,后者是房间找到了,“电话被窃听”是一起来修饰房间的。但是,纯粹运用前面的模型,我们无法区分出哪句话应该是哪个句法结构树。如何强化句法分析的模型和算法,让计算机构建出一棵正确的句法树,这成了一个大问题。

     让我们来看一个更简单的例子吧。同样是“动词+形容词+名词”,我们有两种构建句法结构树的方案:

    

     未经过汉语语法训练的朋友可能会问,“点亮蜡烛”和“踢新皮球”的句法结构真的不同吗?我们能证明,这里面真的存在不同。我们造一个句子“踢破皮球”,你会发现对于这个句子来说,两种句法结构都是成立的,于是出现了歧义:把皮球踢破了(结构和“点亮蜡烛”一致),或者是,踢一个破的皮球(结构和“踢新皮球”一致)。

     但为什么“点亮蜡烛”只有一种理解方式呢?这是因为我们通常不会把“亮”字直接放在名词前做定语,我们一般不说“一根亮蜡烛”、“一颗亮星星”等等。为什么“踢新皮球”也只有一种理解方式呢?这是因为我们通常不会把“新”直接放在动词后面作补语,不会说“皮球踢新了”,“衣服洗新了”等等。但是“破”既能作定语又能作补语,于是“踢破皮球”就产生了两种不同的意思。如果我们把每个形容词能否作定语,能否作补语都记下来,然后在生成规则中添加限制条件,不就能完美解决这个问题了吗?

     基于规则的句法分析器就是这么做的。汉语语言学家们已经列出了所有词的各种特征:

    亮:词性 = 形容词,能作补语 = True ,能作定语 = False ・・・・・・

           新:词性 = 形容词,能作补语 = False ,能作定语 = True ・・・・・・

           ・・・・・・

     当然,每个动词也有一大堆属性:

    点:词性 = 动词,能带宾语 = True ,能带补语 = True ・・・・・・

           踢:词性 = 动词,能带宾语 = True ,能带补语 = True ・・・・・・

           污染:词性 = 动词,能带宾语 = True ,能带补语 = False ・・・・・・

           排队:词性 = 动词,能带宾语 = False ,能带补语 = False ・・・・・・

           ・・・・・・

     名词也不例外:

    蜡烛:词性 = 名词,能作主语 = True ,能作宾语 = True ,能受数量词修饰 = True ・・・・・・

           皮球:词性 = 名词,能作主语 = True ,能作宾语 = True ,能受数量词修饰 = True ・・・・・・

           ・・・・・・

     有人估计会觉得奇怪了:“能作主语”也是一个属性,莫非有些名词不能做主语?哈哈,这样的名词不但有,而且还真不少:剧毒、看头、厉害、正轨、存亡・・・・・・这些词都不放在动词前面。难道有些名词不能做宾语吗?这样的词也有不少:享年、芳龄、心术、浑身、家丑・・・・・・这些词都不放在动词后面。这样说来,存在不受数量词修饰的词也就不奇怪了,事实上上面这些怪异的名词前面基本上都不能加数量词。

     另外一个至关重要的就是,这些性质可以“向上传递”。比方说,我们规定,套用规则

    名词性短语 → 形容词性短语+名词性短语

     后,整个名词性短语能否作主语、能否作宾语、能否受数量词修饰,这将取决于它的第二个构成成分。通俗地讲就是,如果“皮球”能够作主语,那么“新皮球”也能够作主语。有了“词语知识库”,又确保了这些知识能够在更高层次得到保留,我们就能给语法生成规则添加限制条件了。例如,我们可以规定,套用规则

    动词性短语 → 动词性短语+名词性短语

     的前提条件就是,那个动词性短语的“能带宾语”属性为 True ,并且那个名词性短语“能作宾语”的属性为 True 。另外,我们规定

    动词性短语 → 动词性短语+形容词性短语

     必须满足动词性短语的“能带补语”属性为 True ,并且形容词性短语“能作补语”属性为 True 。这样便阻止了“踢新皮球”中的“踢”和“新”先结合起来,因为“新”不能作补语。

     最后我们规定,套用规则

    名词性短语 → 形容词性短语+名词性短语

     时,形容词性短语必须要能作定语。这就避免了“点亮蜡烛”中的“亮”和“蜡烛”先组合起来,因为“亮”通常不作定语。这样,我们便解决了“动词+形容词+名词”的结构分析问题。

     当然,这只是一个很简单的例子。在这里的问题 6 、 7 、 8 中你可以看到,一条语法生成规则往往有很多限制条件,这些限制条件不光是简单的“功能相符”和“前后一致”,有些复杂的限制条件甚至需要用 IF … THEN … 的方式来描述。你可以在这里看到,汉语中词与词之间还有各种怪异的区别特征,并且哪个词拥有哪些性质纯粹是知识库的问题,完全没有规律可循。一个实用的句法结构分析系统,往往拥有上百种属性标签。北京大学计算语言所编写了《现代汉语语法信息词典》,它里面包含了 579 种属性。我们的理想目标就是,找到汉语中每一种可能会影响句法结构的因素,并据此为词库里的每一个词打上标签;再列出汉语语法中的每一条生成规则,找到每一条生成规则的应用条件,以及应用这条规则之后,整个成分将会以怎样的方式继承哪些子成分的哪些属性,又会在什么样的情况下产生哪些新的属性。按照生成语言学的观点,计算机就应该能正确解析所有的汉语句子了。

      

         那么,这样一来,计算机是否就已经能从句子中获取到理解语义需要的所有信息了呢?答案是否定的。还有这么一些句子,它从分词到词义到结构都没有两可的情况,但整个句子仍然有歧义。考虑这句话“鸡不吃了”,它有两种意思:鸡不吃东西了,或者我们不吃鸡了。但是,这种歧义并不是由分词或者词义或者结构导致的,两种意思所对应的语法结构完全相同,都是“鸡”加上“不吃了”。但为什么歧义仍然产生了呢?这是因为,在句法结构内部,还有更深层次的语义结构,两者并不相同。

     汉语就是这么奇怪,位于主语位置上的事物既有可能是动作的发出者,也有可能是动作的承受者。“我吃完了”可以说,“苹果吃完了”也能讲。然而,“鸡”这个东西既能吃,也能被吃,歧义由此产生。

     位于宾语位置上的事物也不一定就是动作的承受者,“来客人了”、“住了一个人”都是属于宾语反而是动作发出者的情况。记得某次数理逻辑课上老师感叹,汉语的谓词非常不规范,明明是太阳在晒我,为什么要说成是“我晒太阳”呢?事实上,汉语的动宾搭配范围极其广泛,还有很多更怪异的例子:“写字”是我们真正在写的东西,“写书”是写的结果,“写毛笔”是写的工具,“写楷体”是写的方式,“写地上”是写的场所,“写一只狗”,等等,什么叫做“写一只狗”啊?我们能说“写一只狗”吗?当然可以,这是写的内容嘛,“同学们这周作文写什么啊”,“我写一只狗”。大家可以想像,学中文的老外看了这个会是什么表情。虽然通过句法分析,我们能够判断出句子中的每样东西都和哪个动词相关联,但从语义层面上看这个关联是什么,我们还需要新的模型。

     汉语语言学家把事物与动词的语义关系分为了 17 种,叫做 17 种“语义角色”,它们是施事、感事、当事、动力、受事、结果、系事、工具、材料、方式、内容、与事、对象、场所、目标、起点、时间。你可以看到,语义角色的划分非常详细。同样是动作的发出者,施事指的是真正意义上的发出动作,比如“他吃饭”中的“他”;感事则是指某种感知活动的经验者,比如“他知道这件事了”中的“他”;当事则是指性质状态的主体,比如“他病了”中的“他”;动力则是自然力量的发出者,比如“洪水淹没了村庄”中的“洪水”。语义角色的具体划分以及 17 这个数目是有争议的,不过不管怎样,这个模型本身能够非常贴切地回答“什么是语义”这个问题。

     汉语有一种“投射理论”,即一个句子的结构是由这个句子中的谓语投射出来的。给定一个动词后,这个动词能够带多少个语义角色,这几个语义角色都是什么,基本上都已经确定了。因而,完整的句子所应有的结构实际上也就已经确定了。比如,说到“休息”这个动词,你就会觉得它缺少一个施事,而且也不缺别的了。我们只会说“老王休息”,不会说“老王休息手”或者“老王休息沙发”。因而我们认为,“休息”只有一个“论元”。它的“论元结构”是:

    休息

     因此,一旦在句子中看到“休息”这个词,我们就需要在句内或者句外寻找“休息”所需要的施事。这个过程有一个很帅的名字,叫做“配价”。“休息”就是一个典型的“一价动词”。我们平时接触的比较多的则是二价动词。不过,它们具体的论元有可能不一样:

    吃

           去

           淹没

     三价动词也是有的,例如

    送

     甚至还有零价动词,例如

    下雨

     下面我们要教计算机做的,就是怎样给动词配价。之前,我们已经给出了解析句法结构的方法,这样计算机便能判断出每个动词究竟在和哪些词发生关系。语义分析的实质,就是确定出它们具体是什么关系。因此,语义识别的问题,也就转化为了“语义角色标注”的问题。然而,语义角色出现的位置并不固定,施事也能出现在动词后面,受事也能出现在动词前面,怎样让计算机识别语义角色呢?在回答这个问题之前,我们不妨问问自己:我们是怎么知道,“我吃完了”中的“我”是“吃”的施事,“苹果吃完了”中的“苹果”是“吃”的受事的呢?大家肯定会说,废话,“我”当然只能是“吃”的施事,因为我显然不会“被吃”;“苹果”当然只能是“吃”的受事,因为苹果显然不能发出“吃”动作。也就是说,“吃”的两个论元都有语义类的要求。我们把“吃”的论元结构写得更详细一些:

    吃

    而“淹没”一词的论元结构则可以补充为:

    淹没

     所以,为了完成计算机自动标注语义角色的任务,我们需要人肉建立两个庞大的数据库:语义类词典和论元结构词典。这样的人肉工程早就已经做过了。北京语言大学 1990 年 5 月启动的“九

建议继续学习:

  1. 一个简单的中文分词程序    (阅读:4468)
  2. 漫话中文分词算法    (阅读:3927)
  3. 腾讯php程序员面试题目答案――编程任务    (阅读:3196)
  4. 基于trie数据字典的php中文分词    (阅读:2994)
  5. Levenshtein distance相似度算法    (阅读:3001)
  6. 排头兵PHP中文分词,纯PHP版实现    (阅读:2638)
  7. Mysql+sphinx+中文分词简介(ubuntu)    (阅读:2293)
  8. Mysql+sphinx+中文分词简介(ubuntu)    (阅读:1921)
  9. 利用新词统计特征进行中文分词    (阅读:1510)
  10. 用MeCab打造一套实用的中文分词系统    (阅读:1124)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1