neo4j知识图谱构架程序

一、知识图谱概述

知识图谱是一种结构化的语义知识库,它通过图的形式存储实体之间的关系。每个节点代表一个实体,边代表实体间的某种关系。知识图谱使得机器能够更好地理解自然语言,并提供更加丰富和准确的信息。

为此,本研究提出一种解决方案,获取初始数据,并通过网络调研扩充完整数据集。首先对收集到的文本进行预处理。预处理后的数据,通过图数据库技术构建知识图谱。在此过程中,需要定义合适的图模型,包括节点类型、边类型和属性,以及设计高效的数据导入和图谱优化策略。需要采用先进的自然语言处理模型对文本进行向量化,并将其储存在向量数据库中。在此基础上,开发搜索功能,包括查询接口设计、搜索算法实现和结果展示。根据机构需求和系统功能,设计前端页面,并使用现代前端技术实现页面。将前端页面与后端服务(知识图谱、文本向量化、搜索功能)集成,进行系统测试,确保系统的稳定性和可靠性。

(1)类型分布情况
系统提供文件按领域的分布情况,通过标签来展示多项领域,运用饼状图可视化方式展示不同领域的文件数量占比,用户可直观地了解不同领域的文件数量、发布趋势和热点变化。

(2)文件详细内容
用户可查看每条文件的详细内容拆解等信息。

(3)知识图谱展现上下行关系和文件解构
系统分析文件之间的上下行关系,即文件之间的前后逻辑关系。用户可查看某条文件上下行关系的对应变化、要求、变动、联系、继承关系等,有助于了解文件之间的逻辑联系和相互影响。

(4)重点热门文件
图谱通过数据分析和用户行为反馈,识别出当前最受欢迎和关注度最高的文件,将其归类为“重点热门文件”,并进行推荐展示。

(5)最新文件推送
展示最新发布的文件。图谱提供实时更新的最新文件推送功能,将最新发布的文件及时推送给用户,让用户快速了解最新动态。

(6)发布机构分类
图谱根据文件的发布机构。使用户能够通过选择不同发布机构来查看该机构发布的所有文件,了解该机构在制定和执行方面的特点和趋势。

(7)主题词分类
系统根据文件的内容提取主题词进行分类,用户可以通过输入关键词或选择预设的主题词,快速找到与特定主题相关的文件,便于用户快速定位到感兴趣的文件。

(8)文件解读
提供文件的解读,通过方向、区域、群体、实施内容这四个方向进行分析,为用户提供权威的解读和分析。用户可以通过查看专家解读,了解制定的背景、目的和影响,以及执行中可能遇到的问题和解决方案。

(9)文件检索
本研究提供强大的关键字搜索功能,用户可输入关键字搜索相关文件。系统支持模糊搜索和精确搜索两种模式,满足不同用户的搜索需求。搜索结果按照关键字重合度百分比进行排序,方便用户快速找到最需要的文件。

(10)文件预测
系统利用高频词统计和AI问答系统相结合的方式进行文件预测。通过获取用户的历史数据和行为数据,分析历史文件的高频词和趋势变化,预测未来可能关注的领域和重点,AI问答系统也可以针对用户提出的问题进行智能回答,并基于数据和模型给出走向的建议和预测。
 

二、应用领域
- 搜索引擎:通过理解查询的深层含义,提供更准确的搜索结果。
- 推荐系统:利用用户和物品之间的关系,提供个性化推荐。
- 智能问答:快速准确地回答基于知识的问题。
- 数据分析:辅助发现数据中的隐藏模式和关联。

三、 构建步骤
1. 数据收集:从不同来源收集结构化和非结构化数据。
2. 实体识别:从文本中识别出实体,如人名、地点等。
3. 关系抽取:确定实体间的语义关系,如“出生在”、“属于”等。
4. 知识融合:解决不同数据源中的实体对应问题,合并相同实体。
5. 知识存储:将提取的知识以图的形式存储在数据库中。

基于初期对文本数据的清洗,下面要进行综合分析处理,内容包括上下行及其关系等。内容涉及到的文本上下行关系拆分其实是一种阅读对象主观客观混合意识的分析过程,目前尚且没有更为先进的大模型和研究理论提供帮助,所以只能采用2024年1月最新热门长文本汉字智能助手产品Kimi Chat进行综合分析处理,Kimi Chat能够根据给出的实体类型和分析要求高效地提取文件中的关键字,概括内容,客观地进行分析文件之间的关系,且该智能助手会准确并严谨地返回所需的分析结果,再结合团队内成员主观理解分析能够为知识图谱提供全面合理的详细数据支持。
使用模型为文字转向量是在搜索中保证在本次研究的高准确率和相关性的主要措施,在以往的搜索方式中由于算法单一且对中文识别的局限性较大,容易产生对文件的误导,所以这次采用的向量检索方式能够计算文字之间的关联度,目的为找出精确符合搜索的内容才能使阅读文件的效率提高。
引入towhee是针对自然语言处理的经典embedding场景需要,把经过训练和调优后的bert-base-chinese或all-MiniLM-L6-v2模型应用于文本的向量化。把需要转为向量的文本数据以csv文件的方式导入,模型接收经过sentence_transformer函数预处理的文本作为输入,并输出一个固定为384维或32维的向量,该向量编码内蕴含了文本的语义信息,能够捕捉文本的复杂语义关系,包括同义性、反义性、上下文关系等。得出结果后保存到文本文件中。
生成的文本向量随后被存储到Milvus库中。为了处理大量的文本,可能需要使用GPU或其他高性能计算资源来加速向量生成的过程。向量生成到milvus数据库存储显示的流程
首先需要识别文件中的关键实体,如文件名称、发文字号、发布机构、实施日期等,这些实体将成为知识图谱中的节点。接着定义实体之间的关系。例如,一个文件可能由某个机构发布,这构成了“发布”关系;如果一个文件修订了另一个文件,那么这构成了“修订”关系。这些关系在图谱中以边的形式表示。对于每个实体要抽取相关的属性信息,这包括但不限于的具体事权、管理标准、必要条件、审核过程等,这些属性将作为节点的标签,丰富图谱的信息内容。
在Neo4j图数据库中根据实体和关系构建数据模型,这涉及到创建节点类型和关系类型,并为它们定义属性。例如,创建“文件”节点类型,与其他“名称”、等属性建立关联属性。将整理好的结构化数据导入到Neo4j数据库中
导入数据后,开始对图谱进行优化,以提高查询效率和可视化效果。最后将Neo4j连接D3、echarts、Neovis.js、vue、element-plus等前端可视化组件工具,将知识图谱以图形的方式展示出来,有助于用户直观地理解之间的关系结构。
将转换好的向量数据和已经整理好的文本数据存入milvus数据库中,创建数据库中的表和向量索引
通过存储并索引这些向量,Milvus 能够通过计算两个向量的相似距离来分析它们之间的相关性。如果两个嵌入向量非常相似,则意味着原始数据源也相似。Milvus的优点在于能够把图像、声音、文本以及用户行为等非结构化的数据通过深度学习进行向量化,然后通过 Milvus 建立向量索引,为后续的数据维护和数据支持制造了良好基础。
在搜索的实现阶段,研究采用了基于向量的相似性搜索方法。利用Milvus库的高效相似性搜索能力,实现了一个能够处理大量数据并快速返回结果的搜索算法。该算法接收用户的查询条件,将用户查询的关键字转换为向量表示,并在Milvus库中与存储的文件向量进行比较,计算出相似度。在优化了搜索算法的性能时,通过调整索引结构和搜索参数,提高了搜索的速度和准确性。在测试中生成了随机向量进行搜索

Neo4j:同样使用Node.js和Express框架,通过neo4j-driver库与Neo4j图数据库通信。API接收Cypher查询语言编写的查询和相应的参数,执行查询,并将结果以JSON格式发送回前端。

MySQL:使用Node.js和Express框架创建一个API,通过mysql2/promise库与MySQL数据库进行交互。该API允许前端通过POST请求发送SQL查询和参数,后端将执行查询并将结果返回给前端。

Milvus:同样使用Node.js和Express框架,在研究中安装Milvus SDK,连接到Milvus服务器。创建API端点发送请求,接收Node.js服务返回的响应,并在Vue.js前端进行相应的处理,实现与Milvus数据库的交互逻辑,如创建集合、插入数据、搜索向量等。

四、 技术挑战
- 数据质量:确保数据的准确性和一致性。
- 大规模处理:处理和存储大规模数据集。
- 实时更新:知识图谱需要定期更新以反映最新的信息。
- 多语言支持:支持不同语言的知识表示和检索。

五、工具与平台
-Neo4j:一个流行的图形数据库,适用于构建知识图谱。

  1. BERT模型

bert-base-chinese是专门为中文文本设计的BERT模型,它对中文的分词方式进行了优化,有更好地处理中文语言的特性。适合需要深层次中文语言理解的场景,能够提供丰富的语言特征和上下文感知能力。

  1. all-MiniLM-L6-v2模型

all-MiniLM-L6-v2依然能够提供与大型模型相当的性能,特别是在下游任务中。在训练过程中使用了多任务学习(MTL)的策略,这使得模型能够同时学习多种语言任务,如文本分类、问答、命名实体识别等。该模型适用于多种NLP任务,并且可以容易地进行微调以适应特定的应用场景。由于模型尺寸的减小,在运行时需要的计算资源更少,适合在移动设备或计算能力有限的环境中使用。

  1. Towhee

Towhee旨在简化自然语言处理和机器学习中的预处理和特征工程任务,支持多种数据类型的处理。在研究开发周期中,提供的embedding工作流中的SentenceTransformer类预构建的数据处理管道,可以根据需要定制政策数据处理、模型训练等流程,包括数据清洗、标准化、向量化,调用模型等步骤。能够提高处理效率,缩短从文本数据到向量的转换时间。

  1. Vue.js框架

Vue是一个流行的JavaScript前端框架,可以用于构建交互式的Web用户界面。此外还选用了Vue相关的技术栈,如Vuex进行状态管理,Vue Router进行页面路由,以及axios进行HTTP通信。这些技术的组合为前端页面的开发提供了坚实的基础,并且能够确保代码的可维护性和扩展性。政策知识图谱的前端界面使用Vue框架来开发能缩短开发时长,以实现页面的动态加载和交互。

  1. Element UI前端组件

为了确保以大数据为主的研究内容减少代码繁琐庞大带来的困难,系统设计时引入了Element UI,它一个基于Vue.js的前端组件库,提供了丰富的UI组件和样式,可以用于构建渲染政策本研究系统中的表格、表单、菜单等组件。

  1. D3、echartss、Neovis.js可视化组件

D3.js是一个用于制作动态、交互式数据可视化的JavaScript库,echartss是一个强大的可视化库,支持各种图表类型的绘制,Neovis.js是一个基于Neo4j的图形可视化库。这些可视化组件可以用于政策知识图谱的可视化展示,包括节点关系、词频统计等,以便于用户直观地理解文本中的内容及其关系。

  1. Neo4j图数据库

Neo4j是一个面向图形数据库管理系统,适用于存储和处理具有复杂关系的数据。政策文本中的实体类别和关系可以以图形的方式存储在Neo4j中,便于进行复杂的关系查询和分析。

  1. Milvus向量数据库

Milvus是一个专门用于存储和检索向量数据的数据库,可以高效地存储和查询大规模的向量数据,可用于存储政策文本中标题的向量表示,并完成相似度搜索等功能。

  1. Pandas库

Pandas库一个强大的数据分析工具,它提供了快速、灵活以及表达力强的数据结构,旨在使“关系”或“标签”数据的操作既简单又直观。它主要用于数据清洗和分析工作。

  1. jieba库

是一个中文分词库,它支持三种分词模式:精确模式、全模式和搜索引擎模式。jieba分词是中文文本预处理的重要步骤,它可以帮助将中文文本分解成单独的词语,从而便于后续的文本分析和处理。

六、启动应用

执行 `npm run dev` 命令,然后在浏览器中访问 `http://localhost:8081` 以启动应用。

七、文件目录布局

- `index.html` 作为项目的入口页面。

- `build/` 存放构建脚本的目录。

  - `build-server.js` 启动本地构建服务器,以便访问构建后的页面。

  - `build.js` 用于生产环境的构建脚本。

  - `dev-client.js` 为开发服务器提供热重载功能,实现开发中的页面自动刷新。

  - `dev-server.js` 启动本地开发服务器。

  - `utils.js` 包含构建过程中使用的工具方法。

  - `webpack.base.conf.js` 定义了webpack的基础配置。

  - `webpack.dev.conf.js` 定义了webpack的开发环境配置。

  - `webpack.prod.conf.js` 定义了webpack的生产环境配置。

- `config/` 包含项目配置文件。

  - `dev.env.js` 定义开发环境的变量。

  - `index.js` 项目的主要配置文件。

  - `prod.env.js` 定义生产环境的变量。

  - `test.env.js` 定义测试环境的变量。

- `package.json` 定义npm包的配置,包括项目的npm脚本和依赖信息。

- `src/` 存放项目源代码。

  - `index.js` 项目的主JavaScript文件。

  - `app.vue` 根组件。

  - `components/` 存放公共组件。

    - `D3Visualization` 用于数据可视化的组件。

    - `search` 搜索功能的组件。

  - `routes/` 定义前端路由。

    - `index.js` 路由配置文件。

  - `views/` 存放页面文件。

    - `echart/` 知识图谱页面。

    - `page/` 知识图谱页面。

- `static/` 存放纯静态资源,这些资源不会被webpack处理。

八、部分代码展示

<template>
  <el-row class="LayOutBody">
    <!-- 查询条件 -->
    <el-row class="SearchHeader">
      <el-col :span="20" style="margin-top:5px;">
        <el-form :inline="true" :model="searchForm" class="demo-form-inline">
         
        </el-form>
      </el-col>
      <el-col :span="4">
        <div style="float:right; width:1000px;">
          <el-button type="primary" @click="executeCypher(searchForm.policyCata)">整体查询</el-button>
          <el-button @click="onSubmit">重 置</el-button>
        </div>
      </el-col>
    </el-row>
    <!-- 主页面 -->
    <el-row class="MainArea">
      <el-col :span="24" class="Mainleft" v-loading="fullscreenLoading">
        <knowlegGraph ref="knowlegGraph" v-if="knowlegGraphshow" :data="echartsNode" :links="nodesRelation" :category="category" :globalData="globalData"></knowlegGraph>
      </el-col>
    </el-row>


  </el-row>
</template>
<script>

import knowlegGraph from "../echarts/knowlegGraph.vue";
var neo4j = require("neo4j-driver");

export default {
  components: {
    knowlegGraph
  },
  data() {
    return {
      viz: "",

      SQL: "MATCH p=(n:`国家级文件名称`)-->() RETURN p",
      
      knowlegGraphshow: true,

      // 查询条件form数据
      searchForm: {
        
      },


      globalData: [], //用来存放被收起的某节点的子节点


      nodesArray: [],  //节点数组
      edgesArray: [],  //关系线数组



      driver: null,
      cypherkeyword: false,
      graphtable: false,
      records: [],
      clearAll: false,

      echartsData: [],
      echartsNode: [],
      category: [],
      nodesRelation: [],
      currentGraph: {
        nodes: {},
        links: {},
      },
      nodeMap: {},
      network: '',

      fullscreenLoading: false
    }
  },
  created() {
    // setTimeout(() => {
    //   this.queryInfo()
    // }, 800);
  },

  mounted() {
    // this.draw();
    this.executeCypher(this.SQL);

  },
  watch: {
    SQL: {
      handler(newData) {
        // this.draw();

      },
      immediate: true,
      deep: true
    },
  },
  methods: {
    // 重置
    onSubmit() {


    },

    /**
     * 直接执行Cypher
     */
    executeCypher(query) {
      this.fullscreenLoading = true
      this.echartsData = []  //节点数组
      this.echartsNode = []  //节点数组
      this.nodesRelation = [] //关系线数组
      this.category = [] //关系线数组
      // this.nodesArray = []  //节点数组
      // this.edgesArray = [] //关系线数组
      this.knowlegGraphshow = false
      // 创建实例
      this.driver = neo4j.driver('bolt://localhost:7687', neo4j.auth.basic('neo4j', '20030409'));
      console.log("🚀 ~ file: AuthorArticleSearch.vue ~ line 46 ~ mounted ~  this.drive", this.driver)

      let me = this;
      me.records = [];
      this.clearAll = true;
      let session = this.driver.session();
      if (query == "") return;
      session.run(query, {}).then((result) => {
        me.clearAll = false;
        me.records = result.records;
        // console.log("neo4j 结果", result.records);
        // let nodes = new Set();

        // 开始处理数据
        for (let i = 0; i < me.records.length; i++) {
          this.echartsData.push({
            name: me.records[i]._fields[0].segments[0].start.properties.name,
            category: me.records[i]._fields[0].segments[0].start.labels[0]
          });
          this.echartsData.push({
            name: me.records[i]._fields[0].segments[0].end.properties.name,
            category: me.records[i]._fields[0].segments[0].end.labels[0]
          });

          this.nodesRelation.push({
            source: me.records[i]._fields[0].segments[0].start.properties.name,
            target: me.records[i]._fields[0].segments[0].end.properties.name,
            name: me.records[i]._fields[0].segments[0].relationship.type,
          });
        }

        //删除arr中的重复对象
        var arrId = [];
        var legend = [];
        for (var item of this.echartsData) {
          legend.push({ name: item.category })
          if (arrId.indexOf(item.name) == -1) {
            arrId.push(item.name)
            this.echartsNode.push(item);
          }
        }

        this.category = Array.from(new Set(legend))

        session.close();
        me.closeLoading(false);
      }).catch(function (error) {
        console.log("Cypher 执行失败!", error);
        me.driver.close();
      });


      setTimeout(() => {
        console.log("neo4j 处理结果", this.nodesRelation);
        console.log("neo4j edgesArray", this.echartsNode);
        this.knowlegGraphshow = true
        this.fullscreenLoading = false
      }, 4000);

    },
    closeLoading(status) {
      console.log('closeLoading', status);
      // this.$refs.Search.setLoading(status);
    },



    queryInfo() {
      // this.basePolicyDeviationList()
    },


  }
}
</script>
<style scoped>
.LayOutBody {
  width: 100%;
  height: 100%;
  border: 10px solid #EAECEF;
}

/* 头部搜索条件 */
.SearchHeader {
  height: 72px;
  border-bottom: 8px solid #EAECEF;
  background: #ffffff;
  padding: 9px 22px;
}

/* 主体部分 */
.MainArea {
  height: 92.4%;
  border-bottom: 10px solid #EAECEF;
  background: #EAECEF;
}

.Mainleft {
  /* width: 66%; */
  height: 100%;
  background: #ffffff;
}

.Vis {
  position: relative;
}

.menu {
  /*这个样式不写,右键弹框会一直显示在画布的左下角*/
  position: absolute;
  background: rgba(3, 3, 3, 0.6);
  border-radius: 5px;
  left: -99999px;
  top: -999999px;
  color: #fff;
  padding: 5px;
}

.LayOutBody {
  overflow-x: visible !important;
}

.headerTop {
  display: flex;
  justify-content: space-between;
}

.el-header,
.el-footer {
  background-color: #B3C0D1;
  color: #333;
  text-align: center;
  line-height: 60px;
}

.el-aside {
  background-color: #D3DCE6;
  color: #333;
  text-align: center;
  line-height: 200px;
}

.el-main {
  background-color: #E9EEF3;
  color: #333;
  text-align: center;
  line-height: 160px;
}

body>.el-container {
  margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
  line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
  line-height: 320px;
}

.WordExplains {
  display: flex;
  justify-content: left;
  font-size: 0.8rem;
}

.Wordname {
  white-space: nowrap;
}

.WordContent {
  margin-left: 5px;
}

.left {
  width: 100%;
  height: 100%;
  /* margin-bottom: 1.5vh; */
  border-top: 1px solid rgb(212, 212, 212);
  border-bottom: 1px solid rgb(202, 202, 202);
  background-color: #fff;
  /* padding: 0 10px 0 10px; */
  overflow: hidden;
}
</style>
<template>
  <el-row class="LayOutBody">
    <!-- 主页面 -->
    <el-row class="MainArea">
      <el-col :span="24" class="Mainleft" v-loading="fullscreenLoading">
        <div class="left" id="viz1" ref="viz1">
          <div class="left"></div>
          
        </div>

      </el-col>
    </el-row>


  </el-row>
</template>
<script>
import NeoVis from 'neovis.js';

export default {

  data() {
    return {
      viz: "",
      SQL: "MATCH p=(n:`文件名称`)-->() RETURN p LIMIT 3000",
    
      driver: null,
      cypherkeyword: false,
      graphtable: false,
      records: [],
      clearAll: false,

      currentGraph: {
        nodes: {},
        links: {},
      },
      nodeMap: {},
      network: '',

      fullscreenLoading: false
    }
  },
  created() {
  },

  mounted() {
    this.draw();
  },
  watch: {
    SQL: {
      handler(newData) {
        this.draw();
      },
      immediate: true,
      deep: true
    },
  },
  methods: {

    draw(sql) {
      //  this.canvas = document.getElementById("js-canvas");
      var viz1 = this.$refs.viz1;
      var viz;
      console.log(viz1);

      var config = {
        container_id: "viz1",
        server_url: "bolt://localhost:7687",
        server_user: "neo4j",
        server_password: "20030409",

        labels: {
          
          
        arrows: true ,
        initial_cypher: this.SQL,
      };
      viz = new NeoVis(config);
      viz._container = viz1;
      viz.render();
    },

    queryInfo() {
      // this.basePolicyDeviationList()
    },


  }
}
</script>
<style scoped>
.LayOutBody {
  width: 100%;
  height: 100%;
  border: 10px solid #EAECEF;
}

/* 头部搜索条件 */
.SearchHeader {
  height: 72px;
  border-bottom: 8px solid #EAECEF;
  background: #ffffff;
  padding: 9px 22px;
}

/* 主体部分 */
.MainArea {
  height: 92.4%;
  border-bottom: 10px solid #EAECEF;
  background: #EAECEF;
}

.Mainleft {
  /* width: 66%; */
  height: 100%;
  background: #ffffff;
}

.Vis {
  position: relative;
}

.menu {
  /*这个样式不写,右键弹框会一直显示在画布的左下角*/
  position: absolute;
  background: rgba(3, 3, 3, 0.6);
  border-radius: 5px;
  left: -99999px;
  top: -999999px;
  color: #fff;
  padding: 5px;
}

.LayOutBody {
  overflow-x: visible !important;
}

.headerTop {
  display: flex;
  justify-content: space-between;
}

.el-header,
.el-footer {
  background-color: #B3C0D1;
  color: #333;
  text-align: center;
  line-height: 60px;
}

.el-aside {
  background-color: #D3DCE6;
  color: #333;
  text-align: center;
  line-height: 200px;
}

.el-main {
  background-color: #E9EEF3;
  color: #333;
  text-align: center;
  line-height: 160px;
}

body>.el-container {
  margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
  line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
  line-height: 320px;
}

.WordExplains {
  display: flex;
  justify-content: left;
  font-size: 0.8rem;
}

.Wordname {
  white-space: nowrap;
}

.WordContent {
  margin-left: 5px;
}

.left {
  width: 100%;
  height: 100%;
  /* margin-bottom: 1.5vh; */
  border-top: 1px solid rgb(212, 212, 212);
  border-bottom: 1px solid rgb(202, 202, 202);
  background-color: #fff;
  /* padding: 0 10px 0 10px; */
  overflow: hidden;
}
</style>

仓库以及下载链接:(开源)neo4jcode: 研究提供一个综合性知识图谱文件分析平台,通过文件概览、分类、关键字搜索检索、知识图谱深度解读,旨在实现人对信息的深入理解和了解趋势,对信息进行有效的预测,为用户提供全面的、直观而又快捷的信息解析。

 

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值