知识图谱项目实践

目录

步骤

SpaCy

[Textacy------Text Analysis for Cybersecurity](#Textacy——Text Analysis for Cybersecurity)

Networkx

Dateparser

导入库

写出页面的名称

​编辑

自然语言处理

词性标注

可能标记的完整列表

[依存句法分析(Dependency Parsing,DEP)](#依存句法分析(Dependency Parsing,DEP))

可能的标签完整列表

实例理解POS与DEP

可视化注释

Spacy还可执行命名实体识别

可能的所有标签的完整列表

Spacy图形工具

实体和关系抽取

构建图表

网络图


使用Python和自然语言处理构建知识图谱。

知识图谱被视为自然语言处理领域的一部分,因为要构建"知识",需要进行"语义增强"过程。由于没有人想要手动执行此任务,因此我们需要使用机器和自然语言处理算法来完成此任务。

我们将解析维基百科并提取一个页面,用作本数据集。

俄乌战争-维基百科

步骤

  • 设置:使用维基百科API进行网页爬取以读取包和数据。
  • NLP使用SpaCy:对文本进行分句、词性标注、依存句法分析和命名实体识别。
  • 提取实体及其关系:使用Textacy库来识别实体并建立它们之间的关系。
  • 网络图构建:使用NetworkX库来创建和操作图形结构。
  • 时间轴图:使用DateParser库来解析日期信息并生成时间轴图。

SpaCy

"spaCy" 这个名称是从 "Space"(空间) 这个词汇中来的,它代表了 spaCy 设计的初衷,即为了提供一个轻量级、高性能的自然语言处理(NLP)库。

SpaCy是一个自然语言处理(NLP)库和工具包,用于处理和分析文本数据。它被设计成高效、快速且易用的工具,具有许多功能,包括分词、命名实体识别、依存关系分析、文本分类等。SpaCy支持多种语言,并提供了预训练的词向量模型。它广泛用于文本挖掘、信息检索、自动化文本分类、情感分析、实体识别、机器翻译等领域。

Textacy------Text Analysis for Cybersecurity

Textacy的名称来源于"Text Analysis for Cybersecurity"(网络安全文本分析),这个名称强调了该库最初的用途,即在网络安全领域中对文本数据进行分析。然而,随着时间的推移,Textacy的功能扩展到了更广泛的自然语言处理和文本挖掘任务,包括情感分析、实体识别、主题建模等,因此它的名称也逐渐演化成了更通用的文本分析工具。

Networkx

NetworkX是一个用于创建、操作和研究复杂网络(图)的Python库。它提供了丰富的功能和工具,使用户能够轻松地构建、分析和可视化各种类型的网络,包括社交网络、网络拓扑、生物网络、交通网络等。

Dateparser

"dateparser" 是一个Python库,用于解析日期和时间字符串。它的主要功能是将各种格式的日期和时间字符串转换成Python的datetime对象,以便在程序中进行日期和时间的处理和计算。

导入库

python 复制代码
## for data
import pandas as pd  #1.1.5
import numpy as np  #1.21.0

## for plotting
import matplotlib.pyplot as plt  #3.3.2

## for text
import wikipediaapi  #0.5.8
import nltk  #3.8.1
import re

## for nlp
import spacy  #3.5.0
from spacy import displacy
import textacy  #0.12.0

## for graph
import networkx as nx  #3.0 (also pygraphviz==1.10)

## for timeline
import dateparser #1.1.7

Wikipedia-api是一个Python库,可轻松解析Wikipedia页面。我们将使用这个库来提取所需的页面,但会排除页面底部的所有"注释"和"参考文献"内容。

写出页面的名称

python 复制代码
topic = "Russo-Ukrainian War"

wiki = wikipediaapi.Wikipedia('en')
page = wiki.page(topic)
txt = page.text[:page.text.find("See also")]
txt[0:500] + " ..."

  • topic = "Russo-Ukrainian War":在这一行中,定义了一个名为 topic 的变量,其中存储了要查询的维基百科主题,即 "Russo-Ukrainian War"(俄乌战争)。
  • wiki = wikipediaapi.Wikipedia('en'):在这一行中,创建了一个名为 wiki 的维基百科API的实例,使用了英语语言版('en'表示英语)。
  • page = wiki.page(topic):这一行使用 wiki 实例的 page 方法来获取与主题 topic 相关的维基百科页面。这将返回一个包含页面内容的对象,存储在名为 page 的变量中。
  • txt = page.text[:page.text.find("See also")]:这一行代码从获取的维基百科页面文本中提取了感兴趣的部分。它使用了字符串切片和 .find() 方法,首先查找文本中 "See also"(通常表示相关链接的部分)的位置,然后将文本截断到这个位置之前,从而得到了页面的一部分文本。这部分文本存储在名为 txt 的变量中。
  • txt[0:500] + " ...":最后一行代码将前500个字符的文本内容提取出来,然后附加了 " ...",以表示文本的截断。这个结果存储在 txt 变量中,它包含了从维基百科页面提取的前500个字符的内容。

自然语言处理

python 复制代码
#python -m spacy download en_core_web_sm

nlp = spacy.load("en_core_web_sm")
doc = nlp(txt)
  • #python -m spacy download en_core_web_sm:这是一个注释行,用于表示在终端或命令行中执行的操作。它指示用户下载spaCy的英语语言模型"en_core_web_sm"。这个模型包括了一些用于处理英语文本的语言数据和算法。
  • nlp = spacy.load("en_core_web_sm"):在这一行代码中,首先导入了spaCy库(前提是已经安装了spaCy库)。然后,使用spacy.load()函数加载了之前下载的英语语言模型"en_core_web_sm"。加载后的模型被存储在名为nlp的变量中,以便后续对文本数据进行处理。
  • doc = nlp(txt):在这一行代码中,使用已加载的模型nlp对文本数据txt进行处理。nlp(txt)将文本数据传递给已加载的模型,返回一个Doc对象,其中包含了对文本进行了分词、词性标注、命名实体识别等自然语言处理任务的结果。这个Doc对象存储了文本的各种信息,可以用于进一步的文本分析和处理。

看SpaCy将文本分成了多少个句子:

python 复制代码
lst_docs = [sent for sent in doc.sents]
print("tot sentences:", len(lst_docs))

lst_docs = [sent for sent in doc.sents]:这一行代码使用了列表推导式(List Comprehension)来遍历doc对象中的每个句子,并将它们存储在一个名为lst_docs的列表中。列表推导式的语法是[expression for item in iterable],在这里,expression是用于生成列表元素的表达式,item是迭代的每个元素,iterable是要迭代的对象。因此,这行代码遍历doc.sents,它是doc对象中句子的一个生成器(generator) ,并将每个句子添加到lst_docs列表中。

词性标注

即用适当的语法标签标记句子中的每个单词的过程

可能标记的完整列表

  • ADJ: 形容词,例如big,old,green,incomprehensible,first
  • ADP: 介词,例如in,to,during
  • ADV: 副词,例如very,tomorrow,down,where,there
  • AUX: 助动词,例如is,has(done),will(do),should(do)
  • CONJ: 连词,例如and,or,but
  • CCONJ: 并列连词,例如and,or,but
  • DET: 限定词,例如a,an,the
  • INTJ: 感叹词,例如psst,ouch,bravo,hello
  • NOUN: 名词,例如girl,cat,tree,air,beauty
  • NUM: 数词,例如1,2017,one,seventy-seven,IV,MMXIV
  • PART: 助词,例如's,not
  • PRON: 代词,例如I,you,he,she,myself,themselves,somebody
  • PROPN: 专有名词,例如Mary,John,London,NATO,HBO
  • PUNCT: 标点符号,例如.,(,),?
  • SCONJ: 从属连词,例如if,while,that
  • SYM: 符号,例如$,%,§,©,+,-,×,÷,=,:),表情符号
  • VERB: 动词,例如run,runs,running,eat,ate,eating
  • X: 其他,例如sfpksdpsxmsa
  • SPACE: 空格

依存句法分析(Dependency Parsing,DEP)

模型还会尝试理解单词对之间的关系。

可能的标签完整列表

  • ACL:作为名词从句的修饰语
  • ACOMP:形容词补语
  • ADVCL:状语从句修饰语
  • ADVMOD:状语修饰语
  • AGENT:主语中的动作执行者
  • AMOD:形容词修饰语
  • APPOS:同位语
  • ATTR:主谓结构中的谓语部分
  • AUX:助动词
  • AUXPASS:被动语态中的助动词
  • CASE:格标记
  • CC:并列连词
  • CCOMP:从句补足语
  • COMPOUND:复合修饰语
  • CONJ:连接词
  • CSUBJ:主语从句
  • CSUBJPASS:被动语态中的主语从句
  • DATIVE:与双宾语动词相关的间接宾语
  • DEP:未分类的依赖
  • DET:限定词
  • DOBJ:直接宾语
  • EXPL:人称代词
  • INTJ:感叹词
  • MARK:标记
  • META:元素修饰语
  • NEG:否定修饰语
  • NOUNMOD:名词修饰语
  • NPMOD:名词短语修饰语
  • NSUBJ:名词从句主语
  • NSUBJPASS:被动语态中的名词从句主语
  • NUMMOD:数字修饰语
  • OPRD:宾语补足语
  • PARATAXIS:并列结构
  • PCOMP:介词的补足语
  • POBJ:介词宾语
  • POSS:所有格修饰语
  • PRECONJ:前置连词
  • PREDET:前置限定词
  • PREP:介词修饰语
  • PRT:小品词
  • PUNCT:标点符号
  • QUANTMOD:量词修饰语
  • RELCL:关系从句修饰语
  • ROOT:句子主干
  • XCOMP:开放性从句补足语

实例理解POS与DEP

python 复制代码
i = 3
list_docs[3]

检查 NLP 模型预测的 POS 和 DEP 标签

python 复制代码
for token in lst_docs[i]:
    print(token.text, "-->", "pos: "+token.pos_, "|", "dep: "+token.dep_, "")
  • token.text:token对象的text属性表示词汇的原始文本内容,即单词或标点符号的字符串。
  • "-->":这部分代码只是一个字符串,用于分隔词汇信息的不同部分,以便输出更易读。
  • "pos: "+token.pos_:token对象的pos_属性表示词汇的词性(Part-of-Speech,POS)。该部分将词汇的词性标签添加到输出中,例如:"pos: NOUN" 表示名词。
  • "|":这部分代码只是一个字符串,用于分隔不同词汇信息。
  • "dep: "+token.dep_:token对象的dep_属性表示词汇与句子中其他词汇的依存关系。该部分将词汇的依存关系标签添加到输出中,例如:"dep: nsubj" 表示名词主语。

可视化注释

SpaCy提供了一个图形工具来可视化这些注释

python 复制代码
from spacy import displacy

displacy.render(lst_docs[i], style="dep", options={"distance":100})

**displacy.render(lst_docs[i], style="dep", options={"distance":100}):**这是用于渲染句子依存关系图的函数调用。它包括以下参数:

  • lst_docs[i]:这是要可视化的文本数据,通常是一个Doc对象,或者在这里是句子的Doc对象,表示要可视化的句子。

  • style="dep":这个参数指定了可视化的样式。在这里,我们选择了"dep",表示依存关系图。

  • options={"distance":100}:这是一个字典参数,用于配置可视化选项。在这里,我们设置了"distance"参数,以控制词汇之间的水平距离。较大的距离可以使图更易于阅读。您可以根据需要自定义其他可视化选项。

  • 最重要的标记是动词 ( POS=VERB ),因为它是句子中含义的词根 ( DEP=ROOT )。
  • 助词,如副词和副词 ( POS=ADV/ADP ),通常作为修饰语 ( *DEP=mod ) 与动词相关联,因为它们可以修饰动词的含义。例如," travel to "和" travel from "具有不同的含义,即使词根相同(" travel ")。
  • 在与动词相连的单词中,必须有一些名词(POS=PROPN/NOUN )作为句子的主语和宾语( *DEP=nsubj/obj )。
  • 名词通常位于形容词 ( POS=ADJ ) 附近,作为其含义的修饰语 ( DEP=amod )。例如,在"好人 "和"坏人"中,形容词赋予名词_"人"相反的含义。

Spacy还可执行命名实体识别

可能的所有标签的完整列表
  • 人名: 包括虚构人物。
  • 国家、宗教或政治团体:民族、宗教或政治团体。
  • 地点:建筑、机场、高速公路、桥梁等。
  • 公司、机构等:公司、机构等。
  • 地理位置:国家、城市、州。
  • 地点:非国家地理位置,山脉、水域等。
  • 产品:物体、车辆、食品等(不包括服务)。
  • 事件:命名飓风、战斗、战争、体育赛事等。
  • 艺术作品:书籍、歌曲等的标题。
  • 法律:成为法律的指定文件。
  • 语言:任何命名的语言。
  • 日期:绝对或相对日期或期间。
  • 时间:小于一天的时间。
  • 百分比:百分比,包括"%"。
  • 货币:货币价值,包括单位。
  • 数量:衡量重量或距离等。
  • 序数: "第一","第二"等。
  • 基数:不属于其他类型的数字。
python 复制代码
for ent in lst_docs[i].ents:
    print(tag.text, f"({tag.label_})")

print(tag.text, f"({tag.label_})"):在每次迭代中,使用 print() 函数打印每个实体的文本内容和实体类型标签。

  • tag.text:这是实体对象的 text 属性,表示实体的原始文本内容。

  • f"({tag.label_})":这是一个格式化字符串,用于将实体的类型标签添加到输出中。在字符串中使用了f开头的字符串字面值,它允许在字符串中插入表达式,这里插入了实体的类型标签,标签位于括号中。

  • 花括号 {} 在格式化字符串中用于表示占位符,可以在运行时将变量或表达式的值插入到字符串中。

在spaCy中,实体(命名实体)对象通常包含两个重要的属性:ent.text 和 ent.label_,它们分别表示实体的文本内容和实体类型标签。

Spacy图形工具

python 复制代码
displacy.render(lst_docs[i], style="ent")

实体和关系抽取

对于每个句子,我们将提取主语和宾语以及它们的修饰语、复合词和它们之间的标点符号。

python 复制代码
## extract entities and relations
dic = {"id":[], "text":[], "entity":[], "relation":[], "object":[]}

for n,sentence in enumerate(lst_docs):
    lst_generators = list(textacy.extract.subject_verb_object_triples(sentence))  
    for sent in lst_generators:
        subj = "_".join(map(str, sent.subject))
        obj  = "_".join(map(str, sent.object))
        relation = "_".join(map(str, sent.verb))
        dic["id"].append(n)
        dic["text"].append(sentence.text)
        dic["entity"].append(subj)
        dic["object"].append(obj)
        dic["relation"].append(relation)


## create dataframe
dtf = pd.DataFrame(dic)

## example
dtf[dtf["id"]==i]

构建图表

网络图

Python标准库中用于创建和操作图网络的是NetworkX。我们可以从整个数据集开始创建图形,但如果节点太多,可视化将变得混乱:

python 复制代码
## create full graph
G = nx.from_pandas_edgelist(dtf, source="entity", target="object", 
                            edge_attr="relation", 
                            create_using=nx.DiGraph())


## plot
plt.figure(figsize=(15,10))

pos = nx.spring_layout(G, k=1)
node_color = "skyblue"
edge_color = "black"

nx.draw(G, pos=pos, with_labels=True, node_color=node_color, 
        edge_color=edge_color, cmap=plt.cm.Dark2, 
        node_size=2000, connectionstyle='arc3,rad=0.1')

nx.draw_networkx_edge_labels(G, pos=pos, label_pos=0.5, 
                         edge_labels=nx.get_edge_attributes(G,'relation'),
                         font_size=12, font_color='black', alpha=0.6)
plt.show()
  • G = nx.from_pandas_edgelist(dtf, source="entity", target="object", edge_attr="relation", create_using=nx.DiGraph()):这行代码使用 NetworkX 库创建了一个有向图(DiGraph)。具体解释如下:
  • nx.from_pandas_edgelist(dtf, source="entity", target="object", edge_attr="relation", create_using=nx.DiGraph()) :这个函数将 Pandas 数据帧 dtf 转换为一个有向图。在有向图中,实体作为节点,关系作为有向边,而 "entity" 列和 "object" 列包含了节点之间的连接,"relation" 列包含了边的属性(关系)。
  • plt.figure(figsize=(15,10)):这行代码创建一个新的图形画布,指定了画布的大小为 15x10 像素。
  • pos = nx.spring_layout(G, k=1):这行代码使用 NetworkX 的 spring_layout 函数布局图形中的节点位置,其中 G 是创建的有向图。k=1 控制了节点之间的相互排斥力,影响图形的布局。
  • node_color 和 edge_color:这两行代码定义了节点和边的颜色。
  • nx.draw(...):这个函数用于绘制图形。以下是参数的含义:
  • G:要绘制的图形。
  • pos=pos:节点位置的布局。
  • with_labels=True:是否显示节点的标签。
  • node_color=node_color:节点的颜色。
  • edge_color=edge_color:边的颜色。
  • cmap=plt.cm.Dark2:用于定义节点颜色映射的颜色映射。
  • nx.draw_networkx_edge_labels(...):这个函数用于在图形上绘制边的标签。以下是参数的含义:
  • pos=pos:节点位置的布局。
  • label_pos=0.5:标签相对于边的位置。
  • edge_labels=nx.get_edge_attributes(G,'relation'):从图中获取边的属性(关系)作为标签。
  • font_size=12:标签的字体大小。
  • font_color='black':标签的字体颜色。
  • alpha=0.6:标签的透明度。
  • plt.show():这行代码用于显示绘制好的图形。

知识图谱可以让我们从大局的角度看到所有事物的相关性,但是如果直接看整张图就没有什么用处。因此,最好根据我们所需的信息应用一些过滤器。对于这个例子,我将只选择涉及最常见实体的部分(基本上是最多连接的节点):

先找出最多连接的节点

python 复制代码
dtf["entity"].value_counts().head()

然后进行过滤操作并进行可视化

python 复制代码
## filter
f = "Russia"
tmp = dtf[(dtf["entity"]==f) | (dtf["object"]==f)]


## create small graph
G = nx.from_pandas_edgelist(tmp, source="entity", target="object", 
                            edge_attr="relation", 
                            create_using=nx.DiGraph())


## plot
plt.figure(figsize=(15,10))

pos = nx.spring_layout(G, k=0.5)
node_color = ["red" if node==f else "skyblue" for node in G.nodes]
edge_color = ["red" if edge[0]==f else "black" for edge in G.edges]

nx.draw(G, pos=pos, with_labels=True, node_color=node_color, 
        edge_color=edge_color, cmap=plt.cm.Dark2, 
        node_size=800, node_shape="o", width=1.0, connectionstyle='arc3,rad=0.1', font_size=8)

nx.draw_networkx_edge_labels(G, pos=pos, label_pos=0.5, 
                        edge_labels=nx.get_edge_attributes(G,'relation'),
                        font_size=8, font_color='black', alpha=0.6)
plt.show()

对于Ukraine的效果图

​​​​​​​

相关推荐
Jsundoku9 分钟前
第四章 深度学习 -- 训练技巧
人工智能·深度学习
HDU-Dade40 分钟前
【校招笔试真题】简要介绍 Self-Attention 的前沿算法
人工智能·算法
在所不辞兄1 小时前
【零基础学智能仿真-63】ABACUS作业工具与MCP接口
人工智能·深度学习·神经网络·机器学习·智能仿真
楚山之石1 小时前
【Medical Image Analysis】深度学习医学图像合成综述:伪CT、合成MRI与合成PET的架构、性能与临床边界
图像处理·人工智能·学习·mr·mri
blackappleD2 小时前
百度 Unlimited OCR 2 拆解:SR-SWA 如何让百页文档的 KV 缓存不再涨
人工智能·llm
数字新视界2 小时前
国产动环数据库在智能机房环境监控中的应用与优势分析
大数据·人工智能·数据中心·机房管理·模块化机房
holly就是我2 小时前
AI 编程助手为什么跑偏?用开源 ccglass 看清 Prompt、工具调用和 Token 消耗
人工智能·后端
雨中飘荡的记忆2 小时前
额度又见底了?这个开源项目,给 AI 编程助手接上 61 家"加油站"
人工智能
天远Date Lab2 小时前
零信任架构实战:基于天远企业年报信息核验构建自动化商业保理财务与社保穿透评估网关
人工智能·架构·自动化
EnCi Zheng2 小时前
后端怎么把AI接口稳定安全低成本接进业务:超时重试、密钥隔离与成本熔断清单
人工智能·后端·安全·架构·api