话不多说,开始正文~

github项目来源 lingerun/KGQA_insurance_product

知识图谱数据来源

该项目数据来自OPENKG,是openkg提供的开源数据集,数据存储在.xls文件中。

构建知识图谱代码
# @file: graph_build.py
# @desc: 在neo4j中生成节点和边,构建保险知识图谱

import pandas as pd
from py2neo import Graph,Node

class GraphBuild:
    def __init__(self):
        self.data_path = '../data/ins_product_data.xls'  # ../是返回上一级目录,./是文件所在目录
        # self.g = Graph(
        #     host="localhost",
        #     http_port=7474,
        #     user="neo4j",
        #     password="neo")
        self.g = Graph("http://localhost:7474", username="neo4j", password='neo4j')    # 填写neo4j数据库账户和密码,默认都是neo4j

        data = pd.read_excel(self.data_path)  # 读取保险数据,存储结构为dataframe

        # 分别获取所有公司名称、产品名称和类别1
        company = data['公司名称']
        product = data['产品名称']
        category = data['类别1']

        self.company = list(set(data['公司名称']))   # set去掉重复值,存入列表中
        self.product = list(set(data['产品名称']))
        self.category = list(set(data['类别1']))

        self.rels_product_category = list(zip(product,category))  # 获取产品和类别之间的关系,zip将两个列表压缩,两列表对应位置的元素重新组成一个个元祖
        self.rels_product_company = list(zip(product,company))   # 获取产品和公司之间的关系,[(product[0],company[0]),(product[1],company[1])…]

    def create_node(self):
        for cop in self.company:
            node = Node('company', name=cop)
            self.g.create(node)
        for pro in self.product:
            node = Node('product', name=pro)
            self.g.create(node)
        for cat in self.category:
            node = Node('category', name=cat)
            self.g.create(node)

        print('node create over!')

    def create_rels(self):
        self.create_relationship('product','category',self.rels_product_category,'belong_category','保险种类')
        self.create_relationship('product','company',self.rels_product_company,'belong_company','所属公司')

    '''创建实体关联边'''
    def create_relationship(self, start_node, end_node, edges, rel_type, rel_name):
        count = 0
        # 去重处理
        set_edges = []
        for edge in edges:
            set_edges.append('###'.join(edge))   #["product###category","product###category",……]
        all = len(set(set_edges))
        for edge in set(set_edges):
            edge = edge.split('###')
            p = edge[0]    #["product"]
            q = edge[1]    #["category"]
            query = "match(p:%s),(q:%s) where p.name='%s'and q.name='%s' create (p)-[rel:%s{name:'%s'}]->(q)" % (
                start_node, end_node, p, q, rel_type, rel_name)    # Cypher查询语句,创建product节点和category节点之间的关系
            print(query)
            try:
                self.g.run(query)
                count += 1
                print(rel_type, count, all)
            except Exception as e:
                print(e)
        return

if __name__ == '__main__':
    build_handle = GraphBuild()
    build_handle.create_node()
    build_handle.create_rels()

原作者利用pandas.Node构建product、company、category三种实体,节点间关系利用Cypher语句查询节点生成。生成的知识图谱部分如下所示。
在这里插入图片描述

更新知识图谱代码
# @file: propert_add.py
# @desc: 为知识图谱中product节点增加属性,实现知识图谱的修改

import pandas as pd
from py2neo import Graph,Node

class GraphRevise:
    def __init__(self):
        self.data_path = '../data/ins_product_data.xls'
        # self.g = Graph(
        #     host="localhost",
        #     http_port=7474,
        #     user="neo4j",
        #     password="neo")
        self.g = Graph("http://localhost:7474", username="neo4j", password='neo4j139lxs@')

        data = pd.read_excel(self.data_path)

        company = data['公司名称']
        product = data['产品名称']
        category = data['类别1']
        link = data['产品链接']
        material = data['需要的理赔资料']
        age = data['承保年龄']
        range = data['保障周期']
        content = data['主要保障']

        self.product_property = list(zip(product,link,material,age,range,content))

        self.company = list(set(data['公司名称']))
        self.product = list(set(data['产品名称']))
        self.category = list(set(data['类别1']))

        self.rels_product_category = list(zip(product,category))
        self.rels_product_company = list(zip(product,company))

    def add_property(self):
        for property in self.product_property:
            query = "match(p:product) where p.name='{}' set p.link='{}',p.material='{}',p.age='{}',p.range='{}',p.content='{}'".format(property[0],property[1],property[2],property[3],property[4],property[5])
            print(query)
            self.g.run(query)

if __name__ == '__main__':
    build_handle = GraphRevise()
    build_handle.add_property()

原作者提供了为实体增加属性的代码,同样利用Cypher语句实现,运行结果如下。

在这里插入图片描述

截图没法截完整,所以完整版文字粘贴如下。

    <id>:
    7556
    age:
    18周岁-55周岁
    content:
    身故或全残保险金 重大疾病保险金,特定疾病额外给付保险金 保险费豁免
    link:
    http://www.iachina.cn/IC/tkk/01/53483eb9-387f-4b78-9f34-21420c97e2a1.html
    material:
    身故:保险合同,申请人有效身份证件,被保人死亡证明书,与该保险有关的其他证明和资料;疾病:保险合同,被保险人有效身份证件,三级医院证明,与该保险有关的其他证明和资料;重疾:保险合同,被保险人有效身份证件,重疾医院证明,与该保险有关的其他证明和资料;全残:保险合同,被保险人有效身份证件,三级医院伤残程度鉴定书,与该保险有关的其他证明和资料;养老长期护理险:保险合同,被保险人有效身份证件,三级医院自主生活能力完全丧失鉴定书,与该保险有关的其他证明和资料
    name:
    民生U+女性特定疾病保险
    range:
    自由定制
总结

整个构建过程已经很熟悉了,把这个项目运行一遍是想学习一下为实体添加属性的方法,原作者利用Cypher语句的方法值得学习~

构建知识图谱的项目不再运行学习啦,后面如果有需要再说吧~

完结,撒花啦~~~

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐