spaCy:词语、短语、名字和概念的检索
spaCy是一个先进且广受欢迎的自然语言处理Python库。
spaCy安装
1 |
pip3 install spacy |
spaCy入门
- 使用
spacy.blank
来创建一个空白的("zh"
)的nlp
对象。 - 创建
doc
并打印其中的文本。
1 2 3 4 5 6 7 8 9 10 |
import spacy # 创建nlp对象 nlp = spacy.blank("zh") # 处理文本 doc = nlp("这是一个句子。") # 打印文本 print(doc.text) |
返回结果如下
1 |
这是一个句子。 |
文本(documents), 跨度(spans)和词符(tokens)
- 使用
spacy.blank
来创建一个nlp
对象。 - 处理文本,然后在
doc
变量中创建一个Doc
对象的实例。 - 选取
Doc
中的第一个词符并打印出它的text
。
1 2 3 4 5 6 7 8 9 10 11 12 |
import spacy nlp = spacy.blank("zh") # 处理文本 doc = nlp("我喜欢老虎和狮子。") # 选择第一个词符 first_token = doc[0] # 打印第一个词符的文本 print(first_token.text) |
返回结果如下
1 |
我 |
- 使用
spacy.blank
来创建一个中文的nlp
对象。 - 处理文本,然后在
doc
变量中创建一个Doc
对象的实例。 - 从
Doc
中截取其部分的词符”老虎”和”老虎和狮子”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import spacy nlp = spacy.blank("zh") # 处理文本 doc = nlp("我喜欢老虎和狮子。") # 遍历打印doc中的内容 for i, token in enumerate(doc): print(i, token.text) # 截取Doc中"老虎"的部分 laohu = doc[3:5] print(laohu.text) # 截取Doc中"老虎和狮子"的部分(不包括"。") laohu_he_shizi = doc[3:8] print(laohu_he_shizi.text) |
返回结果如下
1 2 3 4 5 6 7 8 9 10 11 |
0 我 1 喜 2 欢 3 老 4 虎 5 和 6 狮 7 子 8 。 老虎 老虎和狮子 |
词汇属性
- 检查词符的
text
属性是否是人民币符号”¥“。 - 获取文档中紧接着当前词符的词符。
doc
中下一个词符的索引是token.i + 1
。 - 使用词符属性
like_num
来检查下一个doc
中的词符是否构成一个数字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import spacy nlp = spacy.blank("zh") # 处理文本 doc = nlp( "在1990年,一份豆腐脑可能只要¥0.5。" "现在一份豆腐脑可能要¥5左右了。" ) # 遍历doc中的词符 for token in doc: # 检测词符的文本是否是"¥" if token.text == "¥": # 获取文档中的下一个词符 next_token = doc[token.i + 1] # 检测下一个词符是否组成一个数字 if next_token.like_num: print("Price found:", next_token.text) |
返回结果如下
1 2 |
Price found: 0 Price found: 5 |
调用流程
- 使用
spacy.load
来调用一个比较小的中文流程"zh_core_web_sm"
。 - 处理文档并打印出文档中的文字。
安装流程包,代码如下(安装中文小报)
1 |
python3 -m spacy download zh_core_web_sm |
1 2 3 4 5 6 7 8 9 10 11 12 |
import spacy # 读取"zh_core_web_sm"流程 nlp = spacy.load("zh_core_web_sm") text = "写入历史了:苹果是美国第一家市值超过一万亿美元的上市公司。" # 处理文本 doc = nlp(text) # 打印doc中的文本 print(doc.text) |
返回结果如下
1 |
写入历史了:苹果是美国第一家市值超过一万亿美元的上市公司。 |
语言学标注的预测
1 2 |
使用nlp对象来处理文本,创建一个doc。 对每一个词符,打印出其中的文字、词符的.pos_(词性标注) 以及词符的.dep_(依存标注)。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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}") |
返回结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
写入 VERB ROOT 历史 NOUN dobj 了 PART dep : 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 conj 。 PUNCT punct |
- 处理文本创建一个
doc
对象。 - 对
doc.ents
做遍历,打印出实体的文本以及label_
属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import spacy nlp = spacy.load("zh_core_web_sm") text = "写入历史了:苹果是美国第一家市值超过一万亿美元的上市公司。" # 处理文本 doc = nlp(text) # 对识别出的实体进行遍历 for ent in doc.ents: # 打印实体文本及标注 print(ent.text, ent.label_) |
返回结果如下
1 2 3 |
美国 GPE 第一 ORDINAL 一万亿美元 MONEY |
命名实体在场景中的预测
- 使用
nlp
对象来处理文本 - 对所有实体进行遍历,打印出实体的文本和标注。
- 看上去模型并没有预测出”iPhone X”。为这几个词符创建一个跨度(span)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import spacy nlp = spacy.load("zh_core_web_sm") text = "苹果公布了预购细节,泄露了即将到来的iPhone X的发布日期。" # 处理文本 doc = nlp(text) # 打印token及序号 for i, token in enumerate(doc): print(i, token.text) # 遍历实体 for ent in doc.ents: # 打印实体文本和标签 print(ent.text, ent.label_) # 获取"iPhone X"的跨度(span) iphone_x = doc[11:13] # 打印span的文本 print("Missing entity:", iphone_x.text) |
返回结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
0 苹果 1 公布 2 了 3 预购 4 细节 5 , 6 泄露 7 了 8 即将 9 到来 10 的 11 iPhone 12 X 13 的 14 发布 15 日期 16 。 Missing entity: iPhone X |
Matcher的使用
- 从
spacy.matcher
中导入Matcher
。 - 用
nlp
对象中共享的vocab
来初始化它。 - 创建一个模板使它可以和
"iPhone"
和"X"
这两个词符的"TEXT"
值匹配。 - 使用
matcher.add
方法把模板加入到matcher里面。 - 在
doc
上面调用matcher,把结果存储在matches
变量中。 - 遍历所有的match,得到从索引
start
到索引end
的匹配结果的跨度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import spacy # 导入Matcher from spacy.matcher import Matcher nlp = spacy.load("zh_core_web_sm") doc = nlp("苹果公布了预购细节,泄露了即将到来的iPhone X的发布日期。") # 用模型分享的词汇表初始化Matcher matcher = Matcher(nlp.vocab) # 创建一个模板来匹配这两个词符:"iPhone"和"X" pattern = [{"TEXT": "iPhone"}, {"TEXT": "X"}] # 把模板加入到matcher中 matcher.add("IPHONE_X_PATTERN", [pattern]) # 在doc中使用matcher matches = matcher(doc) print("Matches:", [doc[start:end].text for match_id, start, end in matches]) |
返回结果如下
1 |
Matches: ['iPhone X'] |
匹配模板的书写
写一个模板,只匹配到所有提及完整iOS版本的部分: “iOS 7”,“iOS 11”和”iOS 10”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import spacy from spacy.matcher import Matcher nlp = spacy.load("zh_core_web_sm") matcher = Matcher(nlp.vocab) doc = nlp( "升级iOS之后,我们并没有发现系统设计有很大的不同,远没有当年iOS 7发布时带来的" "焕然一新的感觉。大部分iOS 11的设计与iOS 10保持一致。但我们仔细试用后也发现了一些" "小的改进。" ) # 写一个模板来匹配完整的iOS版本 ("iOS 7", "iOS 11", "iOS 10") pattern = [{"TEXT": "iOS"}, {"IS_DIGIT": True}] # 把模板加入到matcher中,将matcher应用到doc上面 matcher.add("IOS_VERSION_PATTERN", [pattern]) matches = matcher(doc) print("Total matches found:", len(matches)) # 遍历所有的匹配,然后打印span的文本 for match_id, start, end in matches: print("Match found:", doc[start:end].text) |
返回结果如下
1 2 3 4 |
Total matches found: 3 Match found: iOS 7 Match found: iOS 11 Match found: iOS 10 |
- 写一个模板,只匹配到不同格式的”download”词(词符的原词是”download”), 后面跟着一个词性是
"PROPN"
(专有名词)的词符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import spacy from spacy.matcher import Matcher nlp = spacy.load("zh_core_web_sm") matcher = Matcher(nlp.vocab) doc = nlp( "我之前有去下载Dota到电脑上面,但是根本打不开游戏,怎么办?" "我下载Minecraft,是Windows的版本,下载后是一个'.zip'的文件夹,然后我用了默认软件做了" "解压...我是不是还需要去下载Winzip?" ) # 写一个模板来匹配"下载"加一个代词 pattern = [{"TEXT": "下载"}, {"POS": "PROPN"}] # 把模板加入到matcher中,然后把matcher应用到doc上面 matcher.add("DOWNLOAD_THINGS_PATTERN", [pattern]) matches = matcher(doc) print("Total matches found:", len(matches)) # 遍历所有的匹配,打印span的文本 for match_id, start, end in matches: print("Match found:", doc[start:end].text) |
返回结果如下
1 2 3 |
Total matches found: 2 Match found: 下载Dota Match found: 下载Minecraft |
- 写一个模板,匹配到形容词(
"ADJ"
) 后面跟着一两个名词"NOUN"
(一个名词和另一个可能有的名词)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import spacy from spacy.matcher import Matcher nlp = spacy.load("zh_core_web_sm") matcher = Matcher(nlp.vocab) doc = nlp( "这个app的特性包括了优雅设计、快捷搜索、自动标签以及可选声音。" ) # 写一个模板是形容词加上一个或者两个名词 pattern = [{"POS": "ADJ"}, {"POS": "NOUN"}, {"POS": "NOUN", "OP": "?"}] # 把模板加入到matcher中然后把matcher应用到doc上面写一个模板,匹配到形容词("ADJ") 后面跟着一两个名词"NOUN"(一个名词和另一个可能有的名词)。 matcher.add("ADJ_NOUN_PATTERN", [pattern]) matches = matcher(doc) print("Total matches found:", len(matches)) # 遍历所有的匹配,打印span的文本 for match_id, start, end in matches: print("Match found:", doc[start:end].text) |
返回结果如下
1 2 3 4 5 |
Total matches found: 4 Match found: 优雅设计 Match found: 快捷搜索 Match found: 自动标签 Match found: 可选声音 |