坦克世界WOT知识图谱之知识图谱篇

news2024/11/18 1:50:26

文章目录

  • 关于Neo4j
  • 1. neo4j安装及配置:
  • 2. 确定三元组
  • 3. 代码实现
  • 结束语

关于Neo4j

  Neo4j是一个高性能的,NOSQL图形数据库。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。是构建知识图谱最常用的图数据库之一。

  知识图谱部署在Linux服务器上,具体版本信息为:
  Ubuntu 22.04.2
  Java 17.0.8
  Neo4j 5.12.0

在这里插入图片描述

1. neo4j安装及配置:

  Neo4j依赖Java引擎,因此需要安装Java

  Java17官方地址:https://www.oracle.com/java/technologies/downloads/#java17

在这里插入图片描述

  Neo4j官方地址:https://neo4j.com/deployment-center/#community

在这里插入图片描述
  安装流程:

# 下载java17
wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz
# 下载neo4j
https://dist.neo4j.org/neo4j-community-5.12.0-unix.tar.gz

# 解压到/usr/local
sudo tar -zxvf jdk-17_linux-x64_bin.tar.gz -C /usr/local/
sudo tar -zxvf neo4j-community-5.12.0-unix.tar.gz -C /usr/local/

  配置流程:

# 配置neo4j
vim /usr/local/neo4j-community-5.12.0/conf/neo4j.conf
# line 65 设置远程访问
server.default_listen_address=0.0.0.0
# line 86, 91 设置端口
server.bolt.listen_address=:7687
server.http.listen_address=:7474
# 7687是bolt端口,Bolt协议是neo4j的应用层协议
# 7474和7473分别是http和https端口,可以通过浏览器来访问可视化界面

# 配置环境变量
vim ~/.bashrc
# >>> setting neo4j >>>
JAVA_HOME=/usr/local/jdk-17.0.8
NEO4J_HOME=/usr/local/neo4j-community-5.12.0
export PATH=$JAVA_HOME/bin:$NEO4J_HOME/bin:$PATH
# <<< setting neo4j <<<

# 使配置生效
source ~/.bashrc

# 查看版本
java --version
neo4j --version

  版本信息如下:

在这里插入图片描述

  以下是neo4j常用的几个指令:

# 启动neo4j
neo4j start
# 查看neo4j的状态
neo4j status
# 停止neo4j
neo4j stop
# 重启neo4j
neo4j restart 

在这里插入图片描述

  ps: 如果因权限问题启动失败,则需要给予一定的权限:
  bash sudo chmod 777 -R neo4j-community-5.12.0 jdk-17.0.8

  浏览器访问可视化界面http://localhost:7474(可以修改为数据库的ip),初始账户及密码均为neo4j

在这里插入图片描述
  登录后会自动跳转让修改初始密码,修改完毕后进入可视化界面:

在这里插入图片描述

2. 确定三元组

  关于知识图谱中三元组的相关知识,这里也不再进行概述,感兴趣的可以查阅相关资料。
  本来计划按照如下方式进行构造知识图谱,但后来实现的过程中发现,不太好构造(其实还不太熟练哈哈哈哈😅),所以就构造简单了些,比如坦克的火力/机动性/防护/侦察这些属性直接展开了。

在这里插入图片描述
  展开后的关系如下:

# (实体, 关系, 实体)
Tank:
    系别:
    类型:
    等级:
    角色:
    性质:
    历史背景:
    
    银币:
    经验:
    
    损伤:
    装甲穿透力:
    火炮装填时间:
    最小弹震持续时间:
    最大弹震持续时间:
    射速:
    平均每分钟损伤:
    瞄准时间:
    00米精度:
    弹药容量:
    
    重量/最大载重量:
    发动机功率:
    单位功率:
    最大速度:
    旋转速度:
    炮塔旋转速度:
    
    生命值:
    车体装甲:
    炮塔装甲:
    悬挂装置维修时间:
    
    观察范围:
    通信距离:

3. 代码实现

  根据上篇博客爬取到的坦克数据,构造知识图谱:

# -*- coding: utf-8 -*-
# Author  : xiayouran
# Email   : youran.xia@foxmail.com
# Datetime: 2023/10/1 20:29
# Filename: build_kg.py
import os
import json
from py2neo import Graph, Node, Relationship, NodeMatcher


class WOTKG(object):
    def __init__(self, clean_kg=True):
        self.clean_kg = clean_kg
        self.entity_tank = []
        self.entity_price = []
        self.entity_firepower = []
        self.entity_mobility = []
        self.entity_survivability = []
        self.entity_spotting = []
        self.all_entity = []
        self.data_path = '../data/tank_list_detail.json'

        self.graph = Graph('neo4j://172.20.203.172:7687', auth=('neo4j', 'lyp123456'))  # use your ip 172.20.197.99
        self.matcher = NodeMatcher(self.graph)
        if self.clean_kg:
            self.graph.delete_all()

    def build_KG(self):
        self.collect_entity()
        self.create_all_node()
        self.create_relation()

    def check_zero(self, v_str):
        if not v_str:
            return True
        elif len(v_str) == 2 and v_str[0] == '0' and v_str[1] in ['秒', '米', '%', '度']:
            return True
        else:
            return False

    def add_entity(self, tank_name, entity_name, v_item: dict):
        for k_, v_ in v_item.items():
            if self.check_zero(v_):
                continue
            if entity_name == 'Price':
                self.entity_price.append(('Price', k_, v_))
            elif entity_name == 'Firepower':
                self.entity_firepower.append(('Firepower', k_, v_))
            elif entity_name == 'Mobility':
                self.entity_mobility.append(('Mobility', k_, v_))
            elif entity_name == 'Survivability':
                self.entity_survivability.append(('Survivability', k_, v_))
            elif entity_name == 'Spotting':
                self.entity_spotting.append(('Spotting', k_, v_))
            self.all_entity.append((tank_name, entity_name, k_, v_))

    def collect_entity(self):
        with open(self.data_path, 'r', encoding='utf-8') as f:
            data_json = json.load(f)
        for tank_item in data_json.values():
            tank_name = tank_item['tank_name']
            for k, v in tank_item.items():
                if k[0] == 't' or not v:
                    continue
                if k == '价格':
                    if isinstance(v, str):
                        self.entity_price.append(('Price', '金币', v))
                        self.all_entity.append((tank_name, 'Price', '金币', v))
                    else:
                        self.add_entity(tank_name, 'Price', v)
                elif k == '火力':
                    self.add_entity(tank_name, 'Firepower', v)
                elif k == '机动性':
                    self.add_entity(tank_name, 'Mobility', v)
                elif k == '防护':
                    self.add_entity(tank_name, 'Survivability', v)
                elif k == '侦察':
                    self.add_entity(tank_name, 'Spotting', v)
                else:
                    self.entity_tank.append((tank_name, k, v))
                    self.all_entity.append((tank_name, 'Tank', k, v))

    def create_node(self, entity_list, entity_name='Tank'):
        head_nodes = []
        tail_nodes = []

        for (head, rela, tail) in entity_list:
            if head not in head_nodes and head not in ['Price', 'Firepower', 'Mobility', 'Survivability', 'Spotting']:
                head_nodes.append(head)
                node = Node(entity_name, name=head)
                self.graph.create(node)
            if tail not in tail_nodes:
                tail_nodes.append(tail)
                node = Node("{}Value".format(entity_name), name=tail)
                self.graph.create(node)

    def create_all_node(self):
        self.create_node(self.entity_tank, entity_name='Tank')
        self.create_node(self.entity_price, entity_name='Price')
        self.create_node(self.entity_firepower, entity_name='Firepower')
        self.create_node(self.entity_mobility, entity_name='Mobility')
        self.create_node(self.entity_survivability, entity_name='Survivability')
        self.create_node(self.entity_spotting, entity_name='Spotting')

    def create_relation(self):
        for (head, flag_str, rela, tail) in self.all_entity:
            node_head = self.matcher.match('Tank').where(name=head).first()
            node_tail = self.matcher.match('{}Value'.format(flag_str)).where(name=tail).first()
            rela_node = Relationship(node_head, rela, node_tail)
            self.graph.create(rela_node)


if __name__ == '__main__':
    wot_kg = WOTKG(clean_kg=True)
    wot_kg.build_KG()

  构造后的知识图谱可视化效果如下:
  单辆坦克:

在这里插入图片描述
  知识图谱局部:

在这里插入图片描述

结束语

  本篇的代码已经同步到仓库中,感兴趣的话可以拉取一下,下一篇文章就基于这个知识图谱来构造一个关于坦克百科的智能问答机器人。

开源代码仓库


  如果喜欢的话记得给我的GitHub仓库WOT点个Star哦!ヾ(≧∇≦*)ヾ


  公众号已开通:夏小悠,关注以获取更多关于Python文章、AI领域最新技术、LLM大模型相关论文及内部PPT等资料^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1129626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UG\NX二次开发 设置视图中心 UF_VIEW_set_center

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 感谢粉丝订阅 感谢 a1794902437 订阅本专栏,非常感谢。 简介 UG\NX二次开发 设置视图中心 UF_VIEW_set_center。如果视图NULL_TAG,则使用工作视图。 效果 代码 #include &qu…

【PointNet—论文笔记分享】

第一个直接基于原始点云数据进行分割、分类的模型&#xff0c;之前都是基于多视图或者体素的方式。 论文: PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation代码: TensorFlow版 Pytorch版 基本模型架构&#xff1a; 分别对每个点进行特征提取…

AI大模型基础环境搭建

文章目录 AI大模型基础环境搭建简介下面是搭建大模型基础环境大模型基础环境通常会依赖以下package&#xff1a;conda安装demo环境搭建关于该git项目需要注意的一些点前后端封装 AI大模型基础环境搭建 简介 简单描述一下本文章里会教大家做的东西 1、搭建大模型基础环境 2、f…

JVM相关的面试题

一、什么是程序计数器 二、简要的介绍一下堆 三、什么是虚拟机栈 四、能不能解释下方法区 五、你听过直接内存吗&#xff1f; 六、什么是类加载器&#xff0c;类加载器有哪些 七、什么是双亲委派模型 八、JVM为什么采用双亲委派机制 九、类装载的执行过程 十、对象什么时候被垃…

Day982.各大开放平台是如何使用OAuth 2.0 -OAuth 2.0

各大开放平台是如何使用OAuth 2.0 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于各大开放平台是如何使用OAuth 2.0的内容。 “开放平台”&#xff0c;不难理解&#xff0c;它的作用就是企业把自己的业务能力主要以开放 API 的形式&#xff0c;赋能给外部开发者。而…

C++(Chapter 3)

C(三) 1.引用 1.引用的概念 引用的概念:引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 引用的语法:类型& 引用变量名(对象名) 引用实体 ; 例如: #i…

【OpenGL】七、混合

混合 文章目录 混合混合公式glBlendFunc&#xff08;混合函数&#xff09;glBlendFuncSeparate渲染半透明纹理 参考链接 混合(Blending)通常是实现物体透明度(Transparency)的一种技术 简而言之&#xff1a;混合就是如何将输出颜色和目标缓冲区颜色结合起来。 混合公式 C_fina…

Android 备忘录,记事本程序设计

android备忘录实现&#xff0c;使用ObjectBox数据库框架进行数据存储&#xff0c;增删改查等操作。代码使用kotlin编写。 1、下面看看ObjectBox数据库封装 需要注意的是&#xff1a; /** * 你只有配置好之后, 点击 Make Model 你的model名字, 才会创建 MyObjectBox对象 …

(十七)VBA常用基础知识:读写text文件

读取文件 1.1.数据准备 1.2 代码准备 Sub test()Dim buf As String, n As LongOpen "/Users/sixdog/Documents/VBA/test.txt" For Input As #1Do Until EOF(1)Line Input #1, bufn n 1Sheet1.Range("A" & n) bufLoopClose #1 End Sub1.3 执行结果…

在Unity中如何设置设备的高、中、低配

在开发游戏或应用程序时&#xff0c;考虑到不同设备的性能差异是至关重要的。Unity作为一种流行的游戏开发引擎&#xff0c;提供了一些方法来区分设备的高、中、低配&#xff0c;并相应地调整游戏的性能要求和图形质量。 以下是在Unity中实现这一目标的几种常用方法&#xff1…

【Linux】零基础入门Linux你所需要掌握的

文章目录 目录结构路径描述颜色区分Linux命令文件权限 目录结构 要了解Linux首先,必须要了解linux的目录层级结构,因为在linux中有一切皆文件"的思想. windows系统里面的文件具有各个盘符,如C盘,D盘等 而在Linux中,Linux的目录结构是一个树型结构 Linux没有盘符的概念,只…

程序的编译,链接,执行

目录 1.程序的翻译环境和执行环境 2.翻译环境 3.运行环境 1.程序的翻译环境和执行环境 当我们写出一段代码后&#xff0c;我们需要将代码运行起来。那在这个过程中文件是如何从代码变成可执行程序的呢&#xff1f; 在程序实现过程中中&#xff0c;存在两个环境&#xff1a;一…

Matlab安装必看,手把手教你安装matlab

目录 一 &#xff0c;Matlab介绍 二&#xff0c;安装matlab2021b 一 &#xff0c;Matlab介绍 Matlab是一种高级计算机语言和交互式环境&#xff0c;广泛用于科学、工程、金融和其他领域的数据分析、可视化和数值计算。它是由MathWorks公司开发的&#xff0c;最初发布于1984年…

【unity3D插件】Embedded Browser(ZFBrowser) — 快速实现PC端内嵌网页(有详细图解)

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity3D插件—Embedded Browser 这里写自定义目录标题 下载基础知识基础操作使用公网网址加载一个网页①使用公网网址加载一个网页②使用…

IP子网到底怎么划分【全网最详解】!!!

在学习IP子网划分前&#xff0c;首先的明白以下几个基础概念&#xff1a; 1、IP地址组成 IP地址由32位二进制组成&#xff0c;32位二进制分成了4字节&#xff0c;每字节8位&#xff0c;字节之间用符.&#xff08;点&#xff09;分隔&#xff0c;为了方便人们记忆&#xff0c;经…

Leetcode刷题详解——搜索插入位置

1. 题目链接&#xff1a;35. 搜索插入位置 2. 题目描述&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。…

判断函数是否标记async

判断函数是否标记为async 今天看到这道题觉得蛮有意思的 就是说让你写一个工具类,让后这个工具类接收一个函数,判断这个函数是不是被async标记了 如下,我们先看看普通函数和被async标记的函数打印出来是啥样子 function isAsyncFunction(func) {console.log(func)}isAsyncFun…

css样式中 before、after 里面的 content 乱码

目录 一、问题 二、原因 三、总结 一、问题 1.代码在本地没有问题&#xff0c;打包放在线上在时候&#xff0c;竟然测试测的时候看到element的字体图标有时候显示乱码&#xff0c;如下图1-1所示。更奇葩的是偶现&#xff0c;只有测试看见了&#xff0c;很难复现。。。 图1-…

【网络协议】聊聊UDP协议

前面的几篇文章讲述了链路层和IP层&#xff0c;主要的话其实就是MAC地址&#xff0c;以及通过IP地址求MAC地址的ARP协议。PING的底层协议 ICMP 。动态分配IP协议 DHCP等。而从今天开始我们开始讲述传输层协议&#xff0c;传输层主要就是UDP和TCP。 TCP 和 UDP 有哪些区别&…

Bean转换工具MapStruct看这一篇就够了

内容持续更新中… 文章目录 1.背景2.mapstruct简介3.mapstruct与其他映射对比4.mapstruct底层原理解析5.具体使用和底层实现5.1 添加maven依赖5.2 对象转换1.UserA和UserB字段相同2.UserA和UserB字段不同3.多个源类4.子对象映射5.数据类型转换数据类型映射枚举映射 6.集合映射…