放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

提取中文句子主谓宾的Java实现

目录

在自然语境中,一个意思可以有多种表现。比如“我喜欢你”“我喜欢隔壁班的你”“你被我偷偷的喜欢着”都表达了“我喜欢你”。搜索引擎如果机械地按照词频算法检索的话,会误解为“我喜欢隔壁班”“你喜欢我”,毕竟词频一样,顺序也差不多。

利用依存关系可以提取句子的主要成分(也就是小学和公务员考试中出现的“提取主干”),可以实现语义上的智能理解。在中文里,我的感受是,大部分句子都有主谓宾,很少缺主语或宾语,三个全缺的几乎没有。所以我猜可以利用主谓宾短语来作为句子的主干,检索的时候主干匹配的话则给予更高的分数,或者用于智能推荐。

开源项目

收到了开源的请求,于是将其开源在Github上:https://github.com/hankcs/MainPartExtractor

请使用Maven编译,会自动下载依赖jar。

对斯坦福的代码失去兴趣,不再维护!

事实上,句法分析和语义理解是个深刻的命题,并不是我这一两个Class可以解决清楚的。而且目前中文句法分析的准确率只有80%左右,在真实语境中的准确率更低。所以能否将其用于生产环境,还请各位读者自己衡量。

本项目的句法分析依赖于Stanford Parser实现,一般来说,大学做的东西都是服务于论文。只要论文上的准确率高出一两个百分点,牺牲再多的性能,再多的可读性都无所谓。我认为,真正要将语义分析导入商用应用,现在还为时过早,这篇文章和这个项目可做尝鲜。

测试用例

 String[] testCaseArray = {
                "我一直很喜欢你",
                "你被我喜欢",
                "美丽又善良的你被卑微的我深深的喜欢着……",
                "只有自信的程序员才能把握未来",
                "主干识别可以提高检索系统的智能",
                "这个项目的作者是hankcs",
                "hankcs是一个无门无派的浪人",
                "搜索hankcs可以找到我的博客",
                "静安区体育局2013年部门决算情况说明",
        };

这里仅仅以一个被字句“你被我喜欢”为例说明。注意句子应当是单句,不含逗号等分句标点。

分词

分词没什么可说的,停用词也不用费心。

分词结果为:你 被 我 喜欢

句法树(依存关系)分析

这里可以利用开源项目Stanford Parser,得到如下结果:

句法树:(ROOT [28.316]
  (IP
    (NP (PN 你))
    (VP (LB 被)
      (IP
        (NP (PN 我))
        (VP (VV 喜欢))))))

画成图是这个样子:

同时得到依存关系:

依存关系:[nsubjpass(喜欢-4, 你-1), pass(喜欢-4, 被-2), nsubj(喜欢-4, 我-3), root(ROOT-0, 喜欢-4)]

其中root表示中心词,nsubjpass表示被动的名词主语,nsubj表示名词主语。更加详细的标签含义可以查看附录。有了依存关系之后,就可以判断谁是主语谁是宾语了。

测试结果:

我一直很喜欢你 我喜欢你
你被我喜欢 我喜欢你
美丽又善良的你被卑微的我深深的喜欢着…… 我喜欢你
只有自信的程序员才能把握未来 程序员把握未来
主干识别可以提高检索系统的智能 主干识别提高智能
这个项目的作者是hankcs 作者是hankcs
hankcs是一个无门无派的浪人 hankcs是浪人
搜索hankcs可以找到我的博客 搜索hankcs找博客
静安区体育局2013年部门决算情况说明 决算情况说明

附录

ROOT:要处理文本的语句

IP:简单从句
NP:名词短语
VP:动词短语
PU:断句符,通常是句号、问号、感叹号等标点符号
LCP:方位词短语
PP:介词短语
CP:由‘的’构成的表示修饰性关系的短语
DNP:由‘的’构成的表示所属关系的短语
ADVP:副词短语
ADJP:形容词短语
DP:限定词短语
QP:量词短语
NN:常用名词
NR:固有名词
NT:时间名词
PN:代词
VV:动词
VC:是
CC:表示连词
VE:有
VA:表语形容词
AS:内容标记(如:了)
VRD:动补复合词
CD: 表示基数词
DT: determiner 表示限定词
EX: existential there 存在句
FW: foreign word 外来词
IN: preposition or conjunction, subordinating 介词或从属连词
JJ: adjective or numeral, ordinal 形容词或序数词
JJR: adjective, comparative 形容词比较级
JJS: adjective, superlative 形容词最高级
LS: list item marker 列表标识
MD: modal auxiliary 情态助动词
PDT: pre-determiner 前位限定词
POS: genitive marker 所有格标记
PRP: pronoun, personal 人称代词
RB: adverb 副词
RBR: adverb, comparative 副词比较级
RBS: adverb, superlative 副词最高级
RP: particle 小品词 
SYM: symbol 符号
TO:”to” as preposition or infinitive marker 作为介词或不定式标记 
WDT: WH-determiner WH限定词
WP: WH-pronoun WH代词
WP$: WH-pronoun, possessive WH所有格代词
WRB:Wh-adverb WH副词
 
关系表示
abbrev: abbreviation modifier,缩写
acomp: adjectival complement,形容词的补充;
advcl : adverbial clause modifier,状语从句修饰词
advmod: adverbial modifier状语
agent: agent,代理,一般有by的时候会出现这个
amod: adjectival modifier形容词
appos: appositional modifier,同位词
attr: attributive,属性
aux: auxiliary,非主要动词和助词,如BE,HAVE SHOULD/COULD等到
auxpass: passive auxiliary 被动词
cc: coordination,并列关系,一般取第一个词
ccomp: clausal complement从句补充
complm: complementizer,引导从句的词好重聚中的主要动词
conj : conjunct,连接两个并列的词。
cop: copula。系动词(如be,seem,appear等),(命题主词与谓词间的)连系
csubj : clausal subject,从主关系
csubjpass: clausal passive subject 主从被动关系
dep: dependent依赖关系
det: determiner决定词,如冠词等
dobj : direct object直接宾语
expl: expletive,主要是抓取there
infmod: infinitival modifier,动词不定式
iobj : indirect object,非直接宾语,也就是所以的间接宾语;
mark: marker,主要出现在有“that” or “whether”“because”, “when”,
mwe: multi-word expression,多个词的表示
neg: negation modifier否定词
nn: noun compound modifier名词组合形式
npadvmod: noun phrase as adverbial modifier名词作状语
nsubj : nominal subject,名词主语
nsubjpass: passive nominal subject,被动的名词主语
num: numeric modifier,数值修饰
number: element of compound number,组合数字
parataxis: parataxis: parataxis,并列关系
partmod: participial modifier动词形式的修饰
pcomp: prepositional complement,介词补充
pobj : object of a preposition,介词的宾语
poss: possession modifier,所有形式,所有格,所属
possessive: possessive modifier,这个表示所有者和那个’S的关系
preconj : preconjunct,常常是出现在 “either”, “both”, “neither”的情况下
predet: predeterminer,前缀决定,常常是表示所有
prep: prepositional modifier
prepc: prepositional clausal modifier
prt: phrasal verb particle,动词短语
punct: punctuation,这个很少见,但是保留下来了,结果当中不会出现这个
purpcl : purpose clause modifier,目的从句
quantmod: quantifier phrase modifier,数量短语
rcmod: relative clause modifier相关关系
ref : referent,指示物,指代
rel : relative
root: root,最重要的词,从它开始,根节点
tmod: temporal modifier
xcomp: open clausal complement
xsubj : controlling subject 掌控者

中心语为谓词
  subj — 主语
 nsubj — 名词性主语(nominal subject) (同步,建设)
   top — 主题(topic) (是,建筑)
npsubj — 被动型主语(nominal passive subject),专指由“被”引导的被动句中的主语,一般是谓词语义上的受事 (称作,镍)
 csubj — 从句主语(clausal subject),中文不存在
 xsubj — x主语,一般是一个主语下面含多个从句 (完善,有些)

中心语为谓词或介词   
   obj — 宾语
  dobj — 直接宾语 (颁布,文件)
  iobj — 间接宾语(indirect object),基本不存在
 range — 间接宾语为数量词,又称为与格 (成交,元)
  pobj — 介词宾语 (根据,要求)
  lobj — 时间介词 (来,近年)

中心语为谓词
  comp — 补语
 ccomp — 从句补语,一般由两个动词构成,中心语引导后一个动词所在的从句(IP) (出现,纳入)
 xcomp — x从句补语(xclausal complement),不存在   
 acomp — 形容词补语(adjectival complement)
 tcomp — 时间补语(temporal complement) (遇到,以前)
lccomp — 位置补语(localizer complement) (占,以上)
       — 结果补语(resultative complement)

中心语为名词
   mod — 修饰语(modifier)
  pass — 被动修饰(passive)
  tmod — 时间修饰(temporal modifier)
 rcmod — 关系从句修饰(relative clause modifier) (问题,遇到)
 numod — 数量修饰(numeric modifier) (规定,若干)
ornmod — 序数修饰(numeric modifier)
   clf — 类别修饰(classifier modifier) (文件,件)
  nmod — 复合名词修饰(noun compound modifier) (浦东,上海)
  amod — 形容词修饰(adjetive modifier) (情况,新)
advmod — 副词修饰(adverbial modifier) (做到,基本)
  vmod — 动词修饰(verb modifier,participle modifier)
prnmod — 插入词修饰(parenthetical modifier)
   neg — 不定修饰(negative modifier) (遇到,不)
   det — 限定词修饰(determiner modifier) (活动,这些)
 possm — 所属标记(possessive marker),NP
  poss — 所属修饰(possessive modifier),NP
  dvpm — DVP标记(dvp marker),DVP (简单,的)
dvpmod — DVP修饰(dvp modifier),DVP (采取,简单)
  assm — 关联标记(associative marker),DNP (开发,的)
assmod — 关联修饰(associative modifier),NP|QP (教训,特区)
  prep — 介词修饰(prepositional modifier) NP|VP|IP(采取,对)
 clmod — 从句修饰(clause modifier) (因为,开始)
 plmod — 介词性地点修饰(prepositional localizer modifier) (在,上)
   asp — 时态标词(aspect marker) (做到,了)
partmod– 分词修饰(participial modifier) 不存在
   etc — 等关系(etc) (办法,等)

中心语为实词
  conj — 联合(conjunct)
   cop — 系动(copula) 双指助动词????
    cc — 连接(coordination),指中心词与连词 (开发,与)

其它
  attr — 属性关系 (是,工程)
cordmod– 并列联合动词(coordinated verb compound) (颁布,实行)
  mmod — 情态动词(modal verb) (得到,能)
    ba — 把字关系
tclaus — 时间从句 (以后,积累)
       — semantic dependent
   cpm — 补语化成分(complementizer),一般指“的”引导的CP (振兴,的)

Reference

http://nlp.stanford.edu/nlp/javadoc/javanlp/overview-summary.html

http://blog.csdn.net/cuixianpeng/article/details/16864785

http://blog.csdn.net/tanzhangwen/article/details/8262049

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » 提取中文句子主谓宾的Java实现

评论 31

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #15

    博主,我看你的代码中用到了Stanford的库,请问怎么训练自己的模型库呢?

    tianyunzqs8年前 (2016-09-06)回复
  2. #14

    hanks: 你还在维护这个项目吗?从GitHub下载的maven项目怎么是一个Java web的项目吖?

    杨学锋-norvar8年前 (2016-03-25)回复
    • 不维护了,斯坦福的库也就那样

      hankcs8年前 (2016-04-08)回复
  3. #13

    这个有python版本的吗?

    mothe1238年前 (2015-12-29)回复
  4. #12

    句法和依存关系列表一个增加一个修改哦
    nummod — 数量修饰(numeric modifier) (规定,若干) 不是numod
    UCP:异体同位语

    另外 stanford这个包句法树还挺准,但是依存关系在提取时候有问题,一些同位语短语分解时候,中心语会定位到非谓语上,很奇怪,研究源码ing

    欧几里德的猫8年前 (2015-12-15)回复
    • 经分析,仿佛VC是cop特性的,都是root都是宾语,所以赶脚把root词直接当成谓语是不合适的

      欧几里德的猫8年前 (2015-12-16)回复
      • 这个问题我也遇到了,感觉有些把宾语成了root,之后直接把root当初谓语,就出问题了,请问你有什么好方法没?

        tianyunzqs8年前 (2016-09-06)回复
  5. #11

    感觉stanford的这个包,在处理句法树时候还是很准的,就是依存文法在处理同位语或者其他类似非标语句时候会出现很多错误,比如中心语定位在非谓语上,这个很奇怪,正在研究源码中

    欧几里德的猫8年前 (2015-12-15)回复
  6. #10

    帮楼主补充一个句法 一个依存关系备注咯
    句法
    UCP:异体同位语
    依存关系
    nummod — 数量修饰(numeric modifier) (规定,若干) 不是numod

    欧几里德的猫8年前 (2015-12-15)回复
  7. #9

    请问这个需要自己维护词库吗

    闫他9年前 (2015-05-25)回复
  8. #8

    给位大神们,我运行之后出现了:Exception in thread "main" java.lang.NullPointerException
    at MainPartExtractor.getMainPart(MainPartExtractor.java:61)
    at MainPartExtractor.getMainPart(MainPartExtractor.java:48)
    at MainPartExtractor.main(MainPartExtractor.java:253)
    。这是什么问题?求大神指点。

    9年前 (2015-03-28)回复
  9. #7

    我这边也无法编译,不知道是不是maven配置的不对。求大神指点。

    小凯9年前 (2015-03-26)回复
  10. #6

    我这边也不行,能不能发个eclipse工程?

    冯文政9年前 (2015-03-26)回复
    • 你好,你是出现了什么问题?

      9年前 (2015-03-26)回复
      • 之前可能是maven没配置好,现在好了,我直接把代码考进了一个工程里,发现了一些stanfordparser的方法已经过时了。

        冯文政9年前 (2015-03-27)回复
        • 你好,可能分享一下代码呢?题主的github上的代码好像不全了,能否发我一份呢?我的邮箱:839624435@qq.com 谢谢

          张蕊5年前 (2019-03-30)回复
  11. #5

    我这边 编译不行。。。

    柚子眼9年前 (2015-03-13)回复
  12. #4

    能留个邮箱交流下么?

    刘yun10年前 (2014-12-01)回复
  13. #3

    你好!,可以把你实现这里的代码共享看一下么?

    刘yun10年前 (2014-12-01)回复
  14. #2

    能不能说明白些,是怎么获取主谓宾的呀,我怎么看不太懂,请多多指教

    Mr.Wang10年前 (2014-11-05)回复
    • 请参考Stanford Parser的主页及文档

      hankcs10年前 (2014-11-19)回复
  15. #1

    我在中二的想能不能用这种主干分析做一个自然语言->编程语言的解释器=w=

    小泣喵喵咪10年前 (2014-09-14)回复
    • 这是未来的发展方向吧,不过自然语言太灵活了,比如未来有一天,小明对机器人说想得到小红的芳心,第二天小红卒……

      hankcs10年前 (2014-09-14)回复

我的作品

HanLP自然语言处理包《自然语言处理入门》