【Spacy教程】统计模型任务和匹配模板Matcher

举报
山顶夕景 发表于 2022/01/24 00:22:50 2022/01/24
【摘要】 学习总结(1)学习spacy的nlp对象、toke对象、span对象;在统计模型的依存标注、词性标注、命名实体标注任务中的用法,以及基于规则的匹配matcher。![在这里插入图片描述](https://img-blog.csdnimg.cn/ebf31d957d6f4a8197fc5b5726a1f3e5.png#pic_center#pic_center =400x)@[toc] 零、...

学习总结

(1)学习spacy的nlp对象、toke对象、span对象;在统计模型的依存标注、词性标注、命名实体标注任务中的用法,以及基于规则的匹配matcher。
![在这里插入图片描述](https://img-blog.csdnimg.cn/ebf31d957d6f4a8197fc5b5726a1f3e5.png#pic_center#pic_center =400x)

@[toc]

零、Introduction to Spacy

0.1 nlp对象、toke对象、span对象

如果是处理中文则是导入中文类:from spacy.lang.zh import Chinese,并且创建nlp对象nlp = Chinese()
(1)这里实例化的对象包含处理管道pipeline,可用于分词,spacy.lang可支持多种语言。
(2)这里我们将文本doc传参入刚才实例化的nlp对象,然后像列表一样进行遍历,也可以通过下标进行索引。
(3)可以通过.text访问文本中每个分词的文本,其可以是一个单词或标点符号。
![在这里插入图片描述](https://img-blog.csdnimg.cn/be0eadc480ff48f7be76c11564db4bde.png#pic_center =310x)

# -*- coding: utf-8 -*-
"""
Created on Wed Dec  8 10:16:04 2021

@author: 86493
"""
# 导入英文类
from spacy.lang.en import English 
# 实例化一个nlp类对象,包含管道pipeline
nlp = English()
# print(nlp)
doc = nlp("December is excited!")
# 迭代tokens
for token in doc:
    print(token.text)
    
token = doc[1]
print(token.text)
December
is
excited
!
is

(1)也可以将多个元素组成Span对象,如下会打印出is excited,注意也是左开右闭。
(2)Span对象只是一个视图,并没有包含数据本身,
![在这里插入图片描述](https://img-blog.csdnimg.cn/3c57497eb3e84eec88e95942f97c2f0e.png#pic_center =300x)

# 左开右闭
span = doc[1: 3] 
print(span.text)

0.2 词汇属性

依次打印出文本中的index、分词、是否为字母、是否为标点符号、是否为数字。

doc = nlp("It costs $5.")
print("Index:   ", [token.i for token in doc])
print("Text:    ", [token.text for token in doc])

print("is_alpha:", [token.is_alpha for token in doc])
print("is_punct:", [token.is_punct for token in doc])
print("like_num:", [token.like_num for token in doc])

结果为:

Index:    [0, 1, 2, 3, 4]
Text:     ['It', 'costs', '$', '5', '.']
is_alpha: [True, True, False, False, False]
is_punct: [False, False, False, False, True]
like_num: [False, False, False, True, False]

一、统计模型

1.1 依存标注、词性标注

可以完成词性标注、依存关系解析、命名实体识别等任务,是从标注过的文本中训练而来。

$ python -m spacy download en_core_web_sm
import spacy

nlp = spacy.load("en_core_web_sm")

(1)Part-of-speech Tags词性标注,可以通过token.pos_获得token的词性标注。
(2).dep_属性返回预测的依存关系标注。
(3).head属性返回句法头词符。即词在句子中所依附的母词符。
注意在spaCy中,返回字符串的属性名一般结尾会有下划线;没有下划线的属性会返回一个整型的ID值。

import spacy

# Load the small English model
nlp = spacy.load("en_core_web_sm")

# Process a text
doc = nlp("She ate the pizza")

# Iterate over the tokens
for token in doc:
    # Print the text and the predicted part-of-speech tag
    print(token.text, token.pos_, token.dep_, token.head.text)
She PRON nsubj ate
ate VERB ROOT ate
the DET det pizza
pizza NOUN dobj ate

命名实体是那些被赋予了名字的真实世界的物体,比如一个人、一个组织或者一个国家。

1.2 命名实体标注

doc.ents中可以读取模型预测出的所有命名实体。
(1)它会返回一个Span实例的遍历器,我们可以打印出实体文本和用.label_属性来打印出实体标注。
(2)ents.text为对应识别出的实体。

下面即找出句子中所有的命名实体:

# 处理文本
doc = nlp("微软准备用十亿美金买下这家英国的创业公司。")

# 遍历识别出的实体
for ent in doc.ents:
    # 打印实体文本及其标注
    print(ent.text, ent.label_)

模型正确地将"微软"识别为一个组织,将"英国"识别为一个地理政治实体, 将"十亿美金"预测为钱。当然如果不知道GPE啥意思,可以spacy.explain("GPE")查看,达到'Countries, cities, states'的解释。结果为:

微软 ORG
十亿美金 MONEY
英国 GPE

小练习:打印出句子中的的文字、词符的.pos_(词性标注) 以及词符的.dep_(依存标注)

import spacy

nlp = spacy.load("zh_core_web_sm")

text = "写入历史了:苹果是美国第一家市值超过一万亿美元的上市公司。"

# 处理文本
doc = nlp(text)

for token in doc:
    # 获取词符文本、词性标注及依存关系标签
    token_text = token.text
    token_pos = token.pos_
    token_dep = token.dep_
    # 规范化打印的格式
    print(f"{token_text:<12}{token_pos:<10}{token_dep:<10}")
写入          VERB      ROOT      
历史          NOUN      dobj      
了           PART      discourse 
:           PUNCT     punct     
苹果          NOUN      nsubj     
是           VERB      cop       
美国          PROPN     nmod      
第一          NUM       nummod    
家           NUM       mark:clf  
市值          NOUN      nsubj     
超过          VERB      acl       
一万亿         NUM       nmod:range
美元          NUM       mark:clf  
的           PART      mark      
上市          NOUN      compound:nn
公司          NOUN      ROOTPUNCT     punct

(2)命名实体识别

import spacy
# Load the small English model
nlp = spacy.load("en_core_web_sm")
# Process a text
doc = nlp("It’s official: Apple is the first U.S. public company to reach a $1 trillion market value")
# 命名实体识别
for ent in doc.ents:
    # 打印实体文本和标签
    print(ent.text, ent.label_)

可以看到上面句子对应的实体:

Apple ORG
first ORDINAL
U.S. GPE
$1 trillion MONEY

小测:
![在这里插入图片描述](https://img-blog.csdnimg.cn/5da761bc6f3a458ab283f0e7553761c0.png#pic_center =690x)

二、基于规则的匹配

2.1 不直接用正则表达式的原因

  • 我们是在Doc对象中而不是直接在字符串上做匹配(与正则表达式相比,matcher是配合Doc和Token这样的方法来使用的, 而不是只作用于字符串上。)
  • 我们是在词符及其属性中做匹配
  • 我们可以直接调用模型的预测结果来写规则。
    举个例子,“duck” (动词) vs. “duck” (名词)是不一样的("duck"名词意思是鸭子,而动词是闪避的意思)

2.2 匹配的模板 Matcher

匹配的模板是一个列表,列表中每个元素是一个字典。
每个字典即一个字符,字典的key为字符属性名,value为映射到对应的目标值。

(1)注意一开始要传入nlp.vocab词表。
(2)matcher.add方法可以用来添加一个模板。第一个参数是唯一的ID用来识别匹配的是哪一个模板。

【栗子1】匹配词符的完全一致的文字

下面的for循环其实也可以写成print("Matchers:", [doc[start: end].text for match_id, start, end in matches])
注意:官方教程说是matcher.add("IPHONE_PATTERN", pattern),但是试了下报错(PS:spacy3.0以前的版本很多不太一样的写法),这里应该给pattern加上[ ],参考官方文档的栗子:
![在这里插入图片描述](https://img-blog.csdnimg.cn/df46dd02311f42a180a1e2d6f83ad92a.png#pic_center =400x)

# 使用matcher
import spacy 
from spacy.matcher import Matcher
# 读取一个模型,创建nlp实例
nlp = spacy.load("en_core_web_sm")
# 用模型分享出的volab初始化matcher 
matcher = Matcher(nlp.vocab)

# 给matcher加入模板
pattern = [{"TEXT": "iPhone"}, {"TEXT": "X"}]
matcher.add("IPHONE_PATTERN", [pattern])

# 处理文本
doc = nlp("Upcoming iPhone X release date leaked")

# 调用matcher 
matches = matcher(doc)

# 遍历所有的匹配结果 
for mathc_id, start, end in matches:
    # 获得匹配的跨度 
    matched_span = doc[start: end]
    print(matched_span.text)

对doc调用一个matcher时会返回一个列表,其中列表中每个元素是一个元组tuple。
每个元组由三个值构成:匹配到的ID,匹配到的跨度的起始start和终止索引end
所以我们可以对所有的匹配结果进行遍历,然后创建Span实例。 这个实例即为doc被起始和终止索引截取的部分。

iPhone X

【栗子2】匹配任意的词符属性

pattern = [
    {"LEMMA": "喜欢", "POS": "VERB"},
    {"POS": "NOUN"}
]
doc = nlp("我喜欢狗但我更喜欢猫。")

词根是“喜欢”的动作,后面接一个名词:

喜欢狗
喜欢猫

【栗子3】使用运算符和量词

可以规定匹配的次数:
![在这里插入图片描述](https://img-blog.csdnimg.cn/5d0d3274d4d8426f88d22de251af2e39.png#pic_center =400x)

pattern = [
    {"LEMMA": "买"},
    {"POS": "NUM", "OP": "?"},  # 可选: 匹配0次或者1次
    {"POS": "NOUN"}
]
doc = nlp("我买个肉夹馍。我还要买凉皮。")

在这里"?"运算符使相应的判断词符变为可选, 所以我们会匹配到一个词根为"买"的词符,一个可选的数词和一个名词。

买个肉夹馍
买凉皮

2.3 Matcher小练习

【栗子1】只匹配到所有提及完整iOS版本的部分

doc = nlp(
    "升级iOS之后,我们并没有发现系统设计有很大的不同,远没有当年iOS 7发布时带来的"
    "焕然一新的感觉。大部分iOS 11的设计与iOS 10保持一致。但我们仔细试用后也发现了一些"
    "小的改进。"
)
# 写一个模板来匹配完整的iOS版本 ("iOS 7", "iOS 11", "iOS 10")
pattern = [{"TEXT": "iOS"}, {"IS_DIGIT": True}]
Match found: iOS 7
Match found: iOS 11
Match found: iOS 10

【栗子2】“下载”+专有名词

doc = nlp(
    "我之前有去下载Dota到电脑上面,但是根本打不开游戏,怎么办?"
    "我下载Minecraft,是Windows的版本,下载后是一个'.zip'的文件夹,然后我用了默认软件做了"
    "解压...我是不是还需要去下载Winzip?"
)# 写一个模板来匹配"下载"加一个代词
pattern = [{"TEXT": "下载"}, {"POS": "PROPN"}]
Match found: 下载Dota
Match found: 下载Minecraft
Match found: 下载Winzip

【栗子3】形容词后接名词

匹配到形容词(“ADJ”) 后面跟着一两个名词"NOUN"(一个名词和另一个可能有的名词)。

doc = nlp(
    "这个app的特性包括了优雅设计、快捷搜索、自动标签以及可选声音。"
)

# 写一个模板是形容词加上一个或者两个名词
pattern = [{"POS": "ADJ"}, {"POS": "NOUN"}, {"POS": "NOUN", "OP": "?"}]
Match found: 优雅设计
Match found: 快捷搜索
Match found: 自动标签
Match found: 可选声音

Reference

(1)https://course.spacy.io/en/chapter1
(2)spacy基础教程

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。