知识图谱中“三元组”抽取——Python中模型总结实战(基于TensorFlow2.5)

一、pyhanlp

【基于java的,安装使用前必须先安装java环境】
1、安装:pip install pyhanlp
【安装过程中会自动安装jpype1,该模块仅支持到python3.7,所以python3.7以上的安装老是报错。】
2、使用:
1)分词

import pyhanlp
print([i.word for i in pyhanlp.HanLP.segment('我们都是中国人,坚持一个中国原则。')])

在这里插入图片描述

二、stanfordnlp

【官方GitHub介绍:https://stanfordnlp.github.io/stanfordnlp/training.html
1、安装:pip 安装

 pip install stanfordnlp --proxy 111.666.88.688:808

2、简单使用

 import stanfordnlp

三、pyltp

【学习手札:https://blog.csdn.net/MebiuW/article/details/52496920
【基于C++的】

四、openNRE

GitHub:https://github.com/thunlp/OpenNRE#datasets
清华大学自然语言处理与社会人文计算实验室(THUNLP)推出的一款开源的神经网络关系抽取工具包,包括了多款常用的关系抽取模型。
使用wiki80数据集,包含80种关系。(也可以自己训练)
但是都是英文数据集,使用也都是基于英文的……

1、安装:我安装到windows上了

cmd中下载git相关安装文件:

git clone https://github.com/thunlp/OpenNRE.git

安装requirements.txt中的模块(括号中是我安装的模块版本)

torch==1.6.0   (1.9.0)
transformers==3.4.0  (4.21.3)
pytest==5.3.2 
scikit-learn==0.22.1 (0.23.2)
scipy==1.4.1  (1.4.1)
nltk>=3.6.4  (3.6.2)

安装openNRE

python setup.py develop

2、使用

【注意】
1)windows在导入包的时候会报错:TypeError: expected str, bytes or os.PathLike object, not NoneType
原因:opennre中的pretrain.py中的第13行在windows运行出错(os.getenv(‘HOME’)获取用户主文件地址,windows没有home地址)。
改为:

# default_root_path = os.path.join(os.getenv('HOME'), '.opennre') # Linux
default_root_path = os.path.join(str(Path.home()), 'opennre') # cqf: windows

2)windows在opennre.get_model(‘wiki80_cnn_softmax’)获取模型时报错:wget不是内部执行命令
原因:wget 是一个Linux环境下用于从万维网上提取文件的工具,windows使用时需要单独安装。
安装:①在网站 https://eternallybored.org/misc/wget/ 上下载windows 上适用的安装包(最新版就可);
   ②下载完成后解压:比如我下载的是 wget-1.21.3-win64.zip ,解压到 D:\software\wget-1.21.3-win64;
   ③添加环境变量:比如我的
在这里插入图片描述
导入模块、加载模型、预测

>>> import opennre
>>> model = opennre.get_model('wiki80_cnn_softmax') # 模型还包括:wiki80_bert_softmax、wiki80_bertentity_softmax、tacred_bert_softmax、tacred_bertentity_softmax
>>> model.infer({
   
   'text': 'Huang Xiaoming starred in the TV series "the emperor of Han Dynasty", in which he played Emperor Wu of Han Dynasty.', 'h': {
   
   'pos':(0,13)}, 't': {
   
   'pos':(41,66)}})
('notable work', 0.96822190284729)

五、基于TensorFlow 2自定义NER模型(构建、训练与保存模型范例)

NER实质:对目标句子序列进行特征向量表示,然后输入模型,预测句子中每个词对应所有 class 的概率,概率最高的即为其标注结果。
环境要求:(keras4bert环境要求后面单独说明)

keras_bert.__version__ = 0.88.0 # 要求keras >= 2.4.3
keras.__version__ = 2.4.3
tf.__version__ = 2.5.0
tfa.__version__ = 0.16.1
transformers.__version__ = 4.9.1

超参:

# 超参
config_path='data/chinese_L-12_H-768_A-12/bert_config.json'
check_point_path='data/chinese_L-12_H-768_A-12/bert_model.ckpt'
seq_len=200
layer_nums=4  # keras_bert加载BERT时参数output_layer_num的值,BERT模型每个encoder的MultiHeadSelfAttentio层数
training=False
trainable=False
num_label=4
drop_rate=0.3
is_training=True
hidden_size=600
TransBERT_MODEL_NAME='data/bert-base-uncased'

1、BiLSTM+CRF模型

理解说明:
CRF作用:①训练过程中作为损失函数,计算loss;②预测过程中,用于解码,获取得分最高的句子标记结果。
CRF的解码函数:
tfa.text.crf_decode()获取CRF解码结果,即最高分数的句子标记结果,返回结果包括:
① decode_tags: A [batch_size, max_seq_len] matrix, with dtype tf.int32. Contains the highest scoring tag indices.
② best_score: A [batch_size] vector, containing the score of decode_tags.

代码算法图:
在这里插入图片描述
1、模型构建

import tensorflow as tf
import tensorflow_addons as tfa # 需单独安装

# 基于tf.keras.layers.Layer类定义一个自己的CRF层
class CRF(tf.keras.layers.Layer):
    def __init__(self, label_num) -> None:
        super().__init__()
        self.trans_params = tf.Variable(
            tf.random.uniform(shape=(label_num, label_num)), name="transition")
    
    def call(self, inputs, labels, seq_lens):
        log_likelihood, self.trans_params = tfa.text.crf_log_likelihood(
                                                inputs,  # tensor:[batch_size, max_seq_len, num_tags] 
                                                labels,  # tensor:[batch_size, max_seq_len] 
                                                seq_lens,  # seq_lens为各个句子的真实长度(不包括padding的部分,本模型训练也将不存在于vocab中的部分排除)
                                                transition_params=self.trans_params)
        loss = tf.reduce_mean(-log_likelihood)
        return loss

class BiLSTM_CRF_model(tf.keras.Model):
    def __init__(self, embedding_dim, vocab_size, hidden_size, label_num) -> None:
        super().__init__()
        self.embeding_layer=tf.keras.layers.Embedding(input_dim=vocab_size, 
    						  output_dim=embedding_dim, 
    						  input_length=None,  #Length of input sequences,如果该层后面连接flatten并dense则必须指定input_length。
    						  embeddings_initializer='uniform')
        self.bilstm_layer=tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(hidden_size, return_sequences=True), 
                                                        merge_mode='concat')
        self.dense = tf.keras.layers.Dense(label_num)
        self.crf_layer=CRF(label_num)

    def call(self, input, labels=None, externalEmbed_file=None, training=True):
        # tf.math.not_equal()比较x、y相等情况,返回bool类型的tensor,shape同x或y
        # tf.cast()强制将给定数据转换为指定数据类型
        seq_lens=tf.math.reduce_sum(tf.cast(tf.math.not_equal(input, 0), dtype=tf.int32), axis=-1) # 计算各个橘子的真实长度
        if externalEmbed_file:
            x=tf.nn.embedding_lookup(externalEmbed_file, input)
        else:
            x=self.embeding_layer(input)
        x=self.bilstm_layer(x)
        logits=self.dense(x) # 得到CRF的输入[batch_size, max_seq_len, num_tags]
        if training:
            labels = tf.convert_to_tensor(labels, dtype=tf.int32)
            loss=self.crf_layer(logits, labels, seq_lens)
            return loss, logits, seq_lens
        else:
            return logits, seq_lens

继承tf.keras.Model类构建的模型结构:
在这里插入图片描述
2、模型训练与保存:

def get_acc_one_step(logits, text_lens, labels_batch, model):
    '''
    【这个计算方式不是很好(一般一个句子中什么都不是的部分占比很大,导致即使全部标记结果都是非实体,那最终准确率也很高),
    最后准确率普遍偏高,模型效果不咋地,可以尝试计算精确率、召回率】
    计算实体识别准确率: 计算每个句
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值