知识图谱实践:基于在线百科多义实体的消歧与链接项目实践

900次阅读
没有评论

一词多义是中文信息处理中一个特别常见的现象,经典的”苹果是水果还是公司”问题一直是困扰大家的一个实际问题,而就“苹果”而言,其义项多达19个,如“苹果产品公司”、“邓丽欣演唱歌曲”等,而在知识图谱构建过程当中,经常会遇到实体链接的问题。

知识图谱实践:基于在线百科多义实体的消歧与链接项目实践

上一篇文章从领域实体链接关键技术出发,对实体链接任务的定义、候选实体提及的生成、候选实体块的匹配、候选实体的消歧等环节进行介绍。

本次文章进行实践,借助在线百科知识库,输入句子以及待链接的实体,通过获取百科义项,完成链接项目的实践。

项目地址:

https://github.com/liuhuanyong/WordMultiSenseDisambiguation

1、实现思路

完整的实体链接流程包括实体识别(实体指称识别)和实体链接两个部分,实体识别可以通过基于目标实体名称的精确匹配、基于目标名称与ES搜索排序的实体识别方法,基于序列标注识别等方式完成。

第二个阶段的实体链接是核心部分,为了简要地说明实体链接的流程,本项目将对这一问题进行尝试,实现了一个依靠在线百科知识库的特定句子下词语语义消歧的方法。

知识图谱实践:基于在线百科多义实体的消歧与链接项目实践

如上图所示:

首先,根据给定的待链接实体通过网络请求,获取百科中所记录的多个义项;

其次,获取每个义项对应的页面关键词以及描述信息构造目标上下文,接着,利用词向量相加求平均的方式对上下文进行向量化表示;

最后对词语上下文与义项语义表示相似度计算,并按照得分从大到小排序得到的份最高的实体,完成链接。

2、实现过程

1)收集消歧或者链接词语的多个义项,使用百度百科查询的接口进行解析,返回多个义项的列表。

def collect_mutilsens(self, word):
        url = "http://baike.baidu.com/item/%s?force=1" % parse.quote(word)
        html = self.get_html(url)
        selector = etree.HTML(html)
        sens = [''.join(i.split(':')[1:]) for i in selector.xpath('//li[@class="list-dot list-dot-paddingleft"]/div/a/text()')]
        sens_link = ['http://baike.baidu.com' + i for i in selector.xpath('//li[@class="list-dot list-dot-paddingleft"]/div/a/@href')]
        sens_dict = {sens[i]:sens_link[i] for i in range(len(sens))}
        return sens_dict

2)根据列表中的实体义项,获取每个义项对应的描述信息,作为该个义项的意义描述。

(1)获取描述信息

def extract_desc(self, link):
        html = self.get_html(link)
        selector = etree.HTML(html)
        keywords = selector.xpath('//meta[@name="keywords"]/@content')
        desc = selector.xpath('//meta[@name="description"]/@content')
        return desc, keywords

(2)获取义项上下文

def collect_concepts(self, wd):
        sens_dict = self.collect_mutilsens(wd)
        for concept, links in sens_dict.items():
            link = links[0]
            desc, keywords = self.extract_desc(link)
            context = ''.join(desc + [' '] + keywords)
            concepts_dict[concept] = context
        return concepts_dict

3)对实体义项的描述信息进行关键词提取,作为整个义项的一个语义特征表示。

def extract_keywords(self, sent):
        keywords = [i for i in anse.extract_tags(sent, topK=20, withWeight=False)]
        return keywords

4)调用预训练词向量文件,对实体义项上下文以及消歧或者链接词语的上下文进行向量化表示。

(1)加载词向量

 def load_embedding(self, embedding_path):
        embedding_dict = {}
        for line in open(embedding_path):
            line = line.strip().split(' ')
            wd = line[0]
            vector = np.array([float(i) for i in line[1:]])
            embedding_dict[wd] = vector
        return embedding_dict

(2)获取单个词的词向量

def get_wordvector(self, word):
        return np.array(self.embdding_dict.get(word, [0]*self.embedding_size))

(3)基于wordvector,通过lookup table的方式找到句子的wordvector的表示

def rep_sentencevector(self, sentence):
        word_list = self.extract_keywords(sentence)
        unknown_embedding = np.zeros(self.embedding_size)
        embedding = np.zeros(self.embedding_size)
        for wd in word_list:
            embedding += self.embdding_dict.get(wd, unknown_embedding)
        return embedding/len(sent_len)

(4)利用cosine余弦相似度计算两个上下文的语义相似度,作为链接得分

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 str(similarity) == 'nan':
            return 0.0
        else:
            return similarity

(5)对链接的得分按照从大到小排序,返回最终实体链接结果

    def detect_main(self, sent, word):
        sent = sent.replace(word, '')
        concept_dict = self.collect_concepts(word)
        sent_vector = self.rep_sentencevector(sent)
        concept_scores_sent = {}
        for concept, desc in concept_dict.items():
            concept_vector = self.rep_sentencevector(desc)
            similarity_sent = self.similarity_cosine(sent_vector, concept_vector)
            concept_scores_sent[concept] = similarity_sent 
        concept_scores_sent = sorted(concept_scores_sent.items(), key=lambda asd:asd[1],reverse=True)
        return concept_scores_sent[:3]

3、实体链接效果

我们以“苹果”作为待链接实体,并给出相应的上下文进行测试,可以得到如下结果。

1)上下文:苹果发布新产品了。待链接实体:苹果

结果:

[('公司', 0.4309597564421702), ('物品', 0.39608141793731144), ('歌曲', 0.37937766923800026)]

2)上下文:最近连降大雨,种苹果的果农损失惨重。待链接实体:苹果

结果:

[ ('果树', 0.23943442305363207), ('角色', 0.22535153116801097),  ('歌曲', 0.21173595044037458)]

4、总结

本文给出了一个基于在线百科知识库的实体链接实现项目,实体链接是当前实体应用的重要技术手段,我们需要从算法和工程两侧多加以关注

关于该项目的实现源码,可访问:

https://github.com/liuhuanyong/WordMultiSenseDisambiguation


5、关于我们

老刘,刘焕勇,NLP开源爱好者与践行者,主页:https://liuhuanyong.github.io。

老刘说NLP,将定期发布语言资源、工程实践、技术总结等内容,欢迎关注、转发、分享、收藏。

​​

 

Read More 

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 
评论(没有评论)
Generated by Feedzy