neo4j构建知识图谱
(python编程疫情知识图谱)
一、知识图谱简介
略过历史,说说我自己对知识图谱的理解。知识图谱很简单理解,知识+图。以图的形式展示知识就是知识图谱。而这里的知识泛指一切,所以很容易理解,即一切都以图的形式展示,这就是知识图(我懂,不一定对)!
好吧,既然如此,我们直接上图,帮助大家更好的理解什么叫知识图谱
抱歉,这是什么?
这就是知识,因为据我了解,知识是指一切
所以他是知识! (看来和课本上学的知识差距这么大,手工狗头……)
好吧,让我们看另一张照片!
这是什么?这就是知识图谱,是不是很直观?
无非就是把上面提到的知识提取到我使用的所有东西中,然后形象化。
正式来说,知识图谱无非是由许多三元组组成的一系列关系数据库,以三元组的形式存储,并以图的形式展示。所以知识图就是这么简单。
其实,我个人认为构建知识图谱的目的不在于构建,而在于利用构建好的知识图谱(现有的知识)去推测未知的知识,这才是知识图谱的重要之处。比如说就拿我上述的例子来看,上述例子为年前郑州疫情的例子。数据获取就是从郑州发布公众号中获取到知识,然后再用neo4j这个软件去搭建这样一个图谱,再通过neo4j数据库的语言去进行分析,获取到一些有用的知识。为了直观展示,再给大家看一个图
很直观的,病例18和病例28之间说让没有什么关系,当时他们却去过很多相同的地方,那这些地方就很可能是高危感染疫情的地方。我们所得到的高危感染疫情的这个知识,就是未知的知识。我们通过构建知识图谱所获取到的知识。
构建知识图谱的步骤
好吧,既然如此,我们就简单梳理一下需要做的几个问题。
1.知识从何而来?
在万物互联的时代,知识当然必须来自爬行动物。因此,对于这个例子,我们获取的所有知识都是从公众号所在的网页爬取的。
具体学习爬虫相关的知识,请看我的其他博客:https://blog.csdn.net/petrichor316/category_11603104.html
2. 地图从何而来?
利用neo4j软件,在python编程平台通过py2neo函数包进行构建三元组关系,也就是我们的图谱。
3.未知知识从何而来?
通过neo4j软件他的数据库语言进行分析而来。
简要演示代码:
一、爬取知识:
通过最近的网页获取所有相关网页
def gettitle(self):
"""获取到活动轨迹的通报以及病例"""
req = requests.get(url=self.target)
req.encoding = 'utf-8'
html = req.text
# 获取到文本及网址信息
bs = BeautifulSoup(html, 'lxml')
headlines = bs.find('section', style="font-size: 16px;white-space: normal;")
headlines = headlines.find_all('a')
# title1 = bs.find('h1', id="activity-name").string
# 得到所有的网址
websites = []
titles = []
websites.append(self.target)
# titles.append(title1)
for headline in headlines:
# print('爬取网址中...',headline)
website = headline.get('href')
# title = headline.find('span').string
# print(title)
# titles.append(title)
print('爬取网页中...',website)
websites.append(website)
websites.append('https://mp.weixin.qq.com/s/MenNRSpSA5ORNGtjosfZLw')
websites.append('https://mp.weixin.qq.com/s/PLyt4qip04CBp8jF9wXO9g')
# time.sleep(1)
print('爬取完毕,正在整理数据,马上呈现......')
# texts.append(text)
# print(websites)
# print(titles)
return websites
然后获取网页中的所有内容。
由于网页标签不规范,导致代码太长,只显示部分源代码。
2.构建地图
创建三元组中的每个节点
def CreateNode(self):
"""创建病例的节点"""
for names in self.perdir:
ids = self.perdir[names]['属性']['姓名']
trenders = self.perdir[names]['属性']['性别']
ages = self.perdir[names]['属性']['年龄']
# print(ids,trenders,ages)
add = []
fri = []
adds = ()
fris = ()
for attrs in self.perdir[names]['属性']:
# print(attrs)
if bool('地址' in attrs):
# print(attrs)
# print(self.perdir[names]['属性'][attrs])
add.append(self.perdir[names]['属性'][attrs])
elif '家属' in attrs:
# print(self.perdir[names]['属性'][attrs])
fri = self.perdir[names]['属性'][attrs]
# print(fri)
# print('names',names)
if len(add) == 1:
# print(add[0])
adds = add[0]
elif len(add) > 1:
# print(add)
adds = tuple(add)
# print(adds)
if len(fri) == 1:
# print(fri[0])
fris = fri[0]
elif len(fri) > 1:
# print(fri)
fris = tuple(fri)
# print(fris)
name = Node('病例',bingli_id = ids,trender = trenders,age = ages,
address = adds,friend = fris)
self.graph.create(name)
# 创建地址节点
for dates in self.perdir[names]['轨迹']:
for time in range(len(self.perdir[names]['轨迹'][dates])):
# print('action:', list(self.perdir[names]['轨迹'][dates][time])[2])
# print('adds:', list(self.perdir[names]['轨迹'][dates][time])[1])
# print(dates, self.perdir[names]['轨迹'][dates][time][0])
place = Node('外出地址',add_id=list(self.perdir[names]['轨迹'][dates][time])[1])
self.graph.create(place)
# 创建病例与轨迹之间的关系
# track = Relationship(names, self.perdir[names]['轨迹'][dates][time][2],
# self.perdir[names]['轨迹'][dates][time][1], date=dates, time=time)
# self.graph.create(track)
创建边缘关系
def CreateRel(self):
for names in self.perdir:
# 创建病例与病例之间的联系
for rels in self.perdir[names]['属性']:
if type(self.perdir[names]['属性'][rels]) == list:
# print(rels, ':', self.perdir[names]['属性'][rels])
for index in self.perdir[names]['属性'][rels]:
# print(names,rels,index)
# 构建病例与病例之间的关系
try:
NamRel = Relationship(self.matcher.match('病例',bingli_id=names).first(),rels,
self.matcher.match('病例',bingli_id=index).first())
self.graph.create(NamRel)
except:
print(names+'构建联系出错'+index)
for dates in self.perdir[names]['轨迹']:
for time in range(len(self.perdir[names]['轨迹'][dates])):
print(list(self.perdir[names]['轨迹'][dates][time])[1])
# print(self.matcher.match('外出地址',add_id=list(self.perdir[names]['轨迹'][dates][time])[1]))
# print(self.perdir[names]['轨迹'][dates][times][2])
print(names,
list(self.perdir[names]['轨迹'][dates][time])[2],
list(self.perdir[names]['轨迹'][dates][time])[1],
dates,
list(self.perdir[names]['轨迹'][dates][time])[0]
)
times = list(self.perdir[names]['轨迹'][dates][time])[0]
track = Relationship(self.matcher.match('病例',bingli_id=names).first(),
list(self.perdir[names]['轨迹'][dates][time])[2],
self.matcher.match('外出地址',add_id=list(self.perdir[names]['轨迹'][dates][time])[1]).first(),
date = dates,time = times)
self.graph.create(track)
这部分代码也是进行在neo4j中构建图谱的核心代码。
3. 进行数据分析
这部分内容就不过多介绍了,因为这是知识图谱创建后需要做的数据分析工作。
简单的给各位看一下在neo4j中的一个增删改查,当然这在python中也可以实现。
最后,我将向您展示最终结果。当然,没有办法截图,所以我只给你看一部分。
这部分内容就不过多介绍了,因为这是知识图谱创建后需要做的数据分析工作。
备注:由于我纯粹是对学习知识图谱感兴趣,所以走了很多弯路。本例使用爬虫中的正则表达式过滤数据,数据清洗不完善。如果可以使用哈工大的语义分割包进行分割和标注,效果会更好!
我也非常渴望向知识图谱行业的大神们学习很多东西,也希望能够为刚开始接触知识图谱的朋友们避免一些坑,从而更有效的提升自己的能力。
希望各位前辈多多交流~
附本人邮箱:630317316@qq.com
如果有人需要我的具体代码,或者知识图谱的入门流程,也欢迎联系我
欢迎各位加我qq一起探讨哦(qq:630317316)
如果您觉得我提供了一个想法,请随时打赏! ~~
文章出处登录后可见!