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

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

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

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

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

原理简介

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

n 名词     nr 人名         nr1 汉语姓氏         nr2 汉语名字         nrj 日语人名         nrf 音译人名     ns 地名      nsf 音译地名     nt 机构团体名     nz 其它专名     nl 名词性惯用语     ng 名词性语素 t 时间词   tg 时间词性语素 s 处所词 f 方位词 v 动词     vd 副动词     vn 名动词     vshi 动词“是”     vyou 动词“有”     vf 趋向动词     vx 形式动词     vi 不及物动词(内动词)     vl 动词性惯用语     vg 动词性语素 a 形容词     ad 副形词     an 名形词     ag 形容词性语素     al 形容词性惯用语 b 区别词     bl 区别词性惯用语 z 状态词 r 代词     rr 人称代词     rz 指示代词         rzt 时间指示代词         rzs 处所指示代词         rzv 谓词性指示代词     ry 疑问代词         ryt 时间疑问代词         rys 处所疑问代词         ryv 谓词性疑问代词     rg 代词性语素 m 数词     mq 数量词 q 量词     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 中国大陆许可协议 进行许可。

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

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


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

查看所有标签

猜你喜欢:

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

利用Python进行数据分析

利用Python进行数据分析

Wes McKinney / 唐学韬 / 机械工业出版社 / 2013-11-18 / 89.00

【名人推荐】 “科学计算和数据分析社区已经等待这本书很多年了:大量具体的实践建议,以及大量综合应用方法。本书在未来几年里肯定会成为Python领域中技术计算的权威指南。” ——Fernando Pérez 加州大学伯克利分校 研究科学家, IPython的创始人之一 【内容简介】 还在苦苦寻觅用Python控制、处理、整理、分析结构化数据的完整课程?本书含有大量的实践案例,......一起来看看 《利用Python进行数据分析》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换