【10】知识图谱实战案例(动手做)

目录

案例1:使用neo4j构建小型金融行业知识图谱

案例2:基于金融知识图谱的问答机器人

案例3:基于金融知识图谱的企业风险挖掘

案例4:使用MRC技术完成事件抽取

案例5:基于法律领域的知识图谱

案例【6】:基于医药领域的知识图谱

案例7:基于农业领域的知识图谱


案例1使用neo4j构建小型金融行业知识图谱

引用于:知识图谱—仅用neo4j搭建简单的金融知识图谱-CSDN博客

数据和任务描述链接:百度网盘 请输入提取码  密码:h8of

一、任务描述

在用neo4j构建一个简单的金融领域的知识图谱,挖掘“高管上市企业行业/概念”之间的关系。

二、数据获取

爬取同花顺官网,得到的html文件,企业信息就存储在这写文件中,需要用BeautifulSoup去解析其内容,挖掘出相关的数据

三、数据清洗,得到图谱源数据

导入到neo4jcsv文件主要有nodes.csv文件(这部分文件在neo4j中是databases的作用)和relationship.csv文件(这部分文件在neo4j中是relation的作用)。

四、导入

使用neo4j-admin导入neo4j,完成实体关系存储

导入命令:

./neo4j-admin import --mode=csv --database=stockkg.db --nodes=/Users/zero/Desktop/kg/stock.csv --nodes=/Users/zero/Desktop/kg/industry.csv --nodes=/Users/zero/Desktop/kg/concept.csv --nodes=/Users/zero/Desktop/kg/executive.csv --relationships=/Users/zero/Desktop/kg/stock_industry.csv --relationships=/Users/zero/Desktop/kg/executive_stock.csv --relationships=/Users/zero/Desktop/kg/stock_concept.csv

案例2基于金融知识图谱的问答机器人

 

from flask import Flask, jsonify, request, abort  
#from flask_cors import *  
from py2neo import Graph,Node,Relationship  
from decimal import Decimal  
from pyhanlp import *   
import json  
import math  
  
app = Flask(__name__)  
#CORS(app, supports_credentials=True)  
@app.route("/qa", methods=['POST', 'GET'])  
def kg_qa():  
    if request.method == 'GET':          
        ques = request.args.get('question')  
        cb = request.args.get('callback')  
        print(ques)  
        qa_graph = Graph('http://localhost:7474',username='neo4j',password='nlp')  
        #qa_graph = Graph('http://10.124.142.22:7474',username='neo4j',password='nlp')  
        keyword = []  
        ansList = []  
        # CRF 词法分析器  
        CRFLexicalAnalyzer = JClass("com.hankcs.hanlp.model.crf.CRFLexicalAnalyzer")  
        analyzer = CRFLexicalAnalyzer()  
        han_word_pos = analyzer.analyze(ques).toString()  
        print(han_word_pos)  
  
        wordlist = han_word_pos.split(" ")  
        for word in wordlist:  
            pos = word.split("/")  
            if "n" in pos[1]:  
                print(pos[0],pos[1])  
                if pos[0] not in keyword:  
                    keyword.append(pos[0])  
        print(keyword)  
#枚举组成cypher查询语句  
        for key1 in keyword:  
            for key2 in keyword:  
                #query_str = "match (n:ques{theme:'%s'})-[r1]->(m:desc{name:'%s'})-[r2]->(a:ans) return a.content"%(key1,key2)  
                query_str = "match (q)-[r2]->(a) where  q.theme=~'.*%s.*' AND a.key=~'.*%s.*' return a.content"%(key1,key2)  
                  
                print(query_str)  
                answer = qa_graph.run(query_str).data()  
                print(answer)  
                if answer:  
                    for item in answer:  
                        print(item)  
                        ans_str = item['a.content']  
                        print(ans_str)  
                        #如果结果里面没有才加入  
                        if ans_str not in ansList:  
                            ansList.append(ans_str)  
        print(ansList)  
  
        #如果两个条件查不出来,那就只查theme  
        if not ansList:  
            for key in keyword:  
                #query_str = "match (n:ques{theme:'%s'})-[r]->(a:ans) return a.content"%(key)  
                query_str = "match (q)-[r2]->(a) where  q.theme=~'.*%s.*' return a.content"%(key)  
                answer = qa_graph.run(query_str).data()  
                if answer:  
                    for item in answer:  
                        ans_str = item['a.content']  
                        print(ans_str)  
                        #如果结果里面没有才加入  
                        if ans_str not in ansList:  
                            ansList.append(ans_str)  
        print(ansList)

 # re_ans = "您想问的是不是这些问题:\n"  
        re_ans = ""  
  
        for i in range(len(ansList)):  
            re_ans += "(%s) %s \n"%(i+1,ansList[i])  
        print(re_ans)  
  
        result = {  
            "question" : ques,  
            "answer" : re_ans  
        }  
        res_str = json.dumps(result)  
        cb_str = cb + "(" + res_str + ")"  
        print(cb_str)  
  
        return cb_str  
    return 'Error Format'  
  
if __name__ == '__main__':  
    from werkzeug.serving import run_simple  
    run_simple('127.0.0.1', 9001, app)  

基于上述代码可以完成基于KBQA的智能问答机器人。本代码使用了flask作为后台,使用了hanlp作为POSNER来解析用户问题,解析完成后,将识别出来的实体传入neo4j中进行查询。

案例3:基于金融知识图谱的企业风险挖掘

一、背景

传统的企业评价主要基于企业的财务信息,借贷记录信息等来判断企业经营状况,以及是否可能违约等信用信息。对于财务健全、在传统银行借贷领域留有记录的大中型企业,这种评价方式无疑较为客观合理。然而,对于更大量的中小微企业,既无法公开获得企业真实财务信息,也无这些企业的公开信用信息,在强变量缺失的情况下,如何利用弱变量客观公正评价企业经营状况,正是本课题需要解决的主要问题。

p企业风险预测背景-2017-CCF-BDCI-Enterprise样本集是从全国2000多万企业抽取部分企业(脱敏后),提供企业主体在多方面留下的行为足迹信息数据

二、样本数据介绍

样本提供两种数据

1)企业身份信息(已脱敏)及企业在一定时间范围内的行为数据。该数据对训练集和评测集都是相同的。

2)目标数据。目标值为该企业在20178月时的经营状况:停业1,正常经营0

三、项目构建思路

AI工程的一般过程:

数据预处理——特征工程——模型训练——模型评估——提供服务/再次训练

四、数据清洗

1. 转化或者去掉数据中存在的中文字符
2. 针对性的填充空置,根据这个工作的类别的平均值,最大值和最小值进行填充,填充的时候考虑公司的注册的时间,
使用相近时间短的同类型的工司的数据进行填充,比如前后
3
3. 针对性的去掉重复的数据,数据本省的噪声,去掉完全相同的数据,比如投资数据出现两份
4. 如何处理异常值,针对有先验证知识的特征进行分组
五、 特征 选择
基础特征 : 添加的过程中进行特征选择和分组,进行多特征多模型训练
1. 直接使用原始数据的列作为特征,使用单个和分组统计的特征,
2. 分时间段记性统计特征
3. 统计特征,比如投资公司的个数,违约的个数等,在本省内的个数和本省外的个数,
4. 计算不同分组之间的统计值的特征
5. 单个数据的同大类别和小类别的公司的个数(已经排序 rank 特征)
6. 同(大、小)行业对根据年份归一化后的注册资本进行排序,得到不同排序次序特征
7. 对一些实数数据,进行取对数特征 变换
偏离值特征 :
1. 计算每一个个体与分组之间的偏离距离,计算分组的均值,得到与每个个体的分组
2. 添加聚类特征,计算单个个体与当年(全部或者 3 年),所有同大类型和同小类型公司的均值的偏差距离
交叉特征 :
1. 跨表时间交叉特征 : 使用不同的表的时间间隔得到特征 , 例如,第一次投资或违约时间和注册时间之间的差值
2. 加减乘除特征、多项式交叉特征,暴力特征,应该是暴力出奇迹
计算的使用进行特征筛选交叉,分别对积极特征和消极特征进行组合,
主管考虑正相关和负相关,比如,分公司的个数、投资公司数量、专利数都是正相关
失信此时、被执行案件此时都是负相关
3. one-hot 特征,将 one-hot 特征乘以某个其他特征
4. stacking 特征,使用树模型得到 stacking 特征
5. 企业关系特征,与这个企业有关系的事务的个数,可以构造一个有向图计算出度和入度
6. 注意时间衰减特征
六、 模型训练与评估
算法:xgboost
训练模型 :
在不同的特征集合上进行单模型调优和多模型融合
复赛的使用分省份预测,提高
结果
评价指标: AUC + F1

树模型有较强的可解释性,往往简单且高效;树模型对于异常值有较强的鲁棒性;树模型对特征处理的要求比较低,不需要对特征进行归一化与空值填充;多模型融合( blending(加权融合),还可以尝试的策略包括:stackingbagging 等)

七、 核心代码讲解 - 偏离值特征
dataset['MPNUM_CLASS'] = dataset['INUM'].apply(lambda x : x if x <= 4 else 5)  
dataset['FSTINUM_CLASS'] = dataset['FSTINUM'].apply(lambda x : x if x <= 6 else 7)  
dataset.fillna(value={'alt_count': 0, 'rig_count': 0}, inplace=True)  
for column in ['MPNUM', 'INUM', 'FINZB', 'FSTINUM', 'TZINUM', 'ENUM', 'ZCZB', 'allnum', 'RGYEAR', 'alt_count', 'rig_count']:  
    groupby_list = [['HY'], ['ETYPE'], ['HY', 'ETYPE'], ['HY', 'PROV'], ['ETYPE', 'PROV'], ['MPNUM_CLASS'], ['FSTINUM_CLASS']]  
    for groupby in groupby_list:  
        if 'MPNUM_CLASS' in groupby and column == 'MPNUM':  
            continue  
        if 'FSTINUM_CLASS' in groupby and column == 'FSTINUM':  
            continue  
        groupby_keylist = []  
        for key in groupby:  
            groupby_keylist.append(dataset[key])  
        tmp = dataset[column].groupby(groupby_keylist).agg([sum, min, max, np.mean]).reset_index()  
        tmp = pd.merge(dataset, tmp, on=groupby, how='left')  
        dataset['ent_' + column.lower() + '-mean_gb_' + '_'.join(groupby).lower()] = dataset[column] - tmp['mean']  
        dataset['ent_' + column.lower() + '-min_gb_' + '_'.join(groupby).lower()] = dataset[column] - tmp['min']  
        dataset['ent_' + column.lower() + '-max_gb_' + '_'.join(groupby).lower()] = dataset[column] - tmp['max']  
        dataset['ent_' + column.lower() + '/sum_gb_' + '_'.join(groupby).lower()] = dataset[column] / tmp['sum']  
dataset.drop(['MPNUM_CLASS', 'FSTINUM_CLASS'], axis=1, inplace=True)  

这段代码的意思是:

首先,根据分组字段对数据集进行分组

然后计算每个个体与分组的均值、最小值、最大值和求和值之间的偏离距离

这类特征对于这个比赛十分有效,是我分数大幅上升的一个原因。

案例4使用MRC技术完成事件抽取

案例分享:中国法研杯CAIL2019http://cail.cipsc.org.cn

案例代码:https://github.com/caldreaming/CAIL

数据集: sQUAD 2.0 ---公开数据集。 中文的是DoReader

一、项目架构

二、机器阅读流程

三、项目方案

案例5:基于法律领域的知识图谱

一、项目介绍

目前知识图谱在各个行业中应用逐步打开,尤其在金融,医疗,法律,旅游方面.知识图谱助力法律智能,能够在一定程度上利用现有大数据以及机器学习/深度学习与自然语言处理技术,提供一些智能的解决方案.本项目将完成两个大方向的工作:

1.罪名为核心,收集相关数据,建成基本的罪名知识图谱,法务资讯对话知识库,案由量刑知识库.

2. 分别基于步骤1的结果,完成以下四个方面的工作:

基于案由量刑知识库的罪名预测模型
基于法务咨询对话知识库的法务问题类型分类
基于法务咨询对话知识库的法务问题自动问答服务
基于罪行知识图谱的知识查询

二、罪名预测

'''''使用svm模型进行预测'''  
    def predict(self, sent):  
        model = joblib.load(self.model_path)  
        represent_sent = self.rep_sentencevector(sent, flag='noseg')  
        text_vector = np.array(represent_sent).reshape(1, -1)  
        res = model.predict(text_vector)[0]  
        label = self.id_dict.get(res)  
        return label  
  
'''''基于wordvector,通过lookup table的方式找到句子的wordvector的表示'''  
    def rep_sentencevector(self, sentence, flag='seg'):  
        if flag == 'seg':  
            word_list = [i for i in sentence.split(' ') if i]  
        else:  
            word_list = self.seg_sent(sentence)  
        embedding = np.zeros(self.embedding_size)  
        sent_len = 0  
        for index, wd in enumerate(word_list):  
            if wd in self.embdding_dict:  
                embedding += self.embdding_dict.get(wd)  
                sent_len += 1  
            else:  
                continue  
        return embedding/sent_len  

三、法务咨询问题分类

问题分类代码 

'''''基于wordvector,通过lookup table的方式找到句子的wordvector的表示'''  
def rep_sentencevector(self, sentence):  
    word_list = self.seg_sent(sentence)[:self.max_length]  
    embedding_matrix = np.zeros((self.max_length, self.embedding_size))  
    for index, wd in enumerate(word_list):  
        if wd in self.embdding_dict:  
            embedding_matrix[index] = self.embdding_dict.get(wd)  
        else:  
            continue  
    len_sent = len(word_list)  
    embedding_matrix = self.modify_sentencevector(embedding_matrix, len_sent)  
  
    return embedding_matrix  
'''''对于OOV词,通过左右词的词向量作平均,作为词向量表示'''  
def modify_sentencevector(self, embedding_matrix, len_sent):  
    context_window = 2  
    for indx, vec in enumerate(embedding_matrix):  
        left = indx - context_window  
        right = indx + context_window  
        if left < 0:  
            left = 0  
        if right > len(embedding_matrix) - 1:  
            right = -2  
        context = embedding_matrix[left:right + 1]  
        if vec.tolist() == [0] * 300 and indx < len_sent:  
            context_vector = context.mean(axis=0)  
            embedding_matrix[indx] = context_vector  
  
    return embedding_matrix  

法务咨询自动问答代码

'''''基于ES的问题查询'''  
    def search_es(self, question):  
        answers = []  
        res = self.search_specific(question)  
        for hit in res:  
            answer_dict = {}  
            answer_dict['score'] = hit['_score']  
            answer_dict['sim_question'] = hit['_source']['question']  
            answer_dict['answers'] = hit['_source']['answers'].split('\n')  
            answers.append(answer_dict)  
        return answers  
 '''''计算问句与库中问句的相似度,对候选结果加以二次筛选'''  
    def similarity_cosine(self, vector1, vector2):  
        cos1 = np.sum(vector1*vector2)  
        cos21 = np.sqrt(sum(vector1**2))  
        cos22 = np.sqrt(sum(vector2**2))  
        similarity = cos1/float(cos21*cos22)  
        if similarity == 'nan':  
            return 0  
        else:  
            return  similarity  

案例【6】:基于医药领域的知识图谱

一、项目背景

从无到有搭建一个以疾病为中心的一定规模医药领域知识图谱,并以该知识图谱完成自动问答与分析服务。

二、构建框架

三、实体、实体关系、属性类型 

四、问答框架

question_classifier.py:问句类型分类脚本
question_parser.py:问句解析脚本
chatbot_graph.py:问答程序脚本 = search_sqler

案例7:基于农业领域的知识图谱

一、项目背景

农业知识图谱是融合了农业地域性,季节性,多样性等特征后,利用农业领域的实体概念与关系,挖掘出农业潜在价值的智能系统

二、系统架构图

三、知识图谱存储

四、技术难点

1.技术难点——NER

2.技术难点——关系提取

3.技术难点——句法依存分析

  • 22
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以使用Neo4j来进行NLP(自然语言处理)的数据训练。Neo4j是一种图形数据库,它的图形结构非常适合处理NLP任务中的复杂关系和语义网络。 在Java中使用Neo4j,我们首先需要导入Neo4j的相关库和依赖。然后,我们可以使用Java的Neo4j驱动程序来连接和操作Neo4j数据。通过这个驱动程序,我们可以执行查询、插入、更新和删除数据等操作。 在NLP数据训练中,我们可以将文本数据转换为图形结构,并使用Neo4j来存储和处理这些数据。例如,我们可以将句子中的词和实体作为节点,将它们之间的关系(如依赖关系、语义关系)作为边。通过构建这样的图形结构,我们可以更好地表示和理解文本中的语义关系。 使用Neo4j进行NLP训练的一个常见任务是实体识别和关系抽取。我们可以使用已有的语料库和机器学习算法来训练模型,然后将模型结果存储到Neo4j中。这样,在实际应用中,我们可以使用已经训练好的模型来进行实体识别和关系抽取。 此外,通过Neo4j的图形查询语言Cypher,我们可以方便地进行复杂的查询和分析。例如,我们可以通过Cypher查询来查找具有特定关系的实体对,或者查找具有特定属性的实体。 总之,Java可以使用Neo4j来进行NLP数据训练。Neo4j的图形数据库特性使得它非常适合处理NLP中的复杂关系和语义网络。我们可以利用Neo4j的功能来存储、处理和查询NLP数据,从而提高NLP任务的效率与精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值