Python+Neo4j构建时光网TOP100电影知识图谱

2023-11-11

Python+Neo4j构建时光网TOP100电影知识图谱

环境

1、Neo4j 3.5.6(2019年6月25日)

2、Java 1.8.0_181

3、Annaconda 3

 

一、准备工作

Neo4j安装:https://blog.csdn.net/gggggao/article/details/93595137

二、节点关系分析

目的:学习并尝试构建知识图谱,选择时光网的电影排名做尝试。

时光网链接: http://www.mtime.com/top/movie/top100/

数据导入neo4j的方式有五种,这里采用最后一种方法(Neo4j-import)来进行导入

查看并分析网页源代码之后,确定爬取的节点和关系对象如下:

节点:
    |----电影
            |----index:ID
            |----properity: rank, src, name, movie_en, year
            |----label
    |----导演
            |----index:ID
            |----properity: director
            |----label
    |----演员
            |----index:ID
            |----properity: actor
            |----label
​
​
关系:
    |----电影<--导演
                  |----start:START_ID
                  |----end:END_ID
                  |----properity: relation
                  |----type:TYPE
    |----电影<--演员
                  |----start:START_ID
                  |----end:END_ID
                  |----properity: relation
                  |----type:TYPE
    |----演员-->导演
                  |----start:START_ID
                  |----end:END_ID
                  |----properity: relation
                  |----type:TYPE

 

三、构建电影知识图谱

3.1 爬取数据

3.1.1 下载网页

本文采用BeautifulSoup来进行数据爬取,首先下载url的html文件

def download_page(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'}
    return requests.get(url, headers = headers).content

3.1.2 解析网页

接着对下载的网页进行解析,得到全部电影信息的list,也就是movie_list

def parse_timesmovie_html(html):
    soup = BeautifulSoup(html, features="lxml")     #parse tool: BeautifulSoup
    movie_list = []  # movie_node list: sava all the movie info into the list
    movie_list_soup = soup.find('ul', attrs={'id':'asyncRatingRegion'})     #find body
    #get the data of: rank, movie_name, src, director, movie_actor[]; then save in the
    for movie_li in movie_list_soup.find_all('li'):
        rank = movie_li.find('div', attrs={'class': 'number'}).getText()   #rank of movie
        movie_info = movie_li.find('div', attrs={'class': 'mov_con'})
        movie_temp = movie_info.find('a').getText().split("\xa0")     #name of movie
        movie_name = movie_temp[0]
        year = movie_temp[1].split(" ")[-1].replace('(','').replace(')','')       #release date of movie
        movie_en_name = movie_temp[1][:-7]  #English name of movie
        #print(movie_en_name)
        src = movie_info.find('a')['href']      #src of movie
        # extract the infomation of director&actor
        person_info = movie_info.select('p')
        # director of movie
        director = person_info[0].find('a').string
        # actors of movie
        movie_actor = []
        for act in person_info[1].find_all('a'):
            movie_actor.append(act.string)
​
        movie_info_all = {'rank': rank,
                      'src': src,
                      'movie_name': movie_name,
                      'movie_en_name': movie_en_name,
                      'year': year,
                      'director': director,
                      'actor': movie_actor
                      }
        movie_list.append(movie_info_all)
    return movie_list

3.1.3 处理重复节点

我们知道,会存在一个导演拍了多部电影,或者一个演员演了多部电影的情况存在,因此,我们需要对可能会重复的节点(导演和演员)进行处理,并返回节点的字典

def handle_entity(person_list):
    director_list, actor_list = [], []
    dir_dic, actor_dic = {}, {}
​
    # separate infomation from person_list
    for elm in person_list:
        director_list.append(elm['director'])
        actor_list.extend(elm['actor'])
    #utilize set() to remove duplicate data from the list[]
    director_set=set(director_list)
    actor_set = set(actor_list)
    #save data to the dictionary
    for index,value in enumerate(director_set):
        dir_dic[index] = value
    for index,value in enumerate(actor_set):
        actor_dic[index] = value
    
    return dir_dic, actor_dic

3.2 生成csv文件

3.2.1 生成节点csv文件

根据上面的分析我们要生成3个节点的csv文件,分别是

  • 电影:times_movie_entity.csv

  • 导演:times_director_entity.csv

  • 演员:times_actor_entity.csv

代码如下所示

#times_movie_entity.csv
def save_movie_entity(movie_entity_list):
    data = pd.DataFrame({'index:ID': [index+1000 for index in range(len(movie_entity_list))],
                         'rank': [movie['rank'] for movie in movie_entity_list],
                         'src': [movie['src'] for movie in movie_entity_list],
                         'name': [movie['movie_name'] for movie in movie_entity_list],
                         'movie_en': [movie['movie_en_name'] for movie in movie_entity_list],
                         'year': [movie['year'] for movie in movie_entity_list],
                         ':LABEL': 'movie'
                         })
    data.to_csv(r'./times_movie_entity.csv', index=False)
​
#times_director_entity.csv
def save_director_entity(director_entity_dic):
    data = pd.DataFrame({'index:ID': [item+2000 for item in director_entity_dic.keys()],
                         'director': [val for val in director_entity_dic.values()],
                         ':LABEL': 'director'
                         })
    data.to_csv(r'./times_director_entity.csv', index=False)
​
#times_actor_entity.csv
def save_actor_entity(actor_entity_dic):
    data = pd.DataFrame({'index:ID': [item+3000 for item in actor_entity_dic.keys()],
                         'actor': [val for val in actor_entity_dic.values()],
                         ':LABEL': 'actor'
                         })
    data.to_csv(r'./times_actor_entity.csv', index=False)

注意:

为了很好的区分三个节点,我们对他们的index进行处理,分别加了1000、2000和3000,也就是

节点文档格式规则 [2]

生成的times_movie_entity.csv文件格式见

3.2.2 生成关系csv文件

根据3.2.1生成的节点文件,我们继续生成它们的3个关系文件,分别是

  • 电影<--导演:times_movie_director_relationship.csv

  • 电影<--演员:times_movie_actor_relationship.csv

  • 演员-->导演:times_director_actor_relationship.csv

代码如下所示

#times_movie_director_relationship.csv
def save_movie_director_relationship(movie_list, movie_dic, director_dic):
    data = pd.DataFrame({':START_ID': [list(director_dic.keys())[list(director_dic.values()).index(info['director'])]+2000 for info in movie_list],
                         ':END_ID': [list(movie_dic.keys())[list(movie_dic.values()).index(info['movie_name'])] for info in movie_list],
                         'relation': 'directed',
                         ':TYPE':'directed'
                         })
    data.to_csv(r'./times_movie_director_relationship.csv', index=False)
​
#times_movie_actor_relationship.csv
def save_movie_actor_relationship(movie_list, movie_dic, actor_dict):
    relation_list = []
    for movie in movie_list:
        for actor_info in movie['actor']:
            actor_index = list(actor_dict.keys())[list(actor_dict.values()).index(actor_info)]
            movie_index = list(movie_dic.keys())[list(movie_dic.values()).index(movie['movie_name'])]
            info = {
                    'actor_index': actor_index,
                    'movie_index': movie_index
            }
            relation_list.append(info)
​
    data = pd.DataFrame({':START_ID': [relation['actor_index']+3000 for relation in relation_list],
                         ':END_ID': [relation['movie_index'] for relation in relation_list],
                         'relation': 'acted',
                         ':TYPE': 'acted'
                         })
    data.to_csv(r'./times_movie_actor_relationship.csv', index=False)
​
#times_director_actor_relationship.csv
def save_director_actor_relationship(movie_list, director_dic, actor_dict):
    relation_list = []
    for movie in movie_list:
        for actor_info in movie['actor']:
            actor_index = list(actor_dict.keys())[list(actor_dict.values()).index(actor_info)]
            dir_index = list(director_dic.keys())[list(director_dic.values()).index(movie['director'])]
            info = {
                'actor_index': actor_index,
                'dir_index': dir_index
            }
            relation_list.append(info)
​
    data = pd.DataFrame({':START_ID': [relation['dir_index']+2000 for relation in relation_list],
                         ':END_ID': [relation['actor_index']+3000 for relation in relation_list],
                         'relation': 'cooperate',
                         ':TYPE': 'cooperate'
                         })
    data.to_csv(r'./times_director_actor_relationship.csv', index=False)

生成的times_director_actor_relationship.csv文件格式见

3.3 构建图谱

3.3.1 准备工作

在导入之前要先关闭neo4j服务

  • 以管理员身份打卡命令提示符

  • 查看neo4j状态,如果是运行状态则将其关闭

3.3.2 生成图谱

服务关闭之后我们导入文件,如下图所示,

命令如下所示:

neo4j-admin import --mode=csv --database=movie.db --nodes D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_actor_entity.csv --nodes D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_director_entity.csv --nodes D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_movie_entity.csv --relationships D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_director_actor_relationship.csv --relationships D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_movie_actor_relationship.csv --relationships D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_movie_director_relationship.csv

导入成功

四、图谱效果查看

命令成功运行之后多了一个neo4j数据库:movie.db里面存放着我们的刚刚成功存储的数据。

为了能把数据加载出来,我们接着进conf设置默认加载的数据库

打开neo4j.conf,输入 dbms.active_database=movie.db,如下所示

最后我们输入Cyper语句查询宫崎骏图谱,Cyper语句如下所示:

match m=(:director{director:'宫崎骏'})-[*..1]-() return m

查询结果如图所示

五、Github

代码github地址:https://github.com/Gao0505/KnowledgeGraph/tree/master/TimesMovieKG

参考

[1]  https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/89078048

[2]  https://blog.csdn.net/sinat_25479505/article/details/80996402 

[3]  https://blog.csdn.net/Chen18125/article/details/84101458

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python+Neo4j构建时光网TOP100电影知识图谱 的相关文章

  • Neo4j https 通信

    有没有办法只允许 https 而不是 http 与 Neo4j 服务器通信 另外 Neo4j Shell 的通信使用哪个通道 http 还是 https 这是来自 Neo4j 文档 HTTPS 支持 http docs neo4j org
  • Neo4j 中的自动增量

    有没有办法像在 Neo4j 的 MySQL 中一样设置 auto increment 例如 当我使用 GraphDatabaseService 对象创建节点时 我希望节点以 1000000000 等数字开头 非常感谢 看看这个答案 我可以在
  • neo4j:单向/双向关系?

    所以我研究了 neo4j 我可能会在即将到来的项目中使用它 因为它的数据模型可能非常适合我的项目 我查看了文档 但我仍然需要这个问题的答案 我可以将关系设置为单向吗 看来 Neo4j 的人很喜欢电影 所以我们继续吧 如果我有这样的图表 Ac
  • “找不到类型的属性”组合存储库 spring-data-neo4j

    我在用着spring data neo4j我正在尝试组合存储库以便能够使用自定义存储库 我认为我已经正确遵循了中指定的命名约定20 8 7 创建存储库 http docs spring io spring data neo4j docs 3
  • 使用 py2neo 在 neo4j 上查询写入性能

    目前 我正在努力寻找一种高性能的方法 使用 py2neo 运行多个查询 我的问题是 python 中有一大堆需要写入 neo4j 的写入查询 我现在尝试了多种方法来解决这个问题 对我来说最好的工作方法如下 from py2neo impor
  • Neo4j聚合函数

    我正在尝试使用SUM函数并将其结果存储为关系的新属性 但它不起作用 我使用的查询是 MATCH a Employee r CorporateMessage gt b WHERE a Eid 6001 AND b Eid IN 6002 60
  • Neo4j 客户端使用“DateTime?”展开

    我目前正在尝试展开具有 日期时间 的 TravelEdges 列表 但我不断收到以下错误 CypherTypeException 类型不匹配 需要一个地图 但是字符串 2018 05 21T08 38 00 我目前正在使用最新版本的 neo
  • 如何删除neo4j中的所有索引?

    我想使用 cypher 批量删除所有存在的索引 可以吗 我正在使用 neo4j 3 4 7 DROP INDEX ON Label attributename 如果我在稍后阶段创建相同的索引 它会替换现有索引吗 删除所有索引和约束的快速方法
  • Spring Neo4j:通过不同控制台执行时相同的密码查询花费不同的时间

    通过不同控制台执行相同的密码查询会花费不同的时间 通过执行spring data neo4j 花了 8 秒 Query MATCH user User uid 0 FRIEND friend User RETURN friend publi
  • Neo4j.rb 创建独特的关系

    这是我的 Neo4j 活动节点 class User include Neo4j ActiveNode has many out following type following model class User end john User
  • 如何在java中使用cypher加载CSV文件?

    我是密码新手 我想在java中使用cypher加载csv 我用谷歌搜索并找到了以下作品 LOAD CSV WITH HEADERS FROM http neo4j com docs 2 3 1 csv import movies csv A
  • Neo4j 在 Cypher 查询运行中仅使用一个核心

    当我在 UI 中运行 Cypher 查询时 服务器中只有一个核心正在运行 查询会卡住或响应非常慢 我使用 Neo4j 3 0 7 社区 有人知道我可以使用所有核心进行哪些调整吗 单个 Cypher 查询仅限于单个线程 看到这个tweet h
  • 如何使用 spring-data-neo4j 配置 neo4j EmbeddedGraphDatabase (现已弃用)?

    我正在使用 spring data neo4j 3 1 1 Release 和 neo4j 2 1 2 我设法制作了一个运行良好的 spring 配置 但它使用了 org neo4j kernel EmbeddedGraphDatabase
  • 如何转储 neo4j 图形数据库?

    我将所有数据库存储在一个位置C JATIN DATA 数据库 neo4jDatabases 如何使用 neo4j Desktop 单独转储所有数据库 我已经尝试过 neo4j admin dump database to 这个命令但出现错误
  • Cypher Linked List:如何按索引取消移位和替换

    我正在尝试按照此处的推荐使用 Neo Cypher 创建链表结构 创建时CYPHER存储相同标签的节点关系顺序 https stackoverflow com questions 33263822 cypher store order of
  • 是否有工具可以将 Neo4j 图转储为 Cypher 并从 Cypher 重新加载它?

    每个熟悉 MySQL 的人都可能使用过 mysqldump 命令 它可以生成代表 MySQL 数据库中的架构和数据的 SQL 语句文件 这些 SQL 文本文件通常用于多种用途 备份 播种副本 在安装之间复制数据库 将产品数据库复制到临时环境
  • 如何在图数据库(如 Neo4j)中对现实世界的关系进行建模?

    我有一个关于在图形数据库中建模的一般性问题 但我似乎无法解决这个问题 您如何建模这种类型的关系 牛顿发明了微积分 In a 简单图 http docs neo4j org chunked snapshot graphdb neo4j rel
  • 为 Apache Spark 示例运行 Cypher (CAPS)

    我知道这是一个广泛的问题 但这会对neo4j不属于某个领域的用户scala编程 我需要使用Apache Spark 项目的 Cypher https github com opencypher cypher for apache spark
  • Neo4j 服务器无法使用非托管扩展启动

    我正在尝试在 neo4j 服务器 版本 CE 2 3 2 上使用非托管扩展 所以我正在尝试一个简单的你好世界的例子 http neo4j com docs stable server unmanaged extensions htmlNeo
  • MongoDB + Neo4J vs OrientDB vs ArangoDB [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我目前正处于 MMO 浏览器游戏的设计阶段 游戏将包括一些实时位置的图块地图 因此每个单元格的图块数据 和通用世界地图 我更喜欢使用 Mongo

随机推荐

  • MATLAB点云处理函数整理

    pcbin 空间bin点云点 bins pcbin ptCloud numBins bins pcbin ptCloud numBins spatialLimits bins binLocations pcbin pcdenoise 去噪
  • 数据结构与算法之二叉树的建立

    文章目录 一 已知二叉树的先序和中序数列 创建二叉树 1 算法思想 2 代码实现 二 已知二叉树的先序和后序数列 创建二叉树 1 算法思想 2 代码实现 三 二叉树的顺序存放 打印先 中 后序遍历 一 已知二叉树的先序和中序数列 创建二叉树
  • Java图形化界面编程一

    目录 一 介绍 二 AWT编程 2 1AWT介绍 2 2 AWT继承体系 2 3 Container容器 2 3 1 Container继承体系 2 3 2 常见API 2 3 3 容器演示 2 4 LayoutManager布局管理器 2
  • Keras使用VGG16模型预测自己的图片

    Keras使用VGG16模型预测自己的图片 环境 Win10 Miniconda3 Pycharm2018 02 代码如下 from keras applications vgg16 import VGG16 from keras prep
  • 计算机视觉课程设计:基于Mediapipe的体感游戏设计

    演示视频 计算机视觉课程设计 基于Mediapipe的体感游戏设计 哔哩哔哩 bilibili
  • SpringCloud微服务架构标准版本拓扑图

    本图是公司需要 自己整理的SpringCloud微服务架构标准版本拓扑图 有 eddx格式 需要请私信 为了方便截了个jpg 希望对你有所帮助 喜欢的朋友点赞收藏转发
  • Cow Marathon(树的直径)(最长路)

    Cow Marathon Time Limit 2000MS Memory Limit 30000KB 64bit IO Format lld llu Submit Status Description After hearing abou
  • 【树莓派】利用tesseract进行汉字识别

    树莓派 利用tesseract进行汉字识别 安装tesseract库 识别图像中的汉字 安装tesseract库 安装tesseract库和它的python封装 sudo apt install tesseract ocr fix miss
  • Python学习-----文件操作(读写定位篇)

    目录 前言 1 打开文件 open 关闭文件 close 2 文件的读取 文件变量名 f 1 整体读取 read 2 读取一行 readline 3 读取多行 readlines 3 文件的写入 文件变量名f write 4 判断文件的可读
  • 稀疏矩阵的存储格式(Sparse Matrix Formats)

    稀疏矩阵的存储格式 Sparse Matrix Storage Formats 1 Coordinate Format COO 这种存储方式的主要优点是灵活 简单 仅存储非零元素以及每个非零元素的坐标 使用3个数组进行存储 values r
  • 解决使用OpenCV-Python外接摄像头打不开问题 re_MSMF::grabFrame videoio(MSMF): can‘t grab frame. Error: -1072873822

    记录在学习django opencv做人脸识别时遇到了以下错误 re MSMF grabFrame videoio MSMF can t grab frame Error 1072873822 直接在 py文件运行 能使用本机的摄像头 放到
  • java Image转byte

    public static byte getImageToByteArr Image src throws IOException int width int src getWidth null int height int src get
  • Flink学习19:算子介绍keyBy

    1 keyBy简介 主要作用 把相同的数据 汇总到相同的分区中 数据本来是分布在不同的slot中 keyBy会把相同的数据拉到相同的slot中 2 keyBy的使用 在使用keyBy时候 需要向keyBy传递一个参数 告诉其按照哪个字段进行
  • 2022-01-12 网工基础(二十)GRE原理与配置 VRRP原理与配置

    一 GRE原理与配置 IPSec VPN 用于在两个端点之间提供安全的 IP 通信 但只能加密并传播单播数据无法加密和传输语音 视频 动态路由协议信息等组播数据流量 通用路由封装协议 GRE Generic Routing Encapsul
  • ​路由器是如何工作的?

    什么叫路由 路由器的英文是 Router 也就是 找路的工具 找什么路 寻找各个网络节点之间的路 换句话说 路由器就像是快递中转站 包裹会经过一个个的中转站 从遥远的地方寄到你家附近 数据包也是一样 路由器是连接两个网络的硬件设备 承担寻路
  • Linux部署东方通TongWeb

    Linux部署东方通TongWeb TongWeb 一 软件版本 二 东方通TongWeb7部署流程 2 1 安装JDK 2 1 1 下载文件 2 1 2 查看当前JDK版本 2 1 3 卸载JDK 2 3 1 卸载JDK 需root权限
  • mmsegmentation 训练自己的数据集

    一 MMSegmentation是什么 MMSegmentation 是一个基于 PyTorch 的语义分割开源工具箱 它是 OpenMMLab 项目的一部分 他与MMDetection类似 集成了各种语义分割算法 可以快速验证语义分割效果
  • 关于HTML5中表单提交的几种验证方法介绍

    转自 微点阅读 https www weidianyuedu com 一 自动验证 我们可以通过元素的属性设置 进行表单提交的验证 required属性 此属性可以应用在大多数输入元素上 除了隐藏元素 图片元素按钮上 提交时 如果元素为空
  • MVVM和MVC有什么区别?

    前言 模型 视图 视图模型 Model View ViewModel MVVM 本质上是MVC 模型 视图 控制器 的改进版 其最重要的特性是数据绑定 data binding 此外还包括依赖注入 路由配置 数据模板等一些特性 从MVC到M
  • Python+Neo4j构建时光网TOP100电影知识图谱

    Python Neo4j构建时光网TOP100电影知识图谱 环境 1 Neo4j 3 5 6 2019年6月25日 2 Java 1 8 0 181 3 Annaconda 3 一 准备工作 Neo4j安装 https blog csdn