带你从入门到精通——知识图谱(六. 知识融合)
建议先阅读我知识图谱专栏中的前置博客,掌握一定的知识图谱前置知识后再阅读本文,链接如下:
知识图谱_梦想是成为算法高手的博客-CSDN博客
目录
六. 知识融合
6.1 知识融合的关键技术
6.2 实体消歧示例
六. 知识融合
知识融合是指将多源异构的候选知识单元进行对齐、消歧以构建出一个一致的、完整的、准确的知识体系,在初始构建知识图谱以及对知识图谱进行更新时都需要进行知识融合,完成知识融合的方法可以分为三类:基于规则和词典的方法、基于机器学习的方法、基于深度学习的方法。
6.1 知识融合的关键技术
指代消解:找出存在共指关系的实体并将其统一归类到同一个实体,其中共指关系是指在文本中,多个表达都指向同一个实体,例如小明和他都是指小明这个人。
基于规则和词典的指代消解方法可以通过指代词词典找出可能的存在共指关系的词,并通过最近匹配原则找到与指代词距离最近的实体,最后将两者进行统一归类。
冲突消解:在可能存在矛盾的SPO三元组或是实体属性中,通过置信度来选出更加可靠的SPO三元组或实体属性。
实体对齐和关系对齐:在不同数据源中,对于同一个实体或是关系可能会有不同的表示方法,例如苹果和apple都是指同一个实体,实体对齐和关系对齐需要将对于同一个实体或关系的不同表示方法进行统一,使这些表示都指向同一个实体或关系。
基于规则和词典的实体对齐和关系对齐方法可以通过构建同义词词典来对可能的存在不同表
示方法的词进行替换,将这些词用同一个词来表示。
实体消歧:某些词有可能存在一词多义的问题,例如苹果可以指水果,也可以指公司,对于这种多义词需要通过实体消歧使其指向一个唯一确定的实体。
6.2 实体消歧示例
假设有如下训练数据:
如下验证数据:
基于机器学习的实体消歧方法示例如下:
import pandas as pd
import jieba
import collections
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
import re# 读取数据
entity_data = pd.read_csv('data/entity_disambiguation/entity_list.csv', encoding='utf=8')
valid_data = pd.read_csv('data/entity_disambiguation/valid_data.csv', encoding='gb18030')# all_names存储所有实体名,keywords存储有重复的实体名
all_names, keywords, res = [], [], []
for name in entity_data['entity_name']:name = name.split('|')all_names.extend(name)for word in name:# 添加实体名到jieba分词器中,jieba后续的分词会按照实体名进行分词jieba.add_word(word)name_cnt = collections.Counter(all_names)
for name, cnt in name_cnt.items():if cnt > 1:keywords.append(name) # 提取有重复的实体名train_sentences = [' '.join(jieba.cut(desc)) for desc in entity_data['desc']]
vectorizer = TfidfVectorizer()
# 基于实体的描述构建实体的TF-IDF特征矩阵
# fit_transform会计算每个token的TF以及IDF值并保存每个token的IDF值,最后返回一个TF-IDF稀疏矩阵
tfidf_matrix = vectorizer.fit_transform(train_sentences)
# print(tfidf_matrix.shape) (16, 619),16为语料库中的文档数量,619为语料库中的唯一的token数量for row, sentence in enumerate(valid_data['sentence']):matches = []for k in keywords:if k in sentence:# escape函数的作用是转义正则表达式中的特殊字符,例如*、+,即自动在这些特殊字符前面添加\for match in re.finditer(re.escape(k), sentence):# 取出多义词的上下文,窗口大小为10,即取多义词的前十个token和后十个tokencontext = sentence[max(0, match.start() - 10): min(len(sentence), match.end() + 10)]context = ' '.join(jieba.cut(context))# 计算多义词上下文的TF-IDF特征向量,TF值根据当前上下文直接计算,IDF值则直接使用训练语料库保存的值,注意添加[]进行升维context_tfidf = vectorizer.transform([context])# print(context_tfidf.shape) (1, 619)sim = cosine_similarity(context_tfidf, tfidf_matrix)[0]# print(type(sim)) <class 'numpy.ndarray'># print(sim.shape) (1, 16)# print(sim[0].shape) (16,)best_match_idx = np.argmax(sim)entity_id = entity_data['entity_id'].iloc[best_match_idx]matches.append(f'{match.start()}-{match.end()}:{entity_id}')row_res = [row]if matches:row_res.append('|'.join(matches))print(f'本句的匹配结果{matches}')else:row_res.append(' ')print('本句没有匹配结果')res.append(row_res)
# 存储结果为DataFrame
res_df = pd.DataFrame(res, columns=['row', 'match'])
print(res_df)