python 知识图谱 包_python从零开始构建知识图谱笔记

教程:https://zhuanlan.zhihu.com/p/243211697

前面都进行的好好的,具体的理论因为我已经了解一点了,就不在赘述,教程里面有,直接开始实践,

前面都没啥问题,直接上代码

image.png

image.png

import re

import pandas as pd

import numpy as np

import bs4

import requests

import spacy

from spacy import displacy

nlp = spacy.load(‘en_core_web_sm’)

from spacy.matcher import Matcher

from spacy.tokens import Span

import networkx as nx

import matplotlib.pyplot as plt

from tqdm import tqdm

pd.set_option(‘display.max_colwidth’, 200)

%matplotlib inline

import wikipedia sentences

candidate_sentences = pd.read_csv(“wiki_sentences_v2.csv”,header=0)

candidate_sentences.shape

candidate_sentences.sample(7)

doc = nlp(“the drawdown process is governed by astm standard d823”)

for tok in doc:

print(tok.text, “…”, tok.dep_)

好了接下来重点在这里,接下来的一个函数,怎么也对不起行列,出来的答案为空,很奇怪

def get_entities(sent):

chunk 1

我在这个块中定义了一些空变量。prv tok dep和prv tok text将分别保留句子中前一个单词和前一个单词本身的依赖标签。前缀和修饰符将保存与主题或对象相关的文本。

ent1 = “”

ent2 = “”

prv_tok_dep = “” # dependency tag of previous token in the sentence

prv_tok_text = “” # previous token in the sentence

prefix = “”

modifier = “”

for tok in nlp(sent):

chunk 2

接下来,我们将遍历句子中的记号。我们将首先检查标记是否为标点符号。如果是,那么我们将忽略它并转移到下一个令牌。如果标记是复合单词的一部分(dependency tag = compound),我们将把它保存在prefix变量中。复合词是由多个单词组成一个具有新含义的单词(例如”Football Stadium”, “animal lover”)。

当我们在句子中遇到主语或宾语时,我们会加上这个前缀。我们将对修饰语做同样的事情,例如”nice shirt”, “big house”

if token is a punctuation mark then move on to the next token

if tok.dep_ != “punct”:

check: token is a compound word or not

if tok.dep_ == “compound”:

prefix = tok.text

if the previous word was also a ‘compound’ then add the current word to it

if prv_tok_dep == “compound”:

prefix = prv_tok_text + ” “+ tok.text

check: token is a modifier or not

if tok.dep_.endswith(“mod”) == True:

modifier = tok.text

if the previous word was also a ‘compound’ then add the current word to it

if prv_tok_dep == “compound”:

modifier = prv_tok_text + ” “+ tok.text

chunk 3

在这里,如果令牌是主语,那么它将作为ent1变量中的第一个实体被捕获。变量如前缀,修饰符,prv tok dep,和prv tok文本将被重置。

if tok.dep_.find(“subj”) == True:

ent1 = modifier +” “+ prefix + ” “+ tok.text

prefix = “”

modifier = “”

prv_tok_dep = “”

prv_tok_text = “”

chunk 4

在这里,如果令牌是宾语,那么它将被捕获为ent2变量中的第二个实体。变量,如前缀,修饰符,prv tok dep,和prv tok文本将再次被重置。

if tok.dep_.find(“obj”) == True:

ent2 = modifier +” “+ prefix +” “+ tok.text

chunk 5

一旦我们捕获了句子中的主语和宾语,我们将更新前面的标记和它的依赖标记。

update variables

prv_tok_dep = tok.dep_

prv_tok_text = tok.text

return [ent1.strip(), ent2.strip()]

get_entities(“the film had 200 patents”)

def get_entities(sent):

chunk 1

我在这个块中定义了一些空变量。prv tok dep和prv tok text将分别保留句子中前一个单词和前一个单词本身的依赖标签。前缀和修饰符将保存与主题或对象相关的文本。

ent1 = “”

ent2 = “”

prv_tok_dep = “” # dependency tag of previous token in the sentence

prv_tok_text = “” # previous token in the sentence

prefix = “”

modifier = “”

for tok in nlp(sent):

chunk 2

接下来,我们将遍历句子中的记号。我们将首先检查标记是否为标点符号。如果是,那么我们将忽略它并转移到下一个令牌。如果标记是复合单词的一部分(dependency tag = compound),我们将把它保存在prefix变量中。复合词是由多个单词组成一个具有新含义的单词(例如”Football Stadium”, “animal lover”)。

当我们在句子中遇到主语或宾语时,我们会加上这个前缀。我们将对修饰语做同样的事情,例如”nice shirt”, “big house”

if token is a punctuation mark then move on to the next token

if tok.dep_ != “punct”:

check: token is a compound word or not

if tok.dep_ == “compound”:

prefix = tok.text

if the previous word was also a ‘compound’ then add the current word to it

if prv_tok_dep == “compound”:

prefix = prv_tok_text + ” “+ tok.text

check: token is a modifier or not

if tok.dep_.endswith(“mod”) == True:

modifier = tok.text

if the previous word was also a ‘compound’ then add the current word to it

if prv_tok_dep == “compound”:

modifier = prv_tok_text + ” “+ tok.text

chunk 3

在这里,如果令牌是主语,那么它将作为ent1变量中的第一个实体被捕获。变量如前缀,修饰符,prv tok dep,和prv tok文本将被重置。

if tok.dep_.find(“subj”) == True:

ent1 = modifier +” “+ prefix + ” “+ tok.text

prefix = “”

modifier = “”

prv_tok_dep = “”

prv_tok_text = “”

chunk 4

在这里,如果令牌是宾语,那么它将被捕获为ent2变量中的第二个实体。变量,如前缀,修饰符,prv tok dep,和prv tok文本将再次被重置。

if tok.dep_.find(“obj”) == True:

ent2 = modifier +” “+ prefix +” “+ tok.text

chunk 5

一旦我们捕获了句子中的主语和宾语,我们将更新前面的标记和它的依赖标记。

update variables

prv_tok_dep = tok.dep_

prv_tok_text = tok.text

return [ent1.strip(), ent2.strip()]

get_entities(“the film had 200 patents”)

image.png

在这里因为之前的教程里面的内容数据下载不到,就自己复制了一些,

image.png

因为原来读入进去有两列,是因为自己的文件不是csv的,现在,直接做一个excel,另存为–其他格式,然后就可以保存为csv文件了,读入进去就正常很多了。

因为这里文件没法上传到简书,所以就给大家看看。还是很简单能做出来的。。。

达到了预期效果,我们对数据集中的句子使用这个函数,提取这些句子中的实体对:

image.png

image.png

好像和正确的不太一样

image.png

原来是这样,因为我的数据只有五句话,没有人家的多,所以根本没有十个到二十个,所以为空,接着我把他调小,就可以了,看起来还行,

原文中还有,

image.png

“如你所见,在这些实体对中有一些代词,如we, it, she等。我们希望用专有名词或名词来代替。也许我们可以进一步改进get entities()函数来过滤代词。但是指代消解是比较高级的技术,现在,让我们让它保持原样,继续到关系提取部分。”

所以这个后来在看看指代消解技术。

关系抽取Relation / Predicate Extraction

“句子中捕获这样的谓词。在这里,我使用了spaCy的基于规则的匹配”

绝望了,这篇老是对不齐,但是这句还好不难对齐

抽提句子关系,,V

def get_relation(sent):

doc = nlp(sent)

Matcher class object

matcher = Matcher(nlp.vocab)

define the pattern

pattern = [{‘DEP’:’ROOT’},

{‘DEP’:’prep’,’OP’:”?”},

{‘DEP’:’agent’,’OP’:”?”},

{‘POS’:’ADJ’,’OP’:”?”}]

matcher.add(“matching_1”, None, pattern)

matches = matcher(doc)

k = len(matches) – 1

span = doc[matches[k][1]:matches[k][2]]

return(span.text)

函数中定义的模式试图找到句子中的词根或主要动词。一旦确定了词根,该模式就会检查它后面是介词(prep)还是代理词。如果是,则将其添加到根词中。试试一下这个函数:

get_relation(“John completed the task”)

image.png

没得问题了。

用在我们的数据集上:

对了人家的数据有名字sentence所以是这样的:

relations = [get_relation(i) for i in tqdm(candidate_sentences[‘sentence’])]

pd.Series(relations).value_counts()[:50]

但是我是自己做的,所以没有名字,都把这个名字删掉就行。

image.png

relations = [get_relation(i) for i in tqdm(candidate_sentences)]

pd.Series(relations).value_counts()[:2]

image.png

但是这个函数可能需要改改,因为我的数据及的结果只有一个is

以下是我的数据集,可以看出来绝对不止一个is是动词,

image.png

可能 因为作者的数据集都是主谓宾这样的形式,但是我们的还加了前置和倒装什么的,不只是主谓宾,还有主谓的,他就识别不好,

5、构建知识图谱Build a Knowledge Graph

最后,我们将从提取的实体(主语-宾语对)和谓词(实体之间的关系)创建知识图。

让我们创建一个实体和谓词的dataframe:

extract subject

source = [i[0] for i in entity_pairs]

extract object

target = [i[1] for i in entity_pairs]

kg_df = pd.DataFrame({‘source’:source, ‘target’:target, ‘edge’:relations})

create a directed-graph from a dataframe

G=nx.from_pandas_edgelist(kg_df, “source”, “target”, edge_attr=True, create_using=nx.MultiDiGraph())

plt.figure(figsize=(12,12))

pos = nx.spring_layout(G)

nx.draw(G, with_labels=True, node_color=’skyblue’, edge_cmap=plt.cm.Blues, pos = pos)

plt.show()

但是因为作者的数据集比较大,所以还需要重新提出来看,但是我的这个哈哈哈就不需要了,太少了实在是。

image.png

END!!!!

Original: https://blog.csdn.net/weixin_29594291/article/details/112829628
Author: zhongxiao.yzx
Title: python 知识图谱 包_python从零开始构建知识图谱笔记

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/556723/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球