• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

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

邮箱:[email protected]


原理简介

在之前的文章中(

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语言自然语言处理:中文分词


找工作难,面试失败的核心原因已经找到


R语言中文社区2018年终文章整理(作者篇)

R语言中文社区2018年终文章整理(类型篇)

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

回复 爬虫            爬虫三大案例实战
回复 Python       1小时破冰入门
回复 数据挖掘     R语言入门及数据挖掘
回复 人工智能     三个月入门人工智能
回复 数据分析师  数据分析师成长之路 
回复 机器学习     机器学习的商业应用
回复 数据科学     数据科学实战
回复 常用算法     常用数据挖掘算法


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
R语言学习笔记︱Echarts与R的可视化包——地区地图发布时间:2022-07-18
下一篇:
R语言如何单独保存输出图片文件发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap