Press "Enter" to skip to content

斯坦福大学自然语言处理包StanfordNLP

最近在推荐点评的影响抽取,中间涉及到分词后的词性识别,看了各种开源分词工具,主要是词性标注集存在差异,最终选定了斯坦福大学的NLP。

 

StanfordNLP的词性标记(中文)

 

动词,形容词(4种):VA,VC,VE,VV

 

谓词性形容词:VA

 

谓词性形容词大致上相当于英语中的形容词和中文语法中、文学作品里的静态动词。我们的谓词性形容词包括两类:

第一类:没有宾语且能被“很”修饰的谓语。
第二类:源自第一类的、通过重叠(如红彤彤)或者通过名词加形容词模式意味着“像N一样A”(如雪白)的谓语。这个类型的谓词性形容词没有宾语,但是有一些不能被“很”修饰,因为这些词的强调意思已经内嵌在词内了。

注意:当集合(VA)中的一个词修饰名词但没有用“的”,那幺它被标注为JJ(名作定)或是一个名词,而不是VA。当集合(VA)中的一个词有一个宾语,那幺它被标注为VV,而不是VA。譬如,这 项/M 活动 丰富/VV 了/AS 他 的/DEG 生活。

 

系动词:VC

 

“是”和“为”被标记为VC。如果“非”的意思是“不是”并且句子里没有其他动词时,“非”也被标注为VC。

 

“是”有几种用法:

连接两个名词短语或者主语:他是/VC 学生。
在分裂句中:他是/VC 昨天 来 的/SP。
为了强调:他是/VC 喜欢 看 书。

现在,在所有这些情况中,“是”被标注为VC。

 

“有”作为主要动词:VE

 

只有当“有,没{有}”和“无”作为主要动词时(包括占有的“有”和表存在的“有”等等),被标注为VE。

 

其他动词:VV

 

VV包括其他动词,诸如情态动词,提升谓词(如“可能”),控制动词(如“要”、“想”),行为动词(如“走”),心理动词(如“喜欢”、“了解”、“怨恨”),等等。

 

名词(3种):NR,NT,NN

 

专有名词:NR

 

专有名词是名词的子集。一个专有名词可以是一个特定的人名,政治或地理上定义的地方(城市、国家、河流、山脉等),或者是一种组织(企业、政府或其他组织实体)。一个专有名词通常是独一无二,并且不能被Det+M所修饰的。

以下名字是专有名词:地区/国家/村庄/城市,山脉/河流,报纸/杂志,组织/公司,学校/联盟/基金会,个人/家庭。
以下名字不是专有名词:国籍(如中国人),种族(如白人),职称(如教授),疾病,职业,器官(如肺),乐器(如钢琴),游戏(如足球),花(如玫瑰),等等。

时间名词:NT

 

时间名词可以是介词的宾语,譬如在、从、到、等到。它们可以被问及,如“这个时候”,也可以被用以提问“什幺时候”。它们也可以直接修饰VP(动词短语)或者S(主语)。像其他名词一样,时间名词可以是某些动词的论元。

 

时间名词可以是时间的名称(如1990年、一月、汉朝)或是由“PN+LC,N+LC,DT+N”等结构组成。例子:一月、汉朝、当今、何时、今后

 

其他名词:NN

 

其他名词包括所有其他名词。其他名词NN,除了地方名词,一般不能修饰动词短语(有“地/DEV”或者没“地/DEV”)。

 

定位(1种):LC

 

方位词:LC

 

很多名词单独使用时不能作为介词如“在”、“到”的论元,也不能直接修饰VP(动词短语)或者S(主语)。方位词的一个功能是连接前述的名词短语或者主语,从而使整个短语可以作为这些介词的论元或者来修饰动词短语或主语。

 

一些方位词可以独立使用作为介词或动词的论元。一些方位词可以被“最”修饰。方位词不能被Det+M所修饰。

 

方位词分为两类:

方位词:这类方位词表示方向、位置等。它们来自名词。一些可以单独使用作为介词或动词的论元。一些可以被“最”修饰。它们不能被Det+M所修饰。

单音节方位词:如:前,后,里,外,内,北,东,边,侧,底,间,末,旁。
双音节方位词:它们由以下部分组成:

单音节方位词加上诸如“以、之”等的语素。例子:之间,以北。
两个单音节方位词。例子:前后,左右,上下,东北。

其他:我们把以下情况标注为LC。

为止:到目前 为止。
开始:从四月 开始。
来:5年来。
以来:1998年 以来。
起:一九九三年 起。
在内:包括他 在内。

代词(1种):PN

 

代词的功能是作为名词短语的替代物或者表示事先详细说明的或者从上下文可知晓的被叫的人或事。它们一般不受Det+M或者形容词性短语修饰。

 

代词包括人称代词(如我、你),当作为名词短语单独使用时为指示代词(如这、那),所有格代名词(如其)以及反身代词(如我自己、自己)。

 

限定词和数词(3种):DT,CD,OD

 

限定词:DT

 

限定词包括指示词(如这、那、该)和诸如“每、各、前、后”等词。限定词不包括基数词和序列词。参见限定词部分。

 

基数词:CD

 

CD包括基数词并随意与一些概数词连用,如“来、多、好几”和诸如“好些、若干、半、许多、很多(如很多 学生)”等词。例子:1245,一百。

 

序列词:OD

 

序列词被标注为OD。我们把第+CD看做一个词,并标注它为OD。例子:第一百。

 

度量词(1种):M

 

度量词跟在数字后形成Det+M结构修饰名词或动词,包括类词(如“个”),表示一群的度量词,如“群”,以及公里、升等度量词。

 

一些度量词可以被有限的形容词(如一/CD小/JJ瓶/M水/NN),临时量词可以被名词和形容词修饰(如:一/CD铁/NN箱子/M书/NN)。

 

副词(1种):AD

 

副词包括情态副词、频率副词、程度副词、连接副词等,大部分副词的功能是修饰动词短语或主语。如:仍然、很、最、大大、又、约

 

介词(1种):P

 

介词可以把名词短语或从句作为论元。注释:把和被不标注为P。如:从、对

 

连词(2):CC,CS

 

并列连接词:CC

 

CC的主要模式是:XP{,},CC XP。如:与、和、或、或者、还是(or)

 

从属连词:CS

 

从属连词连接两个句子,一个句子从属于另一个,这样的连词标记为CS。CS模式是:CS S1,S2和S2 CS,S1。如:如果/CS,……就/AD……

 

助词(8):DEC,DEG,DER,DEV,SP,AS,ETC,SP,MSP

 

“的”作为补语标记/名词化标记:DEC(的,之)

 

如:吃的DEC。模式是:S/VP DEC{NP}

 

注:的还有其他标记

DEC 他的/DEG车
SP 他是/VC一定要来的/SP。
AS 他是/VC在这里下的/AS车。

“的”作为关联标记或所有格标记:DEG

 

模式:NP/PP/JJ/DT DEG{NP}。

 

补语短语 得:DER

 

在V-得-R和V-得结构中,“得”标记为DER。注:有些以“得”结尾的搭配不是V-得结构,如记得,获得是动词。

 

方式“地”:DEV

 

当“地”出现在“XP地VP”,XP修饰VP。在一些古典文学中,“的”也用于这种情景,此时“的”也标注为DEV。

 

动态助词:AS

 

动态助词仅包括“着,了,过,的”。

 

句末助词:SP

 

SP经常出现在句末,如:他好吧[SP]?有时,句末助词用于表停顿,如:他吧[SP],人很好。如:了,呢,吧,啊,呀,吗

 

ETC

 

ETC用于标注等,等等。

 

其他助词:MSP

 

“所,以,来,而”,当它们出现在VP前时,标注为MSP。

所:他所[MSP]需要的/DEC
以或来:用……以/MSP(或来)维持
而:为……而[MSP]奋斗

其他(8种):IJ,ON,PU,JJ,FW,LB,SB,BA

 

感叹词:IJ

 

出现在句首位置的感叹词,如:啊。

 

拟声词:ON

修饰“ON地V”中的VP:雨哗哗[ON]地[DEV]下了[AS]一夜
修饰“ON中的N”中的NP:砰[ON]的/DEG一声!
自行成句:砰砰[ON]!
一般不能被副词修饰,如:哗啦啦,咯吱。

长“被”结构:LB

 

仅包括“被,叫,给,为(口语中)”,当它们出现在被字结构NP0+LB+NP1+VP中。如:他被/LB 我训了/AS 一顿/M .

 

注:当叫作为兼语动词时,“叫”标注为VV。如:他叫/VV你去。

 

短“被”结构:SB(仅包括口语中的“被,给”)

 

NP0+SB+VP,他被/SB 训了/AS一顿/M。

 

注:“给”有其他标记:LB,VV和P。如:你给/P他写封/M信。

 

把字结构:BA

 

仅包括“把,将”,当它们出现在把字结构中(NP0+BA+NP1+VP)。如:他把/BA你骗了/AS。

 

注:“将”有其他标记:AD和VV,如:他将/VV了[AS]我的[DEG]军。

 

其他名词修饰语:JJ

 

包括三种类型:

区别词 只修饰模式JJ+的+{N}或JJ+N中的名词,且一定要有“的”,它们不能被程度副词修饰。如:共同/JJ的/DEG目标/NN,她是[VC]女/JJ的/DEG。
带有连字符的复合词。通常为双音节词JJ+N 如留美/JJ学者/NN
形容词:新/JJ消息/NN。模式:JJ+N

注:当“的/DEC”在形容词和名词中间时,形容词标记为VA。

 

外来词:FW

 

FW仅被用于:当词性标注标记在上下文中不是很清楚时。外来词不包括外来词的翻译,不包括混合中文的词(如卡拉OK/NN,A型/NN),不包括词义和词性在文中都是清楚的词。

 

标点:PU

 

当标点是词的一部分时,不用标注为PU,如123,456/CD。

 

StanfordNLP的词性标记(英文)

 

 

 

Stanford NLP自然语言处理包与使用

 

方案一:调用Stanford CoreNLP

 

Stanford CoreNLP的源代码是使用Java写的,提供了Server方式进行交互。 stanfordcorenlp 是一个对Stanford CoreNLP进行了封装的Python工具包。

 

安装流程:

安装Python包:pip install stanfordcorenlp
下载安装JDK(版本要求JDK 1.8以上)
下载安装 Stanford CoreNLP文件即语言包 。解压CoreNLP文件,并将中文包放在解压文件的根目录。

在Python环境下直接调用

 

代码示例:

 

from stanfordcorenlp import StanfordCoreNLP
 
nlp = StanfordCoreNLP('D:\\stanford-corenlp-full-2018-02-27', lang='zh')
sentence = '斯坦福大学自然语言处理包StanfordNLP'
print(nlp.word_tokenize(sentence))  # 分词
print(nlp.pos_tag(sentence))  # 词性标注
print(nlp.ner(sentence))  # 实体识别
print(nlp.parse(sentence))  # 语法树
print(nlp.dependency_parse(sentence))  # 依存句法

 

正常返回结果:

 

['斯坦福', '大学', '自然', '语言', '处理', '包', 'StanfordNLP']
[('斯坦福', 'NR'), ('大学', 'NN'), ('自然', 'AD'), ('语言', 'NN'), ('处理', 'VV'), ('包', 'NN'), ('StanfordNLP', 'NN')]
[('斯坦福', 'ORGANIZATION'), ('大学', 'ORGANIZATION'), ('自然', 'O'), ('语言', 'O'), ('处理', 'O'), ('包', 'O'), ('StanfordNLP', 'O')]
(ROOT
  (IP
    (NP (NR 斯坦福) (NN 大学))
    (ADVP (AD 自然))
    (NP (NN 语言))
    (VP (VV 处理)
      (NP (NN 包) (NN StanfordNLP)))))
[('ROOT', 0, 5), ('compound:nn', 2, 1), ('nsubj', 5, 2), ('advmod', 5, 3), ('nsubj', 5, 4), ('compound:nn', 7, 6), ('dobj', 5, 7)]

 

如果报如下错误,则为JDK没有安装或JDK环境变量没有正确配置。

 

Traceback (most recent call last):
  File "D:/CodeHub/NLP/test_new.py", line 3, in <module>
    nlp = StanfordCoreNLP('D:\\stanford-corenlp-full-2018-02-27', lang='zh')
  File "D:\CodeHub\NLP\venv\lib\site-packages\stanfordcorenlp\corenlp.py", line 46, in __init__
    if not subprocess.call(['java', '-version'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) == 0:
  File "D:\Program Files\Python37\lib\subprocess.py", line 339, in call
    with Popen(*popenargs, **kwargs) as p:
  File "D:\Program Files\Python37\lib\subprocess.py", line 800, in __init__
    restore_signals, start_new_session)
  File "D:\Program Files\Python37\lib\subprocess.py", line 1207, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] 系统找不到指定的文件。

 

以服务方式调用

 

以命令方式创建一个CoreNLP服务:

 

PS D:\stanford-corenlp-full-2018-02-27> java -mx6g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -timeout 5000
[main] INFO CoreNLP - --- StanfordCoreNLPServer#main() called ---
[main] INFO CoreNLP - setting default constituency parser
[main] INFO CoreNLP - warning: cannot find edu/stanford/nlp/models/srparser/englishSR.ser.gz
[main] INFO CoreNLP - using: edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz instead
[main] INFO CoreNLP - to use shift reduce parser download English models jar from:
[main] INFO CoreNLP - http://stanfordnlp.github.io/CoreNLP/download.html
[main] INFO CoreNLP -     Threads: 4
[main] INFO CoreNLP - Starting server...
[main] INFO CoreNLP - StanfordCoreNLPServer listening at /0:0:0:0:0:0:0:0:9000

 

代码示例:

 

from stanfordcorenlp import StanfordCoreNLP
 
nlp = StanfordCoreNLP('http://localhost', port=9000, lang='zh')
sentence = '斯坦福大学自然语言处理包StanfordNLP'
print(nlp.word_tokenize(sentence))  # 分词
print(nlp.pos_tag(sentence))  # 词性标注
print(nlp.ner(sentence))  # 实体识别
print(nlp.parse(sentence))  # 语法树
print(nlp.dependency_parse(sentence))  # 依存句法

 

方案二、使用官方发布的 stanfordnlp

 

安装方法: pip install stanfordnlp 。我执行的时候报如下错误:

 

Collecting torch>=1.0.0 (from stanfordnlp)
  Could not find a version that satisfies the requirement torch>=1.0.0 (from stanfordnlp) (from versions: 0.1.2, 0.1.2.post1, 0.1.2.post2)
No matching distribution found for torch>=1.0.0 (from stanfordnlp)

 

无法找到适合版本的pytorch? 于是采用手动安装PyTorch的方式: https://pytorch.org/get-started/locally/ 后可顺利安装。

 

使用示例:

 

import stanfordnlp
# stanfordnlp.download('zh')   # This downloads the English models for the neural pipeline
# 中间会遇到模型无法下载的情况,可通过以下地址http://nlp.stanford.edu/software/stanfordnlp_models/latest/zh_gsd_models.zip
# 下载后解压,并放入:C:\\Users\\$username$\\stanfordnlp_resources\\ 文件夹下。
 
nlp = stanfordnlp.Pipeline(lang='zh') # This sets up a default neural pipeline in English
doc = nlp("位置很棒,地铁口附近,很舒适,唯一有缺点就是新装修,公共服务特别好,早餐比我想像的好很多,而且提供到号中午十二点。")
doc.sentences[0].print_dependencies()
# doc.sentences[0].print_tokens()
# doc.sentences[0].print_words()

 

执行后输出如下:

 

('位置', '5', 'nmod')
('很棒', '5', 'amod')
(',地', '5', 'nmod')
('铁口', '5', 'nmod')
('附近', '8', 'nsubj')
(',', '8', 'advmod')
('很', '8', 'advmod')
('舒适', '29', 'dep')
(',', '29', 'punct')
('唯一', '12', 'amod')
('有', '12', 'amod')
('缺点', '13', 'nsubj')
('就是', '29', 'dep')
('新装', '15', 'nsubj')
('修,', '19', 'advcl')
('公共', '17', 'amod')
('服务', '15', 'obj')
('特别', '19', 'advmod')
('好', '23', 'dep')
(',', '19', 'mark:relcl')
('早餐', '23', 'nsubj')
('比我', '23', 'advmod')
('想像', '26', 'acl:relcl')
('的', '23', 'mark:relcl')
('好', '26', 'amod')
('很多', '29', 'nsubj')
(',', '29', 'punct')
('而且', '29', 'mark')
('提供', '0', 'root')
('到', '29', 'mark')
('号', '34', 'nmod')
('中午', '34', 'nmod')
('十二', '34', 'nummod')
('点', '29', 'obj')
('。', '29', 'punct')

 

可以看到上面的分词效果较差,所以还是推荐使用第一种方案。

 

参考链接: https://stanfordnlp.github.io/stanfordnlp/

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注