美文网首页NLP
知识图谱-基于规则的知识抽取实战

知识图谱-基于规则的知识抽取实战

作者: Huoyo | 来源:发表于2019-10-06 19:56 被阅读0次

    一、简介

    基于规则的知识抽取主要还是通过人工定义一些抽取规则,从文章中抽取出三元组信息(实体-关系-实体)。重点即是定义规则。虽然定义规则这种抽取方式看起来有点low,但却简单实用,很多时候,效果比很多高深的算法还要好一些(非绝对,具体领域具体分析)。
    本文的数据来源和https://blog.csdn.net/qq_21120275/article/details/102159314保持一致。

    二、原理

    本文的抽取原理主要分为三个步骤

    第一步:定义需要抽取的关系集合,比如【父亲,母亲,儿子,女儿,...】
    第二步:遍历文章的每一句话,将每句话中非实体和非关系集合里面的词去掉
    第三步:从每句话的第二个词开始遍历,遇到关系集合中的词,就选出该词左右最近的实体

    本文没有贴出全部代码,只拿重点代码作为讲解。

    三、实战

    1、规则集定义

    本文从简单入手,依旧和https://blog.csdn.net/qq_21120275/article/details/102159314一样抽取人物关系,先定义需要抽取的关系集合

    allowRelationships = ['母亲','父亲','儿子','女儿','母','父','下嫁','又嫁','祖父','祖母','孙','孙子','改嫁','哥哥','姐姐','弟弟']
    

    2、数据获取

    使用requests进行文章内容的爬取

    import requests
    from lxml import etree
    import jieba
    from jieba import posseg
    import re
    hraders={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763'}
    url='http://www.uuqgs.com/lsrw/1358.html'
    html = requests.get(url,headers=hraders)
    text = html.content.decode("gb2312","ignore")
    selector = etree.HTML(text)
    content=selector.xpath('//div[@id="newscont"]/p/text()')
    

    3、去除无关词组

    通过jieba词性识别抽取出nr的实体和带有关系的词组

    # 抽取的实体词性
    allowTags = ['nr']
    relationships = set()
    for line in content:
        sentence = []
        for word, tag in posseg.cut(line):
            if tag == 'nr' or word in alowRelationships:
                sentence.append(word)
        sentence = ' '.join(sentence)
    

    4、关系抽取

    遍历一句话,从第二个词组开始,如果该词组属于要抽取的关系词组,则抽出前一个词组作为主语,后一个词语作为宾语:

        sentenceSplit = sentence.split(' ')
        print("原始文本:", line)
        for i in range(1,len(sentenceSplit)-1):
            if sentenceSplit[i] in alowRelationships:
                source = sentenceSplit[i-1]
                relationship = sentenceSplit[i]
                target = sentenceSplit[i+1]
                print('提取结果:',source+'->'+relationship+'->'+target)
                relationships.add(source+'->'+relationship+'->'+target)
    

    5、抽取结果验证

    结果如下:

    '''
    原始文本: 武德九年(626年),玄武门之变后,李渊退位称太上皇,禅位于儿子李世民。
    提取结果: 太上皇->儿子->李世民
    原始文本: 李渊的祖父李虎,在西魏时官至太尉,是西魏八柱国之一。李渊的父亲李昞,北周时历官御史大夫、安州总管、柱国大将军,袭封唐国公。李渊的母亲是隋文帝独孤皇后的姐姐[7] 。
    提取结果: 李渊->祖父->李虎
    提取结果: 李渊->父亲->李昞
    提取结果: 李渊->母亲->隋文帝  #错误结果
    '''
    

    6、知识存储

    本文的存储形式采用rdf格式,使用rdflib工具包进行操作

    import rdflib
    
    g = rdflib.Graph()
    pesonUrl = 'http://www.huoyo.org/person/'
    relationshipUrl = 'http://www.huoyo.org/relationship/'
    for line in relationships:
        line = line.split('->')
        p1 = rdflib.URIRef(pesonUrl+line[0])
        re = rdflib.URIRef(relationshipUrl+line[1])
        #p2 = rdflib.URIRef(pesonUrl+line[2])
        p2 = rdflib.Literal(line[2])
        g.add((p1,re,p2))
        g.serialize("graph.rdf")
    

    文件结果如下

    <?xml version="1.0" encoding="UTF-8"?>
    <rdf:RDF
       xmlns:ns1="http://www.huoyo.org/relationship/"
       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    >
      <rdf:Description rdf:about="http://www.huoyo.org/person/李渊">
        <ns1:女儿>南昌公主</ns1:女儿>
         ...
        <ns1:女儿>高密公主</ns1:女儿>
        <ns1:女儿>长沙公主</ns1:女儿>
        <ns1:儿子>彭思王李元则</ns1:儿子>
      </rdf:Description>
      <rdf:Description rdf:about="http://www.huoyo.org/person/周王李元方">
        <ns1:母>张婕妤</ns1:母>
      </rdf:Description>
       ...
      <rdf:Description rdf:about="http://www.huoyo.org/person/韩王李元嘉">
        <ns1:母>宇文昭仪</ns1:母>
      </rdf:Description>
    </rdf:RDF>
    
    

    7、查询验证

    使用sparql语言进行查询验证

    g = rdflib.Graph()
    g.parse("graph.rdf", format="xml")
    q = "PREFIX p: <"+pesonUrl+">" \
        "PREFIX r: <"+relationshipUrl+">" \
        "select distinct ?b where { p:李渊 r:儿子 ?b }"
    x = g.query(q)
    t = list(x) 
    for i in t:
        print(i)
    

    三、总结

    本文主要基于规则进行知识的抽取,核心点就是关系规则的定义和规则两边的实体抽取,整体效果还行,会有部分错误需要人工干预。基于规则抽取的优缺点如下:

    • 优点
    • 无需训练
    • 实现简单
    • 缺点
    • 需要人工干预,特别是细节处理上
    • 只能抽取实体-关系-实体模式的三元组,对于实体-实体-关系模式需要人工识别
    • 局限于通用领域的实体识别,特殊实体和词性需要单独处理

    相关文章

      网友评论

        本文标题:知识图谱-基于规则的知识抽取实战

        本文链接:https://www.haomeiwen.com/subject/kwjupctx.html