知识图谱-LSTM+CRF人物关系抽取实战,Golang多线程实现方式及并发与同步

88 阅读3分钟

二、实践简介

1、数据来源

本文主要基于历史文章中的人物关系抽取,数据来源于www.lishixinzhi.comwww.uuqgs.com/

2、预测类别(7个)

主语开头:B-SUBJECT
主语非开头:I-SUBJECT
谓语开头:B-PREDICATE
谓语非开头:I-PREDICATE
宾语开头:B-OBJECT
宾语非开头:I-OBJECT
其他:O

3、框架

keras

4、模型结构

本次抽取本质上还是基于LSTM的一个分类问题,至于CRF层,完全是为了保证序列的输出严格性,因为CRF对于预测序列有较强的的限制性,比如B-PRESON后面只能为I-PERSON或者O之类的限制。

_________________________________________________________________
Layer (type)                 Output Shape              Param # 
=================================================================
embedding_1 (Embedding)      (None, 91, 100)           60000     
_________________________________________________________________
bidirectional_1 (Bidirection (None, 91, 100)           60400     
_________________________________________________________________
time_distributed_1 (TimeDist (None, 91, 7)             707       
_________________________________________________________________
crf_1 (CRF)                  (None, 91, 7)             119       
=================================================================
Total params: 121,226
Trainable params: 61,226
Non-trainable params: 60,000

5、项目流程

    # 获取词典映射
    word2id, tag2id, id2word, id2tag = getWordAndTagId('train.txt')
    # 获取句子和标注
    sentences, tags=getSentencesAndTags('train.txt')
    # 将句子和标注转换为id
    sentencesIds, tagsIds = sentencesAndTags2id(sentences, tags,word2id, tag2id)
    # 将句子和标注进行填充,确保输入维度一致
    sentencesIds = pad_sequences(sentencesIds, padding='post')
    tagsIds = pad_sequences(tagsIds, padding='post')
    print(sentencesIds.shape)
    print(tagsIds.shape)
    # 载入模型
    model=model(len(word2id),100,sentencesIds.shape[1],len(tag2id))
   # 训练
    history = model.fit(sentencesIds, tagsIds.reshape([len(tagsIds),-1,1]), epochs=500)

三、数据标注

关于训练数据,未找到合适的标注数据,只能自己标注了,如下:

B-SUBJECT
孙 I-SUBJECT
无 I-SUBJECT
忌 I-SUBJECT
看 O
到 O
外 B-PREDICATE
甥 I-PREDICATE
承 B-OBJECTI-OBJECT
、 O
李 B-OBJECTI-OBJECT
都 O
完 O
了 O
。 O

唐 B-SUBJECT
玄 I-SUBJECT
宗 I-SUBJECT
有 O
两 O
个 O
同 O
母 O
妹 B-PREDICATE
妹 I-PREDICATE
: O
金 B-OBJECTI-OBJECTI-OBJECTI-OBJECT
和 O
玉 B-OBJECTI-OBJECTI-OBJECTI-OBJECT
。 O

...此处省略n多

李 B-SUBJECT
文 I-SUBJECT
有 O
两 O
个 O
妹 B-PREDICATE
妹 I-PREDICATE
, O
一 O
个 O
叫 O
宇 B-OBJECTI-OBJECT
, O
一 O
个 O
叫 O
佳 B-OBJECTI-OBJECT
。 O

四、实战

1、数据预处理

1.1 词典映射

主要是低频词过滤字与id的映射(word2id)、预测类别与id的映射(lable2id),具体实现方式各有不同,不做重点讲解,但要特别注意未登录词的处理:

 word_size = len(words)
 word2id = {count[0]: index for index, count in enumerate(words,start=1)}  
 id2word = {index: count[0] for index, count in enumerate(words,start=1)}
 tag2id = {count[0]: index for index, count in enumerate(tags)}
 id2tag = {index: count[0] for index, count in enumerate(tags)}
 # 填充词
 word2id['<PAD>'] = 0
# 未登录词
 word2id['<UNK>'] = word_size + 1

1.2 从训练文件中获取句子和标签
def getSentencesAndTags(filePath):
    '''
 从文件里面获取句子和标注
 :param filePath:
 :return:
 '''
    with open(filePath,encoding='utf-8') as file:
        wordsAndtags=[line.split() for line in file]
        sentences=[]
        tags=[]
        sentence=[]
        tag=[]
        for wordAndTag in wordsAndtags:
            if len(wordAndTag)==2:
                sentence.append(wordAndTag[0])
                tag.append(wordAndTag[1])
            else:
                sentences.append(sentence)
                tags.append(tag)
                sentence=[]
                tag = []
    return sentences,tags

1.3 输入文本转id

将输入的文本,通过词典,转换成数字序列:

def sentencesAndTags2id(sentences,tags,word2id, tag2id):
    '''
 将句子和标注转换为id
 :param sentences:
 :param tags:
 :param word2id:
 :param tag2id:
 :return:
 '''
    sentencesIds = [[word2id.get(char,len(word2id)) for char in sentence] for sentence in sentences]
    tagsIds = [[tag2id[char] for char in tag] for tag in tags]
    return sentencesIds,tagsIds

1.4 数据填充

为了保证数据的维度一致,进行句子填充

from keras_preprocessing.sequence import pad_sequences
sentencesIds = pad_sequences(sentencesIds, padding='post')
tagsIds = pad_sequences(tagsIds, padding='post')


![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/47d520d20a0b4e4b94ef624f3cbb9878~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252670&x-signature=mCft8Wma0J5Q63oKX2YzNTw9iok%3D)
![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a7d7a8dbbde84e6baff8249a9e316bd2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252670&x-signature=43To60DsVhZIO2zsQFdWKH2iBEY%3D)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://gitee.com/vip204888)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**