精华内容
下载资源
问答
  • 命名实体识别算法crf
    2022-03-04 11:29:47

    完整代码 https://www.heywhale.com/home/competition/6216f74572960d0017d5e691/content/

    条件随机场-CRF

    CRF,英文全称为Conditional Random Field, 中文名为条件随机场,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫(Markov)随机场。

    较为简单的条件随机场是定义在线性链上的条件随机场,称为线性链条件随机场(linear chain conditional random field)。

    线性链条件随机场可以用于序列标注等问题,需要解决的命名实体识别(NER)任务正好可通过序列标注方法解决。

    在条件概率模型P(Y|X)中,Y是输出变量,表示标记序列(或状态序列),X是输入变量,表示需要标注的观测序列。

    训练时,利用训练数据 集通过极大似然估计或正则化的极大似然估计得到条件概率模型p(Y|X);
    预测时,对于给定的输入序列x,求出条件概率p(y|x)最大的输出序列y


    Linear-chain CRF推导:https://lauraruis.github.io/2021/01/25/crfpt1.html

    实践1:基于CRF++实现NER

    CRF++简介

    CRF++是著名的条件随机场的开源工具,也是目前综合性能最佳的CRF工具,采用C++语言编写而成。其最重要的功能我认为是采用了特征模板。这样就可以自动生成一系列的特征函数,而不用我们自己生成特征函数,我们要做的就是寻找特征,比如词性等。


    官网地址:http://taku910.github.io/crfpp/

    安装

    CRF++的安装可分为Windows环境和Linux环境下的安装。关于Linux环境下的安装,可以参考文章:CRFPP/CRF++编译安装与部署 。 在Windows中CRF++不需要安装,下载解压CRF++0.58文件即可以使用

    训练语料创建

    在训练之前需要将标注数据转化为CRF++训练格式文件:

    分两列,第一列是字符,第二例是对应的标签,中间用\t分割。

    比如标注方案采用BISO,效果如下:

    模板

    模板是使用CRF++的关键,它能帮助我们自动生成一系列的特征函数,而不用我们自己生成特征函数,而特征函数正是CRF算法的核心概念之一。一个简单的模板文件如下:

    在这里,我们需要好好理解下模板文件的规则。T**:%x[#,#]中的T表示模板类型,两个"#"分别表示相对的行偏移与列偏移。一共有两种模板:

    训练

    crf_learn -f 3 -c 4.0 -m 100 template train.data crf_model > train.rst

    其中,template为模板文件,train.data为训练语料,-t表示可以得到一个model文件和一个model.txt文件,其他可选参数说明如下:

    -f, –freq=INT使用属性的出现次数不少于INT(默认为1)
    
    -m, –maxiter=INT设置INT为LBFGS的最大迭代次数 (默认10k)
    
    -c, –cost=FLOAT    设置FLOAT为代价参数,过大会过度拟合 (默认1.0)
    
    -e, –eta=FLOAT设置终止标准FLOAT(默认0.0001)
    
    -C, –convert将文本模式转为二进制模式
    
    -t, –textmodel为调试建立文本模型文件
    
    -a, –algorithm=(CRF|MIRA)    选择训练算法,默认为CRF-L2
    
    -p, –thread=INT线程数(默认1),利用多个CPU减少训练时间
    
    -H, –shrinking-size=INT    设置INT为最适宜的跌代变量次数 (默认20)
    
    -v, –version显示版本号并退出
    
    -h, –help显示帮助并退出

    输出信息

    iter:迭代次数。当迭代次数达到maxiter时,迭代终止
    
    terr:标记错误率
    
    serr:句子错误率
    
    obj:当前对象的值。当这个值收敛到一个确定值的时候,训练完成
    
    diff:与上一个对象值之间的相对差。当此值低于eta时,训练完成

    预测

    在训练完模型后,我们可以使用训练好的模型对新数据进行预测,预测命令格式如下:

    crf_test -m crf_model test.data > test.rstt

    -m model表示使用我们刚刚训练好的model模型,预测的数据文件为test.data> test.rstt 表示将预测后的数据写入到test.rstt 中。

    实践2:基于sklearn_crfsuite实现NER

    sklearn_crfsuite简介

    sklearn-crfsuite是基于CRFsuite库的一款轻量级的CRF库。该库兼容sklearn的算法,因此可以结合sklearn库的算法设计实体识别系统。sklearn-crfsuite不仅提供了条件随机场的训练和预测方法还提供了评测方法。

    https://sklearn-crfsuite.readthedocs.io/en/latest/#

    安装:pip install sklearn-crfsuite

    特征与模型创建

    特征构造:

    模型初始化

    crf_model = sklearn_crfsuite.CRF(algorithm='lbfgs',c1=0.25,c2=0.018,max_iterations=100,
                                     all_possible_transitions=True,verbose=True)
    crf_model.fit(X_train, y_train)

    参考资料

    参考资料

     

    更多相关内容
  • CRF命名实体识别

    千次阅读 2022-04-14 19:53:47
    CRF 层可以向最终的预测标签添加一些约束,以确保它们是有效的。这些约束可以由 CRF 层在训练过程中从训练数据集自动学习。 CRF损失函数: Path Score Real = Emission score(发射分数) + Transition score...

    CRF 层可以向最终的预测标签添加一些约束,以确保它们是有效的。这些约束可以由 CRF 层在训练过程中从训练数据集自动学习。

    CRF损失函数:

    Path Score Real = Emission score(发射分数) + Transition score(转移分数)

    Emission score:神经网络输出的各个Tag的置信度;

    Transition score:CRF层中各个Tag之前的转移概率;Preal path = escore

    当只使用CRF做NER的时候规则都是人为制定的

    在只有CRF的情况下,上面说的2类特征函数都是人工设定好的。通俗的说就是人工设定了观测序列的特征;计算的时候,如果这句话符合特征模板中的特征规则,则那个特征规则的值就为1,否则就为0。

    而深度学习模型+CRF则是模型根据数据训练得出的规则模板

     为什么不能通过人工来判断标注规则并编写好修正逻辑呢?
    因为人工虽然能判断出预测的标注前后关系是否符合规则,但是无法知道如何对不符合规则的预测进行调整,比如我们知道句子的开头应该是“B-”或“O”,而不是“I-”,但是究竟是B-还是O呢?而且对于标注状态非常多的场景下,人工编写的工作量和逻辑是非常大且复杂的

    BERT负责学习输入句子中每个字和符号到对应的实体标签的规律,而CRF负责学习相邻实体标签之间的转移规则

    CRF层可以自己学习这些约束。我们不需要手动构建矩阵。随着训练迭代次数的增加,分数会逐渐趋于合理。

    正确路径的分数求解分以下两部分:

    《1:发射分数

    《2:转移分数:实际是CRF的学习参数

    所有路径的得分总和

    基于损失最小化原则,前面加符号

    基于上面式子,就是求下面的分母

     发射矩阵:三个字符w、两个标签l

     

    下面展开成矩阵是为了便于计算

    对previous和 obs和转移矩阵求和

    实际根据previous就能求出所有路径得分之和(4种情况)

    在解码阶段:

    我们还有两个变量用来存储历史信息(得分和索引),alpha0​和alpha1​

     

    用两个列表存储每一步的最大得分以及其对应的标签,然后解码从尾到头根据两个列表回溯出最优解码路径。

    维特比存储上一个节点的最大概率节点路径,带来的好处是:最优路径变为了节点个数3条,而不是之前的3^5条了

    展开全文
  • 使用CRF++实现命名实体识别(NER) https://www.cnblogs.com/jclian91/p/10795413.html 利用crf++进行实体识别 https://www.jianshu.com/p/f5868fdd96d2 最近文章 EMNLP 2022 和 COLING 2022,投哪个会议比较好?...

    每天给你送来NLP技术干货!


    来自:ChallengeHub

    作者:致Great

    完整代码 https://www.heywhale.com/home/competition/6216f74572960d0017d5e691/content/

    1

    条件随机场-CRF

    CRF,英文全称为Conditional Random Field, 中文名为条件随机场,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫(Markov)随机场。

    较为简单的条件随机场是定义在线性链上的条件随机场,称为线性链条件随机场(linear chain conditional random field)。

    线性链条件随机场可以用于序列标注等问题,需要解决的命名实体识别(NER)任务正好可通过序列标注方法解决。

    5ec18b343d1013b968899ef46e92bb00.png

    在条件概率模型P(Y|X)中,Y是输出变量,表示标记序列(或状态序列),X是输入变量,表示需要标注的观测序列。

    训练时,利用训练数据 集通过极大似然估计或正则化的极大似然估计得到条件概率模型p(Y|X);
    预测时,对于给定的输入序列x,求出条件概率p(y|x)最大的输出序列y

    利用线性链CRF来做实体识别的时候,需要假设每个标签 的预测同时依赖于先前预测的标签 和 的词语输入序列,如下图所示ec2dd672599532c7053fea67551ab37b.png每个 NER标签仅依赖于其直接前前继和后继标签以及 x

    CRF是一种选择因子的特定方式,换句话说,就是特征函数。定义因子的 CRF 方法是采用实值特征函数  与参数 θ 和  θ 的线性组合的指数,下面是特征函数与权重参数在时间步上是对应的:

    关于Linear-chain CRF的训练推导,可以查看文章:条件随机场CRF(一)从随机场到线性链条件随机场 

    2

    实践1:基于CRF++实现NER

    CRF++简介

    CRF++是著名的条件随机场的开源工具,也是目前综合性能最佳的CRF工具,采用C++语言编写而成。其最重要的功能我认为是采用了特征模板。这样就可以自动生成一系列的特征函数,而不用我们自己生成特征函数,我们要做的就是寻找特征,比如词性等。2c61643bbecfc7024911f408f581ae1f.png官网地址:http://taku910.github.io/crfpp/

    安装

    CRF++的安装可分为Windows环境和Linux环境下的安装。关于Linux环境下的安装,可以参考文章:CRFPP/CRF++编译安装与部署 。在Windows中CRF++不需要安装,下载解压CRF++0.58文件即可以使用

    b2edeaf3b9ffd2305f938e57bc0e1532.png

    训练语料创建

    在训练之前需要将标注数据转化为CRF++训练格式文件:

    分两列,第一列是字符,第二例是对应的标签,中间用\t分割。

    比如标注方案采用BISO,效果如下:

    08ca90b022ed50384a7477f62de7a1db.png

    模板

    模板是使用CRF++的关键,它能帮助我们自动生成一系列的特征函数,而不用我们自己生成特征函数,而特征函数正是CRF算法的核心概念之一。一个简单的模板文件如下:2a59a65a827a68b4fa5178a3a014e195.png在这里,我们需要好好理解下模板文件的规则。T**:%x[#,#]中的T表示模板类型,两个"#"分别表示相对的行偏移与列偏移。一共有两种模板:8522f0d47b235d5f54b638e2c48feb49.png

    训练

    crf_learn -f 3 -c 4.0 -m 100 template train.data crf_model > train.rst

    其中,template为模板文件,train.data为训练语料,-t表示可以得到一个model文件和一个model.txt文件,其他可选参数说明如下:

    -f, –freq=INT使用属性的出现次数不少于INT(默认为1)
    
    -m, –maxiter=INT设置INT为LBFGS的最大迭代次数 (默认10k)
    
    -c, –cost=FLOAT    设置FLOAT为代价参数,过大会过度拟合 (默认1.0)
    
    -e, –eta=FLOAT设置终止标准FLOAT(默认0.0001)
    
    -C, –convert将文本模式转为二进制模式
    
    -t, –textmodel为调试建立文本模型文件
    
    -a, –algorithm=(CRF|MIRA)    选择训练算法,默认为CRF-L2
    
    -p, –thread=INT线程数(默认1),利用多个CPU减少训练时间
    
    -H, –shrinking-size=INT    设置INT为最适宜的跌代变量次数 (默认20)
    
    -v, –version显示版本号并退出
    
    -h, –help显示帮助并退出

    输出信息

    iter:迭代次数。当迭代次数达到maxiter时,迭代终止
    
    terr:标记错误率
    
    serr:句子错误率
    
    obj:当前对象的值。当这个值收敛到一个确定值的时候,训练完成
    
    diff:与上一个对象值之间的相对差。当此值低于eta时,训练完成

    预测

    在训练完模型后,我们可以使用训练好的模型对新数据进行预测,预测命令格式如下:

    crf_test -m crf_model test.data > test.rstt

    -m model表示使用我们刚刚训练好的model模型,预测的数据文件为test.data> test.rstt  表示将预测后的数据写入到test.rstt  中。b0d3360de6e70c7e76fd9dd90a381002.png

    3

    实践2:基于sklearn_crfsuite实现NER

    sklearn_crfsuite简介

    sklearn-crfsuite是基于CRFsuite库的一款轻量级的CRF库。该库兼容sklearn的算法,因此可以结合sklearn库的算法设计实体识别系统。sklearn-crfsuite不仅提供了条件随机场的训练和预测方法还提供了评测方法。

    https://sklearn-crfsuite.readthedocs.io/en/latest/#

    d2df74f2259346adc21ad4d93bc9e098.png

    安装:pip install sklearn-crfsuite

    特征与模型创建

    特征构造:eb505aeb2e41f75782aa746d745f3835.png模型初始化

    crf_model = sklearn_crfsuite.CRF(algorithm='lbfgs',c1=0.25,c2=0.018,max_iterations=100,
                                     all_possible_transitions=True,verbose=True)
    crf_model.fit(X_train, y_train)

    完整代码如下:

    import re
    import sklearn_crfsuite
    from sklearn_crfsuite import metrics
    import joblib
    import yaml
    import warnings
    
    warnings.filterwarnings('ignore')
    
    
    
    def load_data(data_path):
        data = list()
        data_sent_with_label = list()
        with open(data_path, mode='r', encoding="utf-8") as f:
            for line in f:
                if line.strip() == "":
                    data.append(data_sent_with_label.copy())
                    data_sent_with_label.clear()
                else:
                    data_sent_with_label.append(tuple(line.strip().split(" ")))
        return data
    
    def word2features(sent, i):
        word = sent[i][0]
    
        features = {
            'bias': 1.0,
            'word': word,
            'word.isdigit()': word.isdigit(),
        }
        if i > 0:
            word1 = sent[i-1][0]
            words = word1 + word
            features.update({
                '-1:word': word1,
                '-1:words': words,
                '-1:word.isdigit()': word1.isdigit(),
            })
        else:
            features['BOS'] = True
    
        if i > 1:
            word2 = sent[i-2][0]
            word1 = sent[i-1][0]
            words = word1 + word2 + word
            features.update({
                '-2:word': word2,
                '-2:words': words,
                '-3:word.isdigit()': word1.isdigit(),
            })
    
        if i > 2:
            word3 = sent[i - 3][0]
            word2 = sent[i - 2][0]
            word1 = sent[i - 1][0]
            words = word1 + word2 + word3 + word
            features.update({
                '-3:word': word3,
                '-3:words': words,
                '-3:word.isdigit()': word1.isdigit(),
            })
    
        if i < len(sent)-1:
            word1 = sent[i+1][0]
            words = word1 + word
            features.update({
                '+1:word': word1,
                '+1:words': words,
                '+1:word.isdigit()': word1.isdigit(),
            })
        else:
            features['EOS'] = True
    
        if i < len(sent)-2:
            word2 = sent[i + 2][0]
            word1 = sent[i + 1][0]
            words = word + word1 + word2
            features.update({
                '+2:word': word2,
                '+2:words': words,
                '+2:word.isdigit()': word2.isdigit(),
            })
    
        if i < len(sent)-3:
            word3 = sent[i + 3][0]
            word2 = sent[i + 2][0]
            word1 = sent[i + 1][0]
            words = word + word1 + word2 + word3
            features.update({
                '+3:word': word3,
                '+3:words': words,
                '+3:word.isdigit()': word3.isdigit(),
            })
    
        return features
    
    def sent2features(sent):
        return [word2features(sent, i) for i in range(len(sent))]
    
    
    def sent2labels(sent):
        return [ele[-1] for ele in sent]
    train=load_data('data/train.txt')
    valid=load_data('data/train.txt')
    test=load_data('data/train.txt')
    print(len(train),len(valid),len(test))
    
    sample_text=''.join([c[0] for c in train[0]])
    sample_tags=[c[1] for c in train[0]]
    print(sample_text)
    print(sample_tags)
    
    
    X_train = [sent2features(s) for s in train]
    y_train = [sent2labels(s) for s in train]
    
    X_dev = [sent2features(s) for s in valid]
    y_dev = [sent2labels(s) for s in valid]
    # **表示该位置接受任意多个关键字(keyword)参数,在函数**位置上转化为词典 [key:value, key:value ]
    crf_model = sklearn_crfsuite.CRF(algorithm='lbfgs',c1=0.25,c2=0.018,max_iterations=100,
                                     all_possible_transitions=True,verbose=True)
    crf_model.fit(X_train, y_train)

    训练效果如下:

    labels=list(crf_model.classes_)
    labels.remove("O")
    y_pred = crf_model.predict(X_dev)
    metrics.flat_f1_score(y_dev, y_pred,
                          average='weighted', labels=labels)
    sorted_labels = sorted(labels,key=lambda name: (name[1:], name[0]))
    print(metrics.flat_classification_report(
        y_dev, y_pred, labels=sorted_labels, digits=3
    ))
    c75fb06b5004e560b9e3ae8830806614.png

    4

    参考资料

    参考资料

    • 条件随机场CRF及CRF++安装与使用 https://www.biaodianfu.com/crf.html

    • 使用CRF++实现命名实体识别(NER) https://www.cnblogs.com/jclian91/p/10795413.html

    • 利用crf++进行实体识别
      https://www.jianshu.com/p/f5868fdd96d2

    最近文章

    EMNLP 2022 和 COLING 2022,投哪个会议比较好?

    一种全新易用的基于Word-Word关系的NER统一模型,刷新了14种数据集并达到新SoTA

    阿里+北大 | 在梯度上做简单mask竟有如此的神奇效果


    下载一:中文版!学习TensorFlow、PyTorch、机器学习、深度学习和数据结构五件套!  后台回复【五件套】
    下载二:南大模式识别PPT  后台回复【南大模式识别】

    投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

    方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

    1b776a4a5d98c3c4bd24ccba9aea110f.png

    记得备注呦

    整理不易,还望给个在看!
    展开全文
  • 为提高医院对复杂数据的处理效率,减轻工作人员的压力,本文提出了一种基于条件随机场(CRF)模型和特征模板结合的算法,来识别中文电子病历中的命名实体单元,识别准确率可以达到92.9%,可以有效地识别电子病历命名...
  • 基于CRF命名实体识别模型 条件随机场 CRF ​ 条件随机场 CRF 是在已知一组输入随机变量条件的情况下,输出另一组随机变量的条件概率分布模型;其前提是假设输出随机变量构成马尔可夫随机场;条件随机场可以应用于...

    基于CRF的命名实体识别模型

    条件随机场 CRF

    ​ 条件随机场 CRF 是在已知一组输入随机变量条件的情况下,输出另一组随机变量的条件概率分布模型;其前提是假设输出随机变量构成马尔可夫随机场;条件随机场可以应用于不同类型的标注问题,例如:单个目标的标注、序列结构的标注和图结构的标注等。

    ​ 在给定训练集 x x x 和对应的标记序列 y y y ,以及多个特征函数需要学习 CRF 的模型参数 λ j , u k \lambda_j,u_k λj,uk 和 条件概率分布 P ( y ∣ x ) P(y|x) P(yx) ,条件概率和模型参数的参数化形式如下:

    在这里插入图片描述

    ​ 其中可以看出 CRF 有两类特征函数,一类是定义在 y y y 节点上的节点特征函数,这类特征函数只和当前节点有关如下式所示,其中 K K K 是定义在该节点的节点特征函数的总个数, i i i 是当前节点在序列的位置。
    s k ( y i , x , i ) , k = 1 , 2 , . . . , K s_k(y_i,x,i), k = 1,2,...,K sk(yi,x,i),k=1,2,...,K
    ​ 另一类是定义在 y y y 上下文的局部特征函数,这类特征函数只和当前节点和上一节点有关如下公式所示,其中 J J J 是定义在该节点的局部特征函数的总个数, i i i 是当前节点在序列的位置。
    t j ( y i + 1 , y i , x , i ) , j = 1 , 2 , . . . , J t_j(y_{i+1},y_i,x,i), j = 1,2,...,J tj(yi+1,yi,x,i),j=1,2,...,J

    基于CRF的命名实体识别

    ​ 首先采用 CRF 模型对每个汉字标注对应实体类型的BIO标记,BIO 标记有 B-Person-人名的开始部分、I-Person-人名的中间部分、B-Organization-组织机构的开始部分、I-Organization-组织机构的中间部分和 O-非实体信息。例如:句子“白居易是中国杰出的诗人”,其对应的观察序列和标注序列如下所示:

    在这里插入图片描述

    ​ 根据 CRF 的特征函数可以构建上下文特征、词本身特征和词性特征等,示例如下:

    在这里插入图片描述

    基于 BiLSTM + CRF 的命名实体识别模型

    模型实现原理

    ​ 基于 BiLSTM + CRF 的命名实体识别模型如下所示,每个句子按照词序逐个输入双向LSTM中,结合正反向隐层输出得到每个词属于每个实体类别标签的概率,输入CRF中,优化目标函数,从而得到每个词所属的实体类别。

    在这里插入图片描述

    ​ 其中 BiLSTM 层的输入是每个词的向量表示;BiLSTM 层的输出是当前时刻的输入属于每个实体类别标签的概率。

    ​ CRF 层主要负责计算得分,根据上面的介绍 CRF 的两类特征函数分别计算得分,第一类仅仅和当前节点有关的特征函数 s k ( y i , x , i ) s_k(y_i,x,i) sk(yi,x,i) 计算 Emission 得分,如下图所示,例如图中 w 0 w_0 w0 被标记为 B-Person 的分数为1.5, w 1 w_1 w1 被标记为 B-Person 的分数为0.2。

    在这里插入图片描述

    ​ 第二类和当前节点和上一节点有关的特征函数 t j ( y i + 1 , y i , x , i ) t_j(y_{i+1},y_i,x,i) tj(yi+1,yi,x,i) 计算 Transition 得分,如下图所示:

    在这里插入图片描述

    ​ CRF 路径得分计算公式与示例如下图所示:

    在这里插入图片描述

    ​ CRF 的损失函数计算公式如下所示,对于5个词组成的句子,假定类别标签有5个(B-Person, I-Person, B-Organization, I-Organization, O),其可能的类别序列有 5 5 = 3125 5^5 = 3125 55=3125 种,即 N = 3125

    在这里插入图片描述

    模型编码实现

    文件目录介绍

    • data:微博命名实体数据集 weiboNER 包含 .tran .dev .test 训练集、开发集和测试集三部分。预训练好的 50 维的词向量 gigaword_chn.all.a2b.uni.ite50.vec

    • model:模型训练,包含 bilstm_crf.pycrf.py

    • utils:工具包,主要包含数据预处理相关方法

    • BiLSTM+CRF源码地址

    程序运行逻辑

    if __name__ == '__main__':
        # 各类参数设置
        ''' ...
        '''
        # 数据处理
        data_initialization(data, train_file, dev_file, test_file)
        data.build_word_pretrain_emb(word_emb_file)
        print('finish loading')
        data.generate_instance(train_file, 'train')
        print("train_file done")
        data.generate_instance(dev_file, 'dev')
        print("dev_file done")
        data.generate_instance(test_file, 'test')
        print("test_file done")
        print('random seed: ' + str(seed_num))
        
        # 模型的声明
        model = BiLSTM_CRF(data)
        print("打印模型可优化的参数名称")
        for name, param in model.named_parameters():
            if param.requires_grad:
                print(name)
    
        save_model_dir = "data/model_para/OntoNotes_lstm_gat_crf_epoch"
        o_label2index = data.label_alphabet.instance2index['O']
        train(data, model, save_model_dir, o_label2index)
    

    数据处理

    data_initialization() 调用 ../utils/data.py 中对应的方法构建训练集、开发集和测试集词典,并从数据中确定标签格式,weiboNER 数据中使用的是 BIO 标签。

    build_word_pretrain_emb() 也是 ../utils/data.py 中的方法,用于载入预训练的词向量,在本实践中即为了加载 gigaword_chn.all.a2b.uni.ite50.vec。加载该预训练词向量依据data_initialization() 生成的数据词典生成一个 np.empty() 的数据对象,并根据数据词典的词汇进行填充,没有对应词汇则随机生成词汇自动填充。

    generate_instance() 也是 ../utils/data.py 中的方法,用于生成词汇在词典中的 id 和词汇标签在标签集合中的 id ,便于输入到神经网络模型中进行训练。

    模型训练

    BiLSTM_CRF() 调用 ../model/bilstm_crf.pyBiLSTM_CRF 类的构造函数声明模型,并调用 train() 方法进行模型的训练。在训练过程中先使用 batchify_with_label() 方法将数据 tensor 化,然后将一个 batch 经过 tensor 化后的张量输入到模型中进行计算 neg_log_likelihood() 损失值等信息,并通过损失值的反传和模型参数进行模型优化。

    ​ 模型训练的关键就在于 neg_log_likelihood() 方法如下所示,其中使用 _get_lstm_features()方法利用 LSTM 模型获得上面实现原理介绍的第一类特征函数的特征;使用 CRF 类中的初始化函数中的 torch.zeros() 获得第二类特征函数的特征;最后使用 CRF 类中的 neg_log_likelihood_loss() 计算上面实现原理介绍的 LSTM + CRF 的总损失值;使用 CRF 类中的 _viterbi_decode() 用于模型的检验和测试。

    def neg_log_likelihood(self, batch_word, mask, batch_label, batch_wordlen):
        """
        :param batch_word: ([batch_size, max_sentence_length])
        :param mask: ([batch_size, max_sentence_length])
        :param batch_label: ([batch_size, max_sentence_length])
        :param batch_wordlen: ([batch_size])
        :return:
        loss : 类似 tensor(3052.6426, device='cuda:0', grad_fn=<SubBackward0>)
        tag_seq: ([batch_size, max_sentence_length])
        """
        lstm_feature = self._get_lstm_features(batch_word, batch_wordlen)
        total_loss = self.crf.neg_log_likelihood_loss(lstm_feature, mask, batch_label)
        scores, tag_seq = self.crf._viterbi_decode(lstm_feature, mask)
        return total_loss, tag_seq
    

    使用 CRF++ 训练命名实体识别模型

    CRF++0.58 工具包安装

    工具包下载

    • CRF++官方下载地址:https://taku910.github.io/crfpp/
    • window版本百度网盘链接:https://pan.baidu.com/s/1LBTUUJX8rHWeQqfZxJCJOw 提取码:9mzm
    • Linux版本百度网盘链接:https://pan.baidu.com/s/1LkBUidOcIlLEltcTpQbkwQ 提取码:11s2

    编译安装

    ​ 在解码目录依次执行下面几条命令

    sudo ./configure --prefix=/-yourfilepath-/crf # 安装到指定目录
    make
    make install
    

    使用 CRF++0.58 工具包训练命名实体识别模型

    ​ 进入到安装目录下 /-yourfilepath-/crf,进行模型训练,CRF源码地址

    数据集准备

    ​ 本命名实体识别模型使用 weiboNER 数据集包含一个训练集 weiboNER.trainweiboNER.test ,将这两个数据集移动到安装目录下 /-yourfilepath-/crf

    特征模板设计

    ​ CRF++中的特征设计如下图所示:

    在这里插入图片描述

    ​ 如果觉得自定义特征模板设计有一定难度,可以参考 CRF++0.58 工具包中的 example 示例中包含的 template 文件,同时也可以将 example 中的执行脚本 exec.sh 拷贝到执行目录下/-yourfilepath-/crf

    模型训练与测试

    ​ 模型训练可以在安装目录下 yourfilepath-/crf 用终端执行如下命令进行训练,也可以自行使用 ./bin/crf_leran 查看训练脚本的使用说明:

    ./bin/crf_learn -c 4.0 -m 50 template weiboNER.train model
    

    ​ 模型测试可以在安装目录下 yourfilepath-/crf 用终端执行如下命令进行训练,也可以自行使用 ./bin/crf_test --help 查看测试脚本的使用说明:

    ./bin.crf_test -m model weiboNER.test > result.test
    

    ​ 模型训练与测试完成之后,安装目录 yourfilepath-/crf 下应该有如下图所示的文件:

    在这里插入图片描述

    模型评估

    ​ 使用 P,R 和 F1值评估使用 CRF++0.58 工具包训练的命名实体识别模型性能,评估源码如下所示:

    import numpy as np
    import os
    import sys
    
    def buildConfusionMatrix(result_file):
        labels = []
        with open(result_file,'r',encoding="utf-8") as f:
            for i in f.readlines():
                labels.append(i.strip().split())
        f.close()
        true_labels = []
        predict_labels = []
        label2idx = dict()
        for i in labels:
            if 0 == len(i):
                continue
            true_labels.append(i[1])
            predict_labels.append(i[2])
            if i[1] not in label2idx:
                label2idx[i[1]] = len(label2idx)
        confMatrix = np.zeros([len(label2idx),len(label2idx)],dtype=np.int32)
        for i in range(len(true_labels)):
            true_labels_idx = label2idx[true_labels[i]]
            predict_labels_idx = label2idx[predict_labels[i]]
            confMatrix[true_labels_idx][predict_labels_idx] += 1
        return confMatrix, label2idx
    
    def calculate_all_prediction(confMatrix):
        '''
        计算总精度:对角线上所有值除以总数
        '''
        total_sum = confMatrix.sum()
        correct_sum = (np.diag(confMatrix)).sum()
        prediction = round(100*float(correct_sum)/float(total_sum),2)
        return prediction
    
    def calculate_label_prediction(confMatrix,labelidx):
        '''
        计算某一个类标预测精度:该类被预测正确的数除以该类的总数
        '''
        label_total_sum = confMatrix.sum(axis=0)[labelidx]
        label_correct_sum = confMatrix[labelidx][labelidx]
        prediction = 0
        if label_total_sum != 0:
            prediction = round(100*float(label_correct_sum)/float(label_total_sum),2)
        return prediction
    
    def calculate_label_recall(confMatrix,labelidx):
        '''
        计算某一个类标的召回率:
        '''
        label_total_sum = confMatrix.sum(axis=1)[labelidx]
        label_correct_sum = confMatrix[labelidx][labelidx]
        recall = 0
        if label_total_sum != 0:
            recall = round(100*float(label_correct_sum)/float(label_total_sum),2)
        return recall
    
    def calculate_f1(prediction,recall):
        if (prediction+recall)==0:
            return 0
        return round(2*prediction*recall/(prediction+recall),2)
    
    def main():
        #读取文件并转化为混淆矩阵,并返回label2idx
        result_file = sys.argv[1]
        confMatrix,label2idx = buildConfusionMatrix(result_file)
        total_sum = confMatrix.sum()
        all_prediction = calculate_all_prediction(confMatrix)
        label_prediction = []
        label_recall = []
        print('total_sum=',total_sum,',label_num=',len(label2idx))
        for i in label2idx:
            label_prediction.append(calculate_label_prediction(confMatrix,label2idx[i]))
            label_recall.append(calculate_label_recall(confMatrix,label2idx[i]))
            for j in label2idx:
                labelidx_i = label2idx[i]
                label2idx_j = label2idx[j]
        print('prediction(accuracy)=',all_prediction,'%')
        p = round(np.array(label_prediction).sum()/len(label_prediction),2)
        r = round(np.array(label_recall).sum()/len(label_prediction),2)
        print('Evaluation:\nprediction=',p,'%,recall=',r,'%,f1=',calculate_f1(p,r))
    
    
    if __name__ == "__main__":
        main()
    

    ​ 评估结果如下图所示:

    在这里插入图片描述

    展开全文
  • 本文针对航天领域命名实体识别这一特定问题,通过人工构建训练数据集、特征设计和CRF模型训练,建立了一种航天命名实体识别的高效方法。通过与基于字符串匹配的方法相比较,本文所提方法有着更高的准确率和召回率,...
  • 命名实体标注 对于给定的长度为 m 的序列 X,假设标注的结果为 [ y1, … , ym ] ,yi=PER/LOC/ORG/O,则命名实体标注问题可以表示在已知序列 X 的条件下,找出使得 [ y1, … , ym ] 的概率 P ( y1, … , ym ) 最大...
  • 这份代码是基于深度神经网络的英文命名实体识别,主要算法是LSTM+CRF
  • 方法1:基于CRF++实现NER CRF++是著名的条件随机场的开源工具,也是目前综合性能最佳的CRF工具,采用C++语言编写而成。其最重要的功能我认为是采用了特征模板。这样就可以自动生成一系列的特征函数,而不用我们自己...
  • 文章目录命名实体识别BiLSTM-CRF代码实现 -- 潘登同学的NLP笔记条件随机场概述直观的例子CRF的特征函数们举些例子对比逻辑回归对比HMMBilstm-CRF命名实体识别代码实现数据预处理训练模型模型应用(维特比算法) ...
  • 机器学习AI算法工程 公众号:datayx在命名实体识别领域,基于神经网络的实现方法是非常流行和常用的。举个例子,该文讲述的用词嵌入和字嵌入的BiLSTM-CRF模型就是其中一种。我将以该模型为例解释CRF层的工作原理。...
  • 当然也有学者认为这个问题还没有得到很好地解决,原因主要有:命名实体识别只是在有限的文本类型(主要是新闻语料中)和实体类别(主要是人名、地名、组织机构名)中取得了不错的效果;与其他信息检索领域相比,实体...
  • 最近在看命名实体识别相关的模型,实验室正好有中医典籍文本的命名实体标注数据集,拿来练练构建一个简单的CRF模型,顺便记录下来,代码可以作为一个参考,手中有标注数据集就可以使用这段代码来训练自己的CRF模型。...
  • 运行Github上简单的一个命名实体识别BiLSTM+CRF模型 一,版本问题 TensorFlow版本为1.4.0 Python版本为2.7 二,运行环境 Linux操作系统 在Win10下会报错 三,运行步骤 首先运行data里的py文件,获取pkl文件,供模型...
  • 欢迎大家来到我们的项目实战课,本期内容是《基于BiLSTM+CRF命名实体识别实战》。所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战讲解。本次主题命名实体识别...
  • 在实验中实现中文分词处理,可考虑使用课堂讲解过的算法(比如基于统计、基于词典的分词方法等),或者课外学习算法(比如Bi-LSTM+CRF模型等)进行分词,最后对比不同算法分词效果和性能,加深对中文分词算法的理解...
  • 条件随机场经常被用于序列标注,其中包括词性标注,分词,命名实体识别\color{red}词性标注,分词,命名实体识别词性标注,分词,命名实体识别等领域。(yes我会标红了) 1 NER任务介绍 更多介绍看这里 对以下NER任务...
  • 今天我们来学习 NER——Named entity recognition,命名实体识别,即识别出文档中具有特定意义的实体,例如人名、地名、机构名、专有名词等。 命名实体识别主要用来提取结构化信息,是信息提取、问答系统、句法分析...
  • 一文读懂BiLSTM+CRF实现命名实体识别
  • CRF++命名实体识别

    千次阅读 2016-09-23 11:24:43
    使用CRF++的windows版本 doc文件:就是官方主页的内容。 example文件夹:有四个任务的训练数据、测试数据和模板文件。 sdk文件夹:CRF++的头文件和静态链接库。 crf_learn.exe:CRF++的训练程序 crf_test.exe:...
  • 第四章 实体识别CRF及LSTM+CRF
  • 命名实体识别主要方法

    千次阅读 2022-03-26 16:52:31
    命名实体识别主要方法 命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是自然语言处理中的一项基础任务,应用范围非常广泛。命名实体一般指的是文本中具有特定意义或者指代性强的实体,...
  • 条件随机场(Conditional Random Fields,简称 CRF)是给定一组输入序列条件下另一组输出序列的条件概率分布模型,在自然语言处理中得到了广泛应用。其准确的数学语言描述为:设 X 与 Y 是随机变量,P(Y|X) 是给定 X...
  • BiLSTM+CRF(二)命名实体识别

    千次阅读 2018-12-03 21:15:11
    前言 前一篇博客里面,我们已经提到了如何构建一个双向的LSTM网络,并在原来单层的RNN的基础上,修改少数几行代码即可实现。...这篇博客,我们就来看看如何通过BiLSTM+CRF来进行命名实体识别的任务...
  • 基于BiLSTM+CRF命名实体识别

    千次阅读 2020-04-25 16:26:00
    一、命名实体识别问题的建模 命名实体识别是自然语言处理中的一项很基础的任务,是指从文本中识别出特定命名指向的词,比如人名、地名和组织机构名等。目前最常用,最成功的建模方法是将这一问题建模成序列标注问题...
  • 为提高医院对复杂数据的处理效率,减轻工作人员的压力,本文提出了一种基于条件随机场(CRF)模型和特征模板结合的算法,来识别中文电子病历中的命名实体单元,识别准确率可以达到92.9%,可以有效地识别电子病历命名...
  • 前面我们用隐马尔可夫模型(HMM)自己尝试训练过一个分词器,其实 HMM 也可以用来训练命名实体识别器,但在本文,我们讲另外一个算法——条件随机场(CRF),来训练一个命名实体识别器。 浅析条件随机场(CRF) 条件...
  • 实验-2 基于BiLSTM-CRF命名实体识别 4 2.1 实验目的 4 2.2 预备知识 4 2.3 实验任务 6 实验报告提交 7 实验-1 中文分词 1.1 实验目的 通过实验了解中文分词的大致思路。在实验中实现中文分词处理,可考虑使用课堂...
  • 什么是命名实体识别二.基于NLTK的命名实体识别三.基于Stanford的NER四.【实战案例】医学糖尿病数据命名实体识别,【Python数据挖掘解决方案】医学糖尿病数据命名实体识别​wx7dcc75bb5e655e9b.h5.xiaoe-tech.com一...
  • 命名实体识别(NER)算法

    千次阅读 2021-11-03 19:01:35
    参考 最通俗易懂的BILSTM-CRFCRF层介绍 简明条件随机场CRF介绍 | 附带纯Keras实现 keras实现源码 BERT标注为何不使用CRF

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,185
精华内容 1,274
关键字:

命名实体识别算法crf