权力的游戏击杀和家族知识图谱(python+neo4j)

一、任务描述

数据集是github上某大神整理出来的全八季任务信息,包括姓名、家族、杀了谁、被谁杀了等等。本文做的知识图谱仅包含所有人物及其被杀关系和家族关系。

数据集链接:https://github.com/jeffreylancaster/game-of-thrones/blob/master/data/characters.json

二、neo4j的安装和部署

参考:https://www.cnblogs.com/ljhdo/p/5521577.html

1.安装Java JRE

下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html

配置Java环境变量。

第一步,新建JAVA_HOME变量,变量值填写jdk的安装目录,默认的安装目录是:C:\Program Files\Java\jre1.8.0_211

第二步,编辑Path变量,在Path变量值的最后输入:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

检查配置是否成功,运行cmd,输入java -version,如果显示java的版本信息,说明Java的安装和配置成功。

2.安装Neo4j

下载地址:https://neo4j.com/download-center/

解压到主目录,“D:\Program Files\neo4j-community-3.2.”。

Neo4j应用程序有如下主要的目录结构:

  • bin目录:用于存储Neo4j的可执行程序;
  • conf目录:用于控制Neo4j启动的配置文件;
  • data目录:用于存储核心数据库文件;
  • plugins目录:用于存储Neo4j的插件;

配置Neo4j环境变量:创建主目录环境变量NEO4J_HOME,并把主目录设置为变量值。

3.启动Neo4j

以管理员身份启动命令行,切换到D:\Program Files\neo4j-community-3.2.\bin,输入以下命令,通过控制台启用neo4j程序:

neo4j.bat console

如果看到以下消息,说明neo4j已经开始运行:

4.Neo4j浏览器

通过命令行启动neo4j之后,访问 “http://localhost:7474/”

默认的host是bolt://localhost:7687,默认的用户是neo4j,默认的密码是:neo4j,第一次成功connect到Neo4j服务器之后,需要重置密码。

5.在Neo4j浏览器中创建节点和关系

CREATE (n:Person { name: 'Andres', title: 'Developer' }) return n;
CREATE (n:Person { name: 'Vic', title: 'Developer' }) return n;
match(n:Person{name:"Vic"}),(m:Person{name:"Andres"}) create (n)-[r:Friend]->(m) return r;
match(n:Person{name:"Vic"}),(m:Person{name:"Andres"}) create (n)<-[r:Friend]-(m) return r;

三、数据处理

从数据集中抽取需要的信息生成节点和关系csv文件。

原始数据集如下图:

只需要其中的characterName、houseName和killedBy信息,同时去除没有人物图片和重复的小角色,建立一个notuse.txt

import json
import pandas as pd

with open('./characters.json', 'r') as f:
    data = json.load(f)
with open('./notuse.txt', 'r') as f:
    notuse = []
    for name in f.readlines():
        name = name.strip()
        notuse.append(name)

characters = []
character2index = {}
index2character = {}
house2index = {}
index2house = {}

character = {'index:ID':[],
             'name':[],
             ':LABEL':[]}
house = {'index:ID':[],
         'name':[],
         ':LABEL':[]}
kill = {':START_ID':[],
        ':END_ID':[],
        'relation':[],
        ':TYPE':[]}
belong = {':START_ID':[],
          ':END_ID':[],
          'relation':[],
          ':TYPE':[]}

index_character = 1
index_house = 10001
for dic in data['characters']:
    if 'characterImageThumb' in dic.keys() and dic['characterName'] not in notuse:
        characters.append(dic) 
        # 构建character节点
        name2index[dic['characterName']] = index_character
        index2name[index_character] = dic['characterName']
        character['index:ID'].append(index_character)
        character['name'].append(dic['characterName'])
        character[':LABEL'].append('character')
        index_character += 1
        # 构建house节点
        if 'houseName' in dic:
            if type(dic['houseName']) == str:
                if dic['houseName'] not in house['name']:
                    house2index[dic['houseName']] = index_house
                    index2house[index_house] = dic['houseName']
                    house['index:ID'].append(index_house)
                    house['name'].append(dic['houseName'])
                    house[':LABEL'].append('house')
                    index_house += 1
            elif type(dic['houseName']) == list:
                for hname in dic['houseName']:
                    if hname not in house['name']:
                        house2index[hname] = index_house
                        index2house[index_house] = hname
                        house['index:ID'].append(index_house)
                        house['name'].append(hname)
                        house[':LABEL'].append('house')
                        index_house += 1
        
for person in characters:
    # 构建killedBy关系
    if 'killedBy' in person.keys():
        for killer in person['killedBy']:
            if killer in name2index.keys():
                kill[':START_ID'].append(name2index[person['characterName']])
                kill[':END_ID'].append(name2index[killer])
                kill['relation'].append('killedBy')
                kill[':TYPE'].append('killedBy')
    # 构建belongTo关系
    if 'houseName' in person.keys():
        if type(person['houseName']) == str:
            belong[':START_ID'].append(name2index[person['characterName']])
            belong[':END_ID'].append(house2index[person['houseName']])
            belong['relation'].append('belongTo')
            belong[':TYPE'].append('belongTo')
        elif type(person['houseName']) == list:
            for h in person['houseName']:
                belong[':START_ID'].append(name2index[person['characterName']])
                belong[':END_ID'].append(house2index[h])
                belong['relation'].append('belongTo')
                belong[':TYPE'].append('belongTo')

df_character = pd.DataFrame(character)
df_house = pd.DataFrame(house)
df_kill = pd.DataFrame(kill)
df_belong = pd.DataFrame(belong)
df_character.to_csv('./character.csv', index=False)
df_house.to_csv('./house.csv', index=False)
df_kill.to_csv('./kill.csv', index=False)
df_belong.to_csv('./belong.csv', index=False)

构建节点和关系csv文件时,注意以下几点:

1.所有的节点文件,第一列都要为“index:ID”,最后一列都要为":LABEL" , 中间所有列即为这个实体的属性。注意实体属性最好不要用中文,label即为这个实体的对应标签。

人物节点文件character.csv:

家族节点文件house.csv:

2.所有的关系文件,第一列都要为“:START_ID”,第二列都要为":END_ID",第三列要为"relation",第四列要为":TYPE" , start_id对应一个节点的index_id,end_id对应另一个节点的index_id,relation即为两者的关系,type即为标签,一般type和relation内容相同。

击杀关系文件kill.csv:

家族关系文件belong.csv:

3.不管是实体还是关系文件里的index_id,可以在一开始设一个比数据规模大出两个数量级的初始值,比如本文的家族id都是10000+i,因为主键设的太小容易造成不同文件的主键混淆。

参考:https://blog.csdn.net/shr903988854/article/details/83145088

四、导入Neo4j数据库

节点路径和关系路径可以根据自己需要指定。文件路径的根目录默认为neo4j/bin。

另外,在执行此语句前要确保没有got.db这个数据库,并且conf文件中注释这句dbms.active_database=got.db(如果存在的话),不然会报数据库存在的错误。

导入成功后,再在conf文件中添加语句dbms.active_database=got.db或取消注释。

在浏览器中查看人物及其关系:

用cypher语句可以对数据库进行增删改查操作

教程:http://neo4j.com.cn/public/cypher/default.html

熟悉了知识存储和检索操作,接下来看一下知识推理和知识融合,希望在2019DeeCamp上能做出完整的知识图谱吧。

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值