R语言自然语言处理:词性标注与命名实体识别

栏目: R语言 · 发布时间: 5年前

R语言自然语言处理:词性标注与命名实体识别

作者: 黄天元 ,复旦大学博士在读,目前研究涉及文本挖掘、社交网络分析和机器学习等。希望与大家分享学习经验,推广并加深R语言在业界的应用。

邮箱:huang.tian-yuan@qq.com

原理简介

在之前的文章中( R语言自然语言处理:中文分词 )介绍了如何利用jiebaR来做中文分词,这次希望研究如果利用R语言来做词性标注,并利用标注来做命名实体识别。 首先需要明确词性标注的概念,就是要把中文分词后的每一个词,确定其性质。是名词?动词?还是形容词?如果是名词,是人名、地名还是机构团体名称?对这些词性进行更为细致的标注,有助于我们对信息进行提取(有的时候动词和形容词其实不包含我们感兴趣的信息,但是名词却非常重要)。此外,也有利于我们了解作者的用词习惯(这个时候,名词又不一定重要了,一个人的行文习惯可以体现在他经常用的动词和形容词)。 因为我们是用jiebaR来做分词,根据官方文档说明,它的标注是根据北大《人民日报》语料库进行训练的,最后的标准整理为ICTPOS3.0词性标记集,内容如下:

名词     nr 人名         nr1 汉语姓氏         nr2 汉语名字         nrj 日语人名         nrf 音译人名     ns 地名      nsf 音译地名     nt 机构团体名     nz 其它专名     nl 名词性惯用语     ng 名词性语素时间词   tg 时间词性语素处所词方位词动词     vd 副动词     vn 名动词     vshi 动词“是”     vyou 动词“有”     vf 趋向动词     vx 形式动词     vi 不及物动词(内动词)     vl 动词性惯用语     vg 动词性语素形容词     ad 副形词     an 名形词     ag 形容词性语素     al 形容词性惯用语区别词     bl 区别词性惯用语状态词代词     rr 人称代词     rz 指示代词         rzt 时间指示代词         rzs 处所指示代词         rzv 谓词性指示代词     ry 疑问代词         ryt 时间疑问代词         rys 处所疑问代词         ryv 谓词性疑问代词     rg 代词性语素数词     mq 数量词量词     qv 动量词     qt 时量词 

词性标注实践

话不多说,我们上代码来做词性标注分析。需要注意的是,我们要做词性标注的输入,既可以是一大段没有经过分词处理字符串,也可以是已经分词完毕的分词结果(也就是字符向量)。我们先介绍第一种情况,就是没有经过分词的大段字符串,要完成分词,然后对每个词都进行词性标注。

 1library(pacman)  2p_load(jiebaR,tidyverse)  3  4cn = "我想写一本书,名字叫做《R语言高效数据处理》。"   #构造中文文本  5tag_worker = worker(type = "tag")    #构造分词标注器  6  7tag_result = tagging(cn,tag_worker)   #进行分词标注  8  9tag_result            #查看结果 10##          r          v          v          m          r          n  11##       "我"       "想"       "写"       "一"     "本书"     "名字"  12##          v        eng          a          n  13##     "叫做"    "R语言"     "高效" "数据处理" 

我们得到的tag_result实质上是一个带属性的向量,这样其实不是特别好用。因此我要把它变成数据框的格式,方便以后利用。

 1str(tag_result)  #查看数据类型  2##  Named chr [1:10] "我" "想" "写" "一" "本书" "名字" "叫做" "R语言" ...  3##  - attr(*, "names")= chr [1:10] "r" "v" "v" "m" ...  4enframe(tag_result) -> tag_table  #转换数据存储格式  5  6tag_table  7## # A tibble: 10 x 2  8##    name  value     9##    <chr> <chr>    10##  1 r     我       11##  2 v     想       12##  3 v     写       13##  4 m     一       14##  5 r     本书     15##  6 n     名字     16##  7 v     叫做     17##  8 eng   R语言    18##  9 a     高效     19## 10 n     数据处理 

其实这里分词效果还不是那么尽如人意,因为“本书”应该分为“本”、“书”,而这里被认定为代词,指代之前提过的一本书(然而我并没有指代任何词)。不过大体来说还算满意。注意“R语言”之所以能够被分出来,是因为我上次处理加了用户词库,因此这次自动地进行了识别。如果大家没有把“R语言”加入到用户自定义词库中,你们看到的应该是“R”、“语言”。关于如何定义用户词库,见上一篇文章 R语言自然语言处理: 中文分词 。 如果已经分词完毕,需要对这些词进行词性标注,可以使用vector_tag函数。我们先按照正常流程进行分词:

1#正常分词流程 2 3worker() -> wk 4segment(cn,wk) -> seg_cn 5 6seg_cn 7##  [1] "我"       "想"       "写"       "一"       "本书"     "名字"     8##  [7] "叫做"     "R语言"    "高效"     "数据处理" 

然后我们利用函数进行标注。

1vector_tag(seg_cn,tag_worker) 2##          r          v          v          m          r          n  3##       "我"       "想"       "写"       "一"     "本书"     "名字"  4##          v        eng          a          n  5##     "叫做"    "R语言"     "高效" "数据处理" 

这个结构与我们上面得到的tag_result是一致的。

命名实体识别尝试

现在我们尝试用词性标注的方法来进行命名实体识别。我们的目的是:对于既定的一套字符串,我们希望得到里面的名词,因为我们认为它会代表一些实际的实体对象。我非常喜欢一篇文章,是王小波的《一只特立独行的猪》,原谅我的任性,我要把这篇文章直接放在这里作为我们的中文语料对象。

1cn = "插队的时候,我喂过猪、也放过牛。假如没有人来管,这两种动物也完全知道该怎样生活。它们会自由自在地闲逛,饥则食渴则饮,春天来临时还要谈谈爱情;这样一来,它们的生活层次很低,完全乏善可陈。人来了以后,给它们的生活做出了安排:每一头牛和每一口猪的生活都有了主题。就它们中的大多数而言,这种生活主题是很悲惨的:前者的主题是干活,后者的主题是长肉。我不认为这有什么可抱怨的,因为我当时的生活也不见得丰富了多少,除了八个样板戏,也没有什么消遣。有极少数的猪和牛,它们的生活另有安排。以猪为例,种猪和母猪除了吃,还有别的事可干。就我所见,它们对这些安排也不大喜欢。种猪的任务是交配,换言之,我们的政策准许它当个花花公子。但是疲惫的种猪往往摆出一种肉猪(肉猪是阉过的)才有的正人君子架势,死活不肯跳到母猪背上去。母猪的任务是生崽儿,但有些母猪却要把猪崽儿吃掉。总的来说,人的安排使猪痛苦不堪。但它们还是接受了:猪总是猪啊。 2对生活做种种设置是人特有的品性。不光是设置动物,也设置自己。我们知道,在古希腊有个斯巴达,那里的生活被设置得了无生趣,其目的就是要使男人成为亡命战士,使女人成为生育机器,前者像些斗鸡,后者像些母猪。这两类动物是很特别的,但我以为,它们肯定不喜欢自己的生活。但不喜欢又能怎么样?人也好,动物也罢,都很难改变自己的命运。 3以下谈到的一只猪有些与众不同。我喂猪时,它已经有四五岁了,从名分上说,它是肉猪,但长得又黑又瘦,两眼炯炯有光。这家伙像山羊一样敏捷,一米高的猪栏一跳就过;它还能跳上猪圈的房顶,这一点又像是猫——所以它总是到处游逛,根本就不在圈里呆着。所有喂过猪的知青都把它当宠儿来对待,它也是我的宠儿——因为它只对知青好,容许他们走到三米之内,要是别的人,它早就跑了。它是公的,原本该劁掉。不过你去试试看,哪怕你把劁猪刀藏在身后,它也能嗅出来,朝你瞪大眼睛,噢噢地吼起来。我总是用细米糠熬的粥喂它,等它吃够了以后,才把糠对到野草里喂别的猪。其他猪看了嫉妒,一起嚷起来。这时候整个猪场一片鬼哭狼嚎,但我和它都不在乎。吃饱了以后,它就跳上房顶去晒太阳,或者模仿各种声音。它会学汽车响、拖拉机响,学得都很像;有时整天不见踪影,我估计它到附近的村寨里找母猪去了。我们这里也有母猪,都关在圈里,被过度的生育搞得走了形,又脏又臭,它对它们不感兴趣;村寨里的母猪好看一些。它有很多精彩的事迹,但我喂猪的时间短,知道得有限,索性就不写了。总而言之,所有喂过猪的知青都喜欢它,喜欢它特立独行的派头儿,还说它活得潇洒。但老乡们就不这么浪漫,他们说,这猪不正经。领导则痛恨它,这一点以后还要谈到。我对它则不止是喜欢——我尊敬它,常常不顾自己虚长十几岁这一现实,把它叫做“猪兄”。如前所述,这位猪兄会模仿各种声音。我想它也学过人说话,但没有学会——假如学会了,我们就可以做倾心之谈。但这不能怪它。人和猪的音色差得太远了。 4后来,猪兄学会了汽笛叫,这个本领给它招来了麻烦。我们那里有座糖厂,中午要鸣一次汽笛,让工人换班。我们队下地干活时,听见这次汽笛响就收工回来。我的猪兄每天上午十点钟总要跳到房上学汽笛,地里的人听见它叫就回来——这可比糖厂鸣笛早了一个半小时。坦白地说,这不能全怪猪兄,它毕竟不是锅炉,叫起来和汽笛还有些区别,但老乡们却硬说听不出来。领导上因此开了一个会,把它定成了破坏春耕的坏分子,要对它采取专政手段——会议的精神我已经知道了,但我不为它担忧——因为假如专政是指绳索和杀猪刀的话,那是一点门都没有的。以前的领导也不是没试过,一百人也治不住它。狗也没用:猪兄跑起来像颗鱼雷,能把狗撞出一丈开外。谁知这回是动了真格的,指导员带了二十几个人,手拿五四式手枪;副指导员带了十几人,手持看青的火枪,分两路在猪场外的空地上兜捕它。这就使我陷入了内心的矛盾:按我和它的交情,我该舞起两把杀猪刀冲出去,和它并肩战斗,但我又觉得这样做太过惊世骇俗——它毕竟是只猪啊;还有一个理由,我不敢对抗领导,我怀疑这才是问题之所在。总之,我在一边看着。猪兄的镇定使我佩服之极:它很冷静地躲在手枪和火枪的连线之内,任凭人喊狗咬,不离那条线。这样,拿手枪的人开火就会把拿火枪的打死,反之亦然;两头同时开火,两头都会被打死。至于它,因为目标小,多半没事。就这样连兜了几个圈子,它找到了一个空子,一头撞出去了;跑得潇洒之极。以后我在甘蔗地里还见过它一次,它长出了獠牙,还认识我,但已不容我走近了。这种冷淡使我痛心,但我也赞成它对心怀叵测的人保持距离。 5我已经四十岁了,除了这只猪,还没见过谁敢于如此无视对生活的设置。相反,我倒见过很多想要设置别人生活的人,还有对被设置的生活安之若素的人。因为这个原故,我一直怀念这只特立独行的猪。" 

现在,我想识别这篇文章里面所有的名词。

1tagging(cn,tag_worker) %>%  2  enframe() %>%  3  filter(name == "n") -> tag_names 

现在我把文中的名词都筛选了出来。词性的列名称为name,词语的列名称为value。我要统计一下王小波在这篇文章中用到名词的词频。

 1tag_names %>%   2  count(value) %>%   #对名词进行计数  3  arrange(desc(n))   #降序排列  4## # A tibble: 113 x 2  5##    value     n  6##    <chr> <int>  7##  1 猪       17  8##  2 人       12  9##  3 母猪      8 10##  4 汽笛      5 11##  5 动物      4 12##  6 领导      4 13##  7 主题      4 14##  8 狗        3 15##  9 火枪      3 16## 10 牛        3 17## # ... with 103 more rows 

有意思,“猪”是出现最多的名词,其次是“人”,再到“母猪”。

实际运用中,想必还是会有很多障碍。大家要记得,在用户自定义词库中,我们是可以给词性进行标注的!也就是我们的词想要识别成什么,我们自己可以说了算。这在垂直领域的运用中,是相当有用的。至于应该如何设置标注,大家可以观察原始词库的格式,然后对文本文件进行修饰。原始文件的位置在哪里?请直接键入 DICTPATH ,你会找到路径,然后用文本格式来查看这个文件即可。然后按照相应格式,来更改用户词典(同一个文件目录下的“user.dict.utf8”)。 我还是认为, 算法是不可能超越词库的,多在词库下功夫,算法才能够发挥效用 。应该想方设法构建更加优秀的自定义词库,并进行面向业务的精准标注,才能够在实际应用中获得好的效果。

往期精彩:

R语言自然语言处理:词性标注与命名实体识别

公众号后台回复关键字即可学习

回复  爬虫             爬虫三大案例实战

回复  Python        1小时破冰入门

回复  数据挖掘      R语言入门及数据挖掘

回复  人工智能      三个月入门人工智能

回复  数据分析师   数据分析师成长之路 

回复  机器学习      机器学习的商业应用

回复  数据科学      数据科学实战

回复  常用算法     

常用数据挖掘算法

本文由R语言中文社区 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。

转载、引用前需联系作者,并署名作者且注明文章出处。

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

修改代码的艺术

修改代码的艺术

Michael Feathers / 刘未鹏 / 人民邮电出版社 / 2007-09-25 / 59.00元

我们都知道,即使是最训练有素的开发团队,也不能保证始终编写出清晰高效的代码。如果不积极地修改、挽救,随着时间流逝,所有软件都会不可避免地渐渐变得复杂、难以理解,最终腐化、变质。因此,理解并修改已经编写好的代码,是每一位程序员每天都要面对的工作,也是开发程序新特性的基础。然而,与开发新代码相比,修改代码更加令人生畏,而且长期以来缺乏文献和资料可供参考。 本书是继《重构》和《重构与模式》之后探讨......一起来看看 《修改代码的艺术》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具