Press "Enter" to skip to content

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

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

 

学习总结

 

(1)学习spacy的nlp对象、toke对象、span对象;在统计模型的依存标注、词性标注、命名实体标注任务中的用法,以及基于规则的匹配matcher。

文章目录

零、Introduction to Spacy
0.1 nlp对象、toke对象、span对象

1.1 依存标注、词性标注

2.1 不直接用正则表达式的原因
2.2 匹配的模板 Matcher
【栗子1】匹配词符的完全一致的文字
【栗子2】匹配任意的词符属性
【栗子3】使用运算符和量词

【栗子1】只匹配到所有提及完整iOS版本的部分
【栗子2】“下载”+专有名词
【栗子3】形容词后接名词

零、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
访问文本中每个分词的文本,其可以是一个单词或标点符号。

# -*- 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
对象只是一个视图,并没有包含数据本身,

# 左开右闭
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      ROOT      
。           PUNCT     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

 

小测:

二、基于规则的匹配

 

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加上[ ]
,参考官方文档的栗子:

# 使用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】使用运算符和量词

 

可以规定匹配的次数:

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基础教程

Be First to Comment

发表回复

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