您当前的位置:首页 > 电脑百科 > 软件技术 > 软件技术

如何使用 Neo4J 和 Transformer 构建知识图谱

时间:2022-03-28 11:46:45  来源:  作者:InfoQ
如何使用 Neo4J 和 Transformer 构建知识图谱

 

本文最初发布于 Towards Data Science。

如何使用 Neo4J 和 Transformer 构建知识图谱

 

图片由作者提供:Neo4j中的知识图谱

简介

 

在这篇文章中,我将展示如何使用经过优化的、基于转换器的命名实体识别(NER)以及 spaCy 的关系提取模型,基于职位描述创建一个知识图谱。这里介绍的方法可以应用于其他任何领域,如生物医学、金融、医疗保健等。

 

以下是我们要采取的步骤:

 

  • 在 google Colab 中加载优化后的转换器 NER 和 spaCy 关系提取模型;
  • 创建一个 Neo4j Sandbox,并添加实体和关系;
  • 查询图,找出与目标简历匹配度最高的职位,找出三个最受欢迎的技能和共现率最高的技能。

 

要了解关于如何使用 UBIAI 生成训练数据以及优化 NER 和关系提取模型的更多信息,请查看以下文章。

 

  • UBIAI:简单易用的NLP应用程序文本标注
  • 如何使用BERT转换器与spaCy3训练一个联合实体和关系提取分类器
  • 如何使用spaCy3优化BERT转换器

 

职位描述数据集可以从Kaggle获取。

 

在本文结束的时候,我们就可以创建出如下所示的知识图谱。

如何使用 Neo4J 和 Transformer 构建知识图谱

 

图片由作者提供:职位描述的知识图谱

命名实体和关系提取

 

首先,我们加载 NER 和关系模型的依赖关系,以及之前优化过的 NER 模型本身,以提取技能、学历、专业和工作年限:

 

!pip install -U pip setuptools wheel
!Python/ target=_blank class=infotextkey>Python -m spaCy project clone tutorials/rel_component
!pip install -U spaCy-nightly --pre
!!pip install -U spaCy transformers
import spaCy
#安装完依赖项后重启运行时
nlp = spaCy.load("[PATH_TO_THE_MODEL]/model-best")

 

加载我们想从中提取实体和关系的职位数据集:

 

import pandas as pd
def get_all_documents():
df = pd.read_csv("/content/drive/MyDrive/job_DB1_1_29.csv",sep='"',hea
der=None)
documents = []
for index,row in df.iterrows():
documents.Append(str(row[0]))
return documents
documents = get_all_documents()
documents = documents[:]

 

从职位数据集中提取实体:

 

import hashlib
def extract_ents(documents,nlp):  
docs = list()  
for doc in nlp.pipe(documents, disable=["tagger", "parser"]):      
dictionary=dict.fromkeys(["text", "annotations"])      
dictionary["text"]= str(doc)      
dictionary['text_sha256'] =  hashlib.sha256(dictionary["text"].encode('utf-8')).hexdigest()      
annotations=[]


for e in doc.ents:        
ent_id = hashlib.sha256(str(e.text).encode('utf-8')).hexdigest()        
ent = {"start":e.start_char,"end":e.end_char, "label":e.label_,"label_upper":e.label_.upper(),"text":e.text,"id":ent_id}        
if e.label_ == "EXPERIENCE":          
ent["years"] = int(e.text[0])        
annotations.append(ent)


dictionary["annotations"] = annotations      
docs.append(dictionary)  
#print(annotations)  
return docs
parsed_ents = extract_ents(documents,nlp)

 

在将实体提供给关系提取模型之前,我们可以看下提取出的部分实体:

 

[('stock market analysis', 'SKILLS'),
('private investor', 'SKILLS'), 
('C++', 'SKILLS'), 
('Investment Software', 'SKILLS'),
('MS windows', 'SKILLS'), 
('web development', 'SKILLS'), 
('Computer Science', 'DIPLOMA_MAJOR'),
('AI', 'SKILLS'),
('software development', 'SKILLS'),
('coding', 'SKILLS'),
('C', 'SKILLS'), 
('C++', 'SKILLS'),
('Visual Studio', 'SKILLS'),
('2 years', 'EXPERIENCE'), 
('C/C++ development', 'SKILLS'), 
('data compression', 'SKILLS'),
('financial markets', 'SKILLS'),
('financial calculation', 'SKILLS'),
('GUI design', 'SKILLS'),
('Windows development', 'SKILLS'), 
('MFC', 'SKILLS'), 
('Win', 'SKILLS'),
('HTTP', 'SKILLS'),
('TCP/IP', 'SKILLS'),
('sockets', 'SKILLS'), 
('.NETwork programming', 'SKILLS'), 
('System administration', 'SKILLS')]

 

我们现在准备好预测关系了;首先加载关系提取模型,务必将目录改为 rel_component/scripts 以便可以访问关系模型的所有必要脚本。

 

cd rel_component/

 

import random
import typer
from pathlib import Path
import spaCy
from spaCy.tokens import DocBin, Doc
from spaCy.training.example import Example
#使factory生效
from rel_pipe import make_relation_extractor, score_relations
#使config生效
from rel_model import create_relation_model, create_classification_layer, create_instances, create_tensors
#安装完依赖项后重启运行时
nlp2 = spaCy.load("/content/drive/MyDrive/training_rel_roberta/model-best")
def extract_relations(documents,nlp,nlp2):
 predicted_rels = list()
for doc in nlp.pipe(documents, disable=["tagger", "parser"]):
 source_hash = hashlib.sha256(doc.text.encode('utf-8')).hexdigest()
for name, proc in nlp2.pipeline:
 doc = proc(doc)
for value, rel_dict in doc._.rel.items():
for e in doc.ents:
for b in doc.ents:
if e.start == value[0] and b.start == value[1]:
 max_key = max(rel_dict, key=rel_dict. get)
#print(max_key)
 e_id = hashlib.sha256(str(e).encode('utf-8')).hexdigest()
 b_id = hashlib.sha256(str(b).encode('utf-8')).hexdigest()
if rel_dict[max_key] >=0.9 :
#print(f" entities: {e.text, b.text} --> predicted relation: {rel_dict}")
 predicted_rels.append({'head': e_id, 'tail': b_id, 'type':max_key, 'source': source_hash})
return predicted_rels
predicted_rels = extract_relations(documents,nlp,nlp2)

 

Predicted relations:  
entities: ('5+ years', 'software engineering') --> predicted relation: {'DEGREE_IN': 9.5471655e-08, 'EXPERIENCE_IN': 0.9967771} 
entities: ('5+ years', 'technical management') --> predicted relation: {'DEGREE_IN': 1.1285037e-07, 'EXPERIENCE_IN': 0.9961034}  entities: ('5+ years', 'designing') --> predicted relation:{'DEGREE_IN': 1.3603304e-08, 'EXPERIENCE_IN': 0.9989103}  
entities: ('4+ years', 'performance management') --> predicted relation: {'DEGREE_IN': 6.748373e-08, 'EXPERIENCE_IN': 0.92884386}

 

Neo4J

 

现在,我们可以加载职位数据集,并将数据提取到 Neo4j 数据库中了。

首先,我们创建一个空的Neo4j Sandbox,并添加连接信息,如下所示:

 

documents = get_all_documents()
documents = documents[:]
parsed_ents = extract_ents(documents,nlp)
predicted_rels = extract_relations(documents,nlp,nlp2)
#neo4j的基础查询功能
from neo4j import GraphDatabase
import pandas as pd
host = 'bolt://[your_host_address]'
user = 'neo4j'
password = '[your_password]'
driver = GraphDatabase.driver(host,auth=(user, password))
def neo4j_query(query, params=None):
with driver.session() as session:
 result = session.run(query, params)
return pd.DataFrame([r.values() for r in result], columns=result.keys())

 

接下来,我们将文档、实体和关系添加到知识图谱中。注意,我们需要从实体 EXPERIENCE 的 name 中提取出整数年限,并将其作为一个属性存储起来。

#清空当前的Neo4j Sandbox db (删除所有东西)
neo4j_query("""
MATCH (n) DETACH DELETE n;
""")
#创建第一个主节点
neo4j_query("""
MERGE (l:LaborMarket {name:"Labor Market"})
RETURN l
""")
#向KG中添加实体:技能、经验、学历、专业
neo4j_query("""
MATCH (l:LaborMarket)
UNWIND $data as row
MERGE (o:Offer{id:row.text_sha256})
SET o.text = row.text
MERGE (l)-[:HAS_OFFER]->(o)
WITH o, row.annotations as entities
UNWIND entities as entity
MERGE (e:Entity {id:entity.id})
ON CREATE SET
 e.name = entity.text,
 e.label = entity.label_upper
MERGE (o)-[m:MENTIONS]->(e)
ON CREATE SET m.count = 1
ON MATCH SET m.count = m.count + 1
WITH e as e
CALL apoc.create.addLabels( id(e), [ e.label ] )
YIELD node
REMOVE node.label
RETURN node
""", {'data': parsed_ents})
#为实体EXPERIENCE添加属性'name'
res = neo4j_query("""
MATCH (e:EXPERIENCE)
RETURN e.id as id, e.name as name
""")
#从EXPERIENCE name中提取工作年限,并保存在属性years中
import re
def get_years(name):
return re.findall(r"d+",name)[0]
res["years"] = res.name.map(lambda name: get_years(name))
data = res.to_dict('records')
#为实体EXPERIENCE添加属性'years'
neo4j_query("""
UNWIND $data as row
MATCH (e:EXPERIENCE {id:row.id})
SET e.years = row.years
RETURN e.name as name, e.years as years
""",{"data":data})
#将关系添加到KG
neo4j_query("""
UNWIND $data as row
MATCH (source:Entity {id: row.head})
MATCH (target:Entity {id: row.tail})
MATCH (offer:Offer {id: row.source})
MERGE (source)-[:REL]->(r:Relation {type: row.type})-[:REL]->(target)
MERGE (offer)-[:MENTIONS]->(r)
""", {'data': predicted_rels})

 

现在开始进入有趣的部分了。我们可以启动知识图谱并运行查询了。让我们运行一个查询,找出与目标简历最匹配的职位:

 

#在表中显示最佳匹配项
other_id = "8de6e42ddfbc2a8bd7008d93516c57e50fa815e64e387eb2fc7a27000ae904b6"
query = """
MATCH (o1:Offer {id:$id})-[m1:MENTIONS]->(s:Entity)<- [m2:MENTIONS]-(o2:Offer)
RETURN DISTINCT o1.id as Source,o2.id as Proposed_Offer, count(*) as freq, collect(s.name) as common_terms
ORDER BY freq
DESC LIMIT $limit
"""
res = neo4j_query(query,{"id":other_id,"limit":3})
res
#在neo4j浏览器中,使用该查询显示最佳匹配项的图
"""MATCH (o1:Offer {id:"8de6e42ddfbc2a8bd7008d93516c57e50fa815e64e387eb2fc7a27000ae904b6"})-[m1:MENTIONS]->(s:Entity)<- [m2:MENTIONS]-(o2:Offer)
WITH o1,s,o2, count(*) as freq
MATCH (o1)--(s)
RETURN collect(o2)[0], o1,s, max(freq)"""

 

以表格形式显示的结果中的公共实体:

如何使用 Neo4J 和 Transformer 构建知识图谱

 

以可视化形式显示的图:

如何使用 Neo4J 和 Transformer 构建知识图谱

 

图片由作者提供:基于最佳匹配职位

 

虽然这个数据集只有 29 个职位描述,但这里介绍的方法可以应用于有成千上万个职位的大规模数据集。只需几行代码,我们立马就可以提取出与目标简历匹配度最高的工作。

 

下面,让我们找出最需要的技能:

 

query = """
MATCH (s:SKILLS)<-[:MENTIONS]-(o:Offer)
RETURN s.name as skill, count(o) as freq
ORDER BY freq DESC
LIMIT 10
"""
res = neo4j_query(query)
res

 

如何使用 Neo4J 和 Transformer 构建知识图谱

 

以及需要最高工作年限的技能:

 

query = """
MATCH (s:SKILLS)--(r:Relation)--(e:EXPERIENCE) where r.type = "EXPERIENCE_IN"
return s.name as skill,e.years as years
ORDER BY years DESC
LIMIT 10
"""
res = neo4j_query(query)
res

 

如何使用 Neo4J 和 Transformer 构建知识图谱

 

Web 开发和技术支持需要的工作年限最高,然后是安全设置。

 

最后,让我们查下共现率最高的技能对:

 

neo4j_query("""
MATCH (s1:SKILLS)<-[:MENTIONS]-(:Offer)-[:MENTIONS]->(s2:SKILLS)
WHERE id(s1) < id(s2)
RETURN s1.name as skill1, s2.name as skill2, count(*) as cooccurrence
ORDER BY cooccurrence
DESC LIMIT 5
""")

 

如何使用 Neo4J 和 Transformer 构建知识图谱

 

小结

 

在这篇文章中,我们描述了如何利用基于转换器的 NER 和 spaCy 的关系提取模型,用 Neo4j 创建知识图谱。除了信息提取之外,图的拓扑结构还可以作为其他机器学习模型的输入。

 

将 NLP 与图数据库 Neo4j 相结合,可以加速许多领域的信息发现,相比之下,在医疗和生物医学领域的应用效果更为显著。

 

如果你有任何问题或希望为具体用例创建自定义模型,请给我们发邮件(admin@ubiai.tools),或是在 Twitter 上给我们留言(@UBIAI5)。

 

原文链接:How to Build a Knowledge Graph with Neo4J and Transformers

 

 

 

进入 InfoQ 官网,了解一线软件开发及相关领域知识~https://www.infoq.cn/



Tags:Neo4J   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
如何使用 Neo4J 和 Transformer 构建知识图谱
本文最初发布于 Towards Data Science。 图片由作者提供:Neo4j中的知识图谱简介 在这篇文章中,我将展示如何使用经过优化的、基于转换器的命名实体识别(NER)以及 spaCy 的关系...【详细内容】
2022-03-28  Search: Neo4J  点击:(381)  评论:(0)  加入收藏
▌简易百科推荐
如何在Windows 10中查看电脑的名称?这里提供详细步骤
你想在有多台计算机组成的网络上查找你的计算机吗?一种方法是找到你的电脑名称,然后在网络上匹配该名称。下面是如何在Windows 10中使用图形和命令行方法查看你的计算机名称。...【详细内容】
2024-04-10  驾驭信息纵横科技    Tags:Windows 10   点击:(6)  评论:(0)  加入收藏
移动版 Outlook 解锁新技能,可验证登录 OneDrive 等微软服务
IT之家 4 月 9 日消息,微软公司近日发布新闻稿,宣布用户可以使用 Outlook 手机应用,轻松登录 Teams、OneDrive、Microsoft 365 以及 Windows 等微软账号服务。移动端 Outlook...【详细内容】
2024-04-09    IT之家  Tags:Outlook   点击:(7)  评论:(0)  加入收藏
Win10/Win11和 macOS用户反馈:谷歌云服务“捆绑”系统 DNS 设置
IT之家 4 月 6 日消息,谷歌公司承认旗下的 Google One 订阅服务中存在问题,在 Windows 10、Windows 11 以及 macOS 系统上会更改系统 DNS 设置,变更为 8.8.8.8 地址。Google On...【详细内容】
2024-04-08    IT之家  Tags:Win10   点击:(10)  评论:(0)  加入收藏
电脑卡顿怎么重装系统,快看这篇
电脑卡顿时,重装系统确实是一种可能的解决方案。以下是重装系统的详细步骤:备份重要数据:首先,你需要将电脑中的重要文件和数据备份到外部存储设备(如U盘、移动硬盘或云存储)中,以...【详细内容】
2024-04-04  科技数码前锋    Tags:重装系统   点击:(4)  评论:(0)  加入收藏
如何检查电脑的最近历史记录?这里提供详细步骤
如果你怀疑有人在使用你的计算机,并且你想查看他们在做什么,下面是如何查看是否有访问内容的痕迹。如何检查我的计算机的最近历史记录要检查计算机的最近历史记录,应该从web浏...【详细内容】
2024-03-30  驾驭信息纵横科技    Tags:历史记录   点击:(6)  评论:(0)  加入收藏
关于Windows中AppData的相关知识,看这篇文章就可以了
如果AppData文件夹占用了你电脑上的太多空间,则需要清理AppData文件夹。下面是一些帮助你在Windows计算机上进行AppData清理的方法。什么是AppData文件夹AppData文件夹是保存...【详细内容】
2024-03-30  驾驭信息纵横科技    Tags:AppData   点击:(10)  评论:(0)  加入收藏
微软 Edge 浏览器将迎来“内存限制器”功能,用户可自主控制 Edge 内存占用
IT之家 3 月 28 日消息,微软即将为其 Edge 浏览器带来一项实用新功能,据悉该公司正在测试一项内置的内存限制器,这项功能可以让用户限制 Edge 所占用的内存,防止浏览器超出内存...【详细内容】
2024-03-29    IT之家  Tags:Edge   点击:(21)  评论:(0)  加入收藏
一寸照片的大小如何压缩?四个实测效果很好的方法
一寸照片作为生活中常见的尺寸之一,常用于各类证件照与证明文件的制作。然而,受限于其较为狭小的尺寸,上传及打印过程中很容易出现尺寸超限的情况。所以,这个时候就需要对其体积...【详细内容】
2024-03-18  宠物小阿涛    Tags:压缩   点击:(19)  评论:(0)  加入收藏
手机投屏到电脑/电视的方法
方法一:Win10自带的投影功能1、将手机和电脑连接同一个无线网络。2、选择【开始】>【设置】>【系统】>【投影到此电脑】3、将默认的始终关闭的选项更改为所有位置都可用。4、...【详细内容】
2024-03-18    老吴讲I  Tags:投屏   点击:(19)  评论:(0)  加入收藏
微软商店怎么卸载应用 一分钟快速看懂!
微软商店怎么卸载应用 一分钟快速看懂!微软公司(Microsoft Corporation)是一家全球领先的科技企业,总部位于美国华盛顿州的雷德蒙德。成立于1975年,由比尔&middot;盖茨和保罗&mid...【详细内容】
2024-02-27  婷婷说体育    Tags:微软商店   点击:(42)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条