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

本文涉及的产品
NLP自然语言处理_基础版,每接口每天50万次
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_高级版,每接口累计50万次
简介: 如果是处理中文则是导入中文类:from spacy.lang.zh import Chinese,并且创建nlp对象nlp = Chinese()。(1)这里实例化的对象包含处理管道pipeline,可用于分词,spacy.lang可支持多种语言。

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

image.png

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

image.png

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

小测:

image.png

二、基于规则的匹配

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

image.png

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

可以规定匹配的次数:

image.png

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

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

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

doc = nlp(
    "这个app的特性包括了优雅设计、快捷搜索、自动标签以及可选声音。"
)
# 写一个模板是形容词加上一个或者两个名词
pattern = [{"POS": "ADJ"}, {"POS": "NOUN"}, {"POS": "NOUN", "OP": "?"}]
Match found: 优雅设计
Match found: 快捷搜索
Match found: 自动标签
Match found: 可选声音
相关文章
ES6系列笔记-字符串方法和字符串模板
ES6系列笔记-字符串方法和字符串模板
46 1
33.从入门到精通:Python3 正则表达式 re.match函数 re.search方法 re.match与re.search的区别
33.从入门到精通:Python3 正则表达式 re.match函数 re.search方法 re.match与re.search的区别
|
Python
Python正则表达式匹配电话号码和邮箱实例演示,正则表达式的基本用法
Python正则表达式匹配电话号码和邮箱实例演示,正则表达式的基本用法
268 0
在字符串方法 search() 中使用正则表达式
在字符串方法 search() 中使用正则表达式
81 0
|
自然语言处理 iOS开发 索引
【Spacy教程】统计模型任务和匹配模板Matcher
如果是处理中文则是导入中文类:from spacy.lang.zh import Chinese,并且创建nlp对象nlp = Chinese()。 (1)这里实例化的对象包含处理管道pipeline,可用于分词,spacy.lang可支持多种语言。
410 0
【Spacy教程】统计模型任务和匹配模板Matcher