概述
知识图谱是数据科学中极具价值的概念,它通过结构化的方式存储实体及其关系。本文将带你使用 Python 和 spaCy 库,从维基百科文本中挖掘信息,亲手构建一个基础的知识图谱。
知识图谱基础
什么是知识图谱
简单来说,图(Graph)由节点(Nodes)和边(Edges)组成。在知识图谱中,节点代表实体,边代表它们之间的关系,通常表现为三元组形式:(头实体,关系,尾实体)。
例如,"普京" (头实体) 与 "俄罗斯" (尾实体) 之间通过 "是总统" (关系) 连接。同样,"普京" 与 "克格勃" 可以通过 "工作过" 关联,"俄罗斯" 与 "APEC 组织" 则通过 "成员" 关联。
识别实体和关系本身并不困难,成熟的有监督命名实体识别(NER)和关系抽取模型已经存在。但标注大规模数据集成本极高。作为初学者,我们可以利用 NLP 技术——如句子分割、依赖解析、词性标注等——来实现这一过程。
句子分割
构建图谱的第一步是将长文本分解为独立的句子,并筛选出包含明确主语和宾语的句子。
以一段关于网球选手 Sumit Nagal 的报道为例:
Indian tennis player Sumit Nagal moved up six places from 135 to a career-best 129 in the latest men's singles ranking. The 22-year-old recently won the ATP Challenger tournament. He made his Grand Slam debut against Federer in the 2019 US Open. Nagal won the first set.
分割后的句子如下:
- Indian tennis player Sumit Nagal moved up six places...
- The 22-year-old recently won the ATP Challenger tournament.
- He made his Grand Slam debut against Federer...
- Nagal won the first set.
其中第 2 句和第 4 句结构清晰。第 2 句中,"22-year-old" 是主语,"ATP Challenger tournament" 是宾语;第 4 句中,"Nagal" 是主语,"first set" 是宾语。人工筛选效率太低,我们需要借助程序自动提取。
实体识别
实体即图谱中的节点。虽然名词和专有名词通常是实体,但当实体跨越多个单词时(如 "22-year-old"),仅靠词性标记(POS)是不够的,必须结合依赖解析(Dependency Parsing)。
我们使用 spaCy 库来解析依赖关系:
import spacy
nlp = spacy.load('en_core_web_sm')
doc = nlp("The 22-year-old recently won ATP Challenger tournament.")
for tok in doc:
print(tok.text, "...", tok.dep_)
输出显示:
old的依赖标签是nsubj(名义主语),但这只是核心词。22-year的标签是amod(形容词修饰语),它是old的修饰成分。
为了提取完整实体,我们需要定义规则:提取主语/宾语及其修饰语、复合词以及标点符号。这样就能得到完整的实体 22-year-old 和 ATP Challenger tournament。
关系抽取
关系即图谱中的边。通常,谓语动词就是句子中的主要关系。
继续分析句子:"Nagal won the first set."
doc = nlp()
tok doc:
(tok.text, , tok.dep_)


