精华内容
下载资源
问答
  • 命名实体识别代码
    2020-05-13 21:30:32

    基于规则的命名实体识别

    简单的分词器(如二元分词器)无法识别OOV,所以需要运用一些规定的规则来辅助识别
    如:在识别音译人名时,可以设置规则:一旦发现某词是人名,而该词后面跟随人名词时,将他们合并

    层叠马尔科夫模型实现命名实体识别

    针对不同情况,需要设计相应的标注集
    拿人名识别举例
    输入数据集进行训练后,代码会将人名拆分为碎片,模拟人名的错误切分.
    接着,检查拆分后的姓名与其前后组成的词是否在辞典中.若在,根据标注集将其标注为对应的标签(如“这里有关天培”这个句子,姓名“关天培”拆分后组成了“有关”这个词语,它在辞典中.此时将这个词语标注为“上文成词”)
    模型经过数据集的训练后进行测试时,会列出粗分的每个词语所有可能的标注,取可能性最大的标注,从而识别出人名

    当然,通过设计对应的标注集,可以实现组织机构和地名的识别

    序列标注实现命名实体识别

    层叠马尔科夫模型的序列是单单通过统计的方法得到,所以对OOV的识别能力很差
    而把前面学到的序列标注用到这上面,可以一定程度解决这个问题
    而感知机因为特征利用率比隐马高,效果比隐马更好,这里介绍感知机实现命名实体识别.
    相对于感知机分词,感知机命名实体识别的输入为 词语和词性,输出依旧为{B,M,E,S},本质依旧是序列标注

    Hanlp的实现

    python版本的命名实体识别代码:

        analyzer = PerceptronLexicalAnalyzer(PerceptronSegmenter(), PerceptronPOSTagger(), recognizer)  # ①
        sentence = Sentence.create("与/c 特朗普/nr 通/v 电话/n 讨论/v [太空/s 探索/vn 技术/n 公司/n]/nt")  # ②
        while not analyzer.analyze(sentence.text()).equals(sentence):  # ③
            analyzer.learn(sentence)
    

    第一行创建了感知机词法分析器,第二,三行训练了一个句子,重复在线学习直到分析结构与其一致为止

    更多相关内容
  • pytorch lstm+crf、bilstm+crf 、LSTM CRF 命名实体识别代码 代码和数据可以直接运行
  • 为提高医院对复杂数据的处理效率,减轻工作人员的压力,本文提出了一种基于条件随机场(CRF)模型和特征模板结合的算法,来识别中文电子病历中的命名实体单元,识别准确率可以达到92.9%,可以有效地识别电子病历命名...
  • spacy-lookup: 基于字典的命名实体识别
  • 代码是基于深度学习的命名实体识别的实现。命名实体识别是自然语言处理中尤为重要的一部分。
  • 本文是BERT实战的第二篇,使用BERT进行命名实体识别(序列标注类任务)。 1. 准备 1.1 环境 python 3.7; pytorch 1.3; transformers 2.3 (安装教程); 1.2 数据 数据链接(链接:...
  • 下载即可运行 1、data文件夹(数据) 2、bilstm_crf_model.py(模型) 3、process_data.py(数据预处理文件) 4、train.py(模型训练文件) 5、val.py(测试文件) 6、model.png(模型结构图)
  • 针对短文本命名实体识别这项紧缺任务,提出了一种面向短文本的快速有效的命名实体识别方法。该方法主要分成三步:第一步,针对短文本表达不规范特性对命名实体识别的干扰,采取去干扰字符,化繁为简等规范化操作。第二步,...
  • 人工智能-项目实践-实体识别-基于tensorflow深度学习的中文的命名实体识别 一个中文的实体命名识别系统 当前版本基于双向循环神经网络(BiRNN) + 条件随机场(CRF)来完成实体的标注。 基本思路是利用深度神经...
  • Medical Named Entity Recognition implement using bi-directional lstm and crf model with char embedding.CCKS2017中文电子病例
  • ner_crf ner_crf是Jupyter笔记本,它使用 / 实现,使用条件随机字段(CRF)描述了命名实体识别(NER)。依存关系ner_crf用编写,因此在使用python3之前应下载最新版本的python3 。 可以从找到python的下载(建议使用...
  • 医学领域命名实体识别代码 数据 可以直接运行 对 对文本中的 病例描述 病特征实现抽取
  • python命名实体识别demo

    2019-01-04 15:40:50
    python命名实体识别的demo以及训练字典,采用4-tag形式,准确率80以上
  • 这项工作的重点是它仅使用实体词典执行NER,而没有任何标签数据。 顺便说一下,我们最近出版了另一本与中文NER相关的作品。 它旨在通过词典增强中文NER。 这项工作的重点是它具有很高的计算效率,同时与现有方法相比...
  • 自定义命名实体识别在此存储库中,我将构建一个自定义NER,该NER将具有诸如工作时间(JT),组织(ORG),工作角色(JR),工作技能(JS),资格(QN),文档(DOC),编程语言等实体(PL),编程框架(PF)等。...
  • 这份代码是基于深度神经网络的英文命名实体识别,主要算法是LSTM+CRF
  • 人工智能-项目实践-命名实体识别-一个中文的实体命名识别系统 当前版本基于双向循环神经网络(BiRNN) + 条件随机场(CRF)来完成实体的标注。 基本思路是利用深度神经网络提取特征,从而避免了手动提取特征的麻烦...
  • 使用 CRF++ 训练命名实体识别模型
  • 基于BERT的中文数据集下的命名实体识别(NER) 基于tensorflow官方代码修改。 环境 Tensorflow:1.13 的Python:3.6 tensorflow2.0会报错。 搜狐比赛 在搜狐这个文本比赛中写了一个基准,使用了bert以及bert + ...
  • 文章目录命名实体识别BiLSTM-CRF代码实现 -- 潘登同学的NLP笔记条件随机场概述直观的例子CRF的特征函数们举些例子对比逻辑回归对比HMMBilstm-CRF命名实体识别代码实现数据预处理训练模型模型应用(维特比算法) ...

    命名实体识别BiLSTM-CRF代码实现 – 潘登同学的NLP笔记

    条件随机场概述

    条件随机场(Conditional Random Fields),是在给定一组输入随机变量条件下另外一组输出随机变量的条件概率分布模型,它是一种判别式的概率无向图模型,既然是判别式,拿就是对条件概率分布建模;

    之前也在BiLSTM-CRF中聊过,判别式模型就是给定x计算y,生成式模型就是计算联合分布的参数;

    设有线性链结构的随机变量序列 X = ( X 1 , X 2 , . . . , X n ) , Y = ( Y 1 , Y 2 , . . . , Y N ) X=(X_1,X_2,...,X_n),Y=(Y_1,Y_2,...,Y_N) X=(X1,X2,...,Xn),Y=(Y1,Y2,...,YN),在给定观察序列 X X X 的条件下,随机变量序列 Y Y Y 的条件概率分布为 P ( Y ∣ X ) P(Y|X) P(YX),若其满足马尔科夫特性,即
    P ( Y i ∣ X , Y 1 , Y 2... Y n ) = P ( Y i ∣ X , Y i − 1 , Y i + 1 ) P(Yi|X,Y1,Y2...Yn)=P(Yi|X,Yi−1,Yi+1) P(YiX,Y1,Y2...Yn)=P(YiX,Yi1,Yi+1)
    这时 P ( Y ∣ X ) P(Y|X) P(YX) 则为线性链条件随机场

    条件随机场(ConditionalRandom Field,CRF)是经典 NER 的主流模型。

    • 它的目标函数不仅考虑输入的状态特征函数,而且还包含了标签转移特征函数。
    • 在训练时可以使用 SGD 学习模型参数。
    • 在已知模型时,给输入序列求预测输出序列即求使目标函数最大化的最优序列,是一个动态规划问题,可以使用 Viterbi 算法解码来得到最优标签序列。
    • CRF 的优点在于其为一个位置进行标注的过程中可以利用丰富的内部及上下文特征信息。

    直观的例子

    假设你有许多小明同学一天内不同时段的照片,从小明提裤子起床到脱裤子睡觉各个时间段都有(小明是照片控!)。现在的任务是对这些照片进行分类。比如有的照片是吃饭,那就给它打上吃饭的标签;有的照片是跑步时拍的,那就打上跑步的标签;有的照片是开会时拍的,那就打上开会的标签。问题来了,你准备怎么干?

    一个简单直观的办法就是,不管这些照片之间的时间顺序,想办法训练出一个多元分类器。就是用一些打好标签的照片作为训练数据,训练出一个模型,直接根据照片的特征来分类。例如,如果照片是早上 6:00 拍的,且画面是黑暗的,那就给它打上睡觉的标签;如果照片上有车,那就给它打上开车的标签。这样可行吗?

    乍一看可以!但实际上,由于我们忽略了这些照片之间的时间顺序这一重要信息,我们的分类器会有缺陷的。举个例子,假如有一张小明闭着嘴的照片,怎么分类?显然难以直接判断,需要参考闭嘴之前的照片,如果之前的照片显示小明在吃饭,那这个闭嘴的照片很可能是小明在咀嚼食物准备下咽,可以给它打上吃饭的标签;如果之前的照片显示小明在唱歌,那这个闭嘴的照片很可能是小明唱歌瞬间的抓拍,可以给它打上唱歌的标签。所以,为了让我们的分类器能够有更好的表现,在为一张照片分类时,我们必须将与它相邻的照片的标签信息考虑进来。这——就是条件随机场(CRF)大显身手的地方!

    CRF的特征函数们

    我们正式地定义一下什么是 CRF 中的特征函数,所谓特征函数,就是这样的函数,它接受四个参数:

    • 句子 s s s(就是我们要标注词性的句子)
    • i i i,用来表示句子 s s s 中第 i i i 个单词
    • l i l_i li,表示要评分的标注序列给第 i i i 个单词标注的词性
    • l i − 1 l_i-1 li1,表示要评分的标注序列给第 i − 1 i-1 i1 个单词标注的词性
      它的输出值是 0 或者 1,0 表示要评分的标注序列不符合这个特征,1 表示要评分的标注序列符合这个特征

    注意: 这里,我们的特征函数仅仅依靠当前单词的标签和它前面的单词的标签对标注序列进行评判,这样建立的 CRF 也叫作线性链 CRF,这是 CRF 中的一种简单情况。为简单起见,本文中我们仅考虑线性链 CRF

    最终算法的预测值 y i ^ \hat{y_i} yi^受很多个特征函数的影响,写为数学表达式
    P ( y ∣ x ) = P R e a l P a t h T o t a l P a t h = e S i Z ( x ) = 1 Z ( x ) exp ⁡ ( ∑ i , k λ k ⋅ t k ( y i , y i − 1 , x , i ) + ∑ i , l μ k ⋅ e l ( y i , x , i ) ) \begin{aligned} P(y|x) &= \frac{P_{RealPath}}{TotalPath} = \frac{e^{S_i}}{Z(x)} \\ &= \frac{1}{Z(x)}\exp(\sum_{i,k} \lambda_k \cdot t_k (y_i,y_{i-1},x,i) + \sum_{i,l} \mu_k \cdot e_l (y_i,x,i)) \end{aligned} P(yx)=TotalPathPRealPath=Z(x)eSi=Z(x)1exp(ikλktk(yi,yi1,x,i)+ilμkel(yi,x,i))

    其中 x x x s s s表达意思一致, λ k \lambda_k λktransition scores矩阵的一个元素, t k t_k tk为特征函数,特征函数个数与 λ k \lambda_k λk都是 l a b e l 2 label^2 label2个; 既然前面是transition scores的一个表达,那么后面自然是Emission scores的表达, e l e_l el也理解为特征函数;exp中的是某一条路径中的表达式; Z ( x ) Z(x) Z(x)则是所有路径的加和…

    举些例子

    f 1 ( s , i , l i , l i − 1 ) = 1 f_1(s,i,l_i,l_{i-1}) = 1 f1(s,i,li,li1)=1
    l i l_i li 是“副词”并且第 i i i 个单词以“ly”结尾时,我们就让 f 1 = 1 f_1 = 1 f1=1,其他情况 f1 为 0。不难想到, f 1 f_1 f1 特征函数的权重 λ 1 \lambda_1 λ1 应当是正的。而且 λ 1 \lambda_1 λ1 越大,表示我们越倾向于采用那些把以“ly”结尾的单词标注为“副词”的标注序列;

    f 2 ( s , i , l i , l i − 1 ) = 1 f_2(s,i,l_i,l_{i-1}) = 1 f2(s,i,li,li1)=1
    如果 i = 1 i=1 i=1 l i = 动 词 l_i=动词 li=,并且句子 s s s 是以“?”结尾时, f 2 = 1 f_2=1 f2=1,其他情况 f 2 = 0 f_2=0 f2=0。同样, λ 2 \lambda_2 λ2 应当是正的,并且 λ 2 \lambda_2 λ2 越大,表示我们越倾向于采用那些把问句的第一个单词标注为“动词”的标注序列;

    f 3 ( s , i , l i , l i − 1 ) = 1 f_3(s,i,l_i,l_{i-1}) = 1 f3(s,i,li,li1)=1
    l i − 1 l_{i-1} li1 是介词, l i l_i li 是名词时, f 3 = 1 f_3 = 1 f3=1,其他情况 f 3 = 0 f_3=0 f3=0 λ 3 \lambda_3 λ3 也应当是正的,并且 λ 3 \lambda_3 λ3 越大,说明我们越认为介词后面应当跟一个名词;

    f 3 ( s , i , l i , l i − 1 ) = 1 f_3(s,i,l_i,l_{i-1}) = 1 f3(s,i,li,li1)=1
    如果 l i l_i li l i − 1 l_{i-1} li1 都是介词,那么 f 4 f_4 f4 等于 1,其他情况 f 4 = 0 f_4=0 f4=0。这里,我们应当可以想到 λ 4 \lambda_4 λ4 是负的,并且 λ 4 \lambda_4 λ4 的绝对值越大,表示我们越不认可介词后面还是介词的标注序列;

    对比逻辑回归

    CRF的概率形式与softmax很像,softmax又是逻辑回归的推广
    p ( l ∣ s ) = exp ⁡ [ ∑ j = 1 m ∑ i = 1 n f j ( l i , l i − 1 , s , i ) ] ∑ exp ⁡ [ ∑ j = 1 m ∑ i = 1 n f j ( l i , l i − 1 , s , i ) ] p(l|s) = \frac{\exp{[\sum_{j=1}^m \sum_{i=1}^n f_j (l_i,l_{i-1},s,i)}]}{\sum \exp{[\sum_{j=1}^m \sum_{i=1}^n f_j (l_i,l_{i-1},s,i)]}} p(ls)=exp[j=1mi=1nfj(li,li1,s,i)]exp[j=1mi=1nfj(li,li1,s,i)]
    那是因为 CRF 确实基本上是逻辑回归的序列版本,鉴于逻辑回归是一个对数线性模型用于分类,CRF 是一个对数线性模型用于序列打标签

    对比HMM

    HMM 采用生成式方法去打标签,数学表达为
    p ( l , s ) = p ( l 1 ) ∏ i p ( l i ∣ l i − 1 ) p ( w i ∣ l i ) p(l,s) = p(l_1)\prod_i p(l_i|l_{i-1})p(w_i|l_i) p(l,s)=p(l1)ip(lili1)p(wili)
    CRF 更强大,它可以做 HMM 可以完成的一切,并且还能做 HMM 不能做的, 我们将HMM的表达式往CRF上靠
    log ⁡ p ( l , s ) = log ⁡ p ( l 1 ) + ∑ i log ⁡ p ( l i ∣ l i − 1 ) + ∑ i log ⁡ p ( w i ∣ l i ) \log p(l,s) = \log p(l_1) + \sum_i\log p(l_i|l_{i-1}) + \sum_i\log p(w_i|l_i) logp(l,s)=logp(l1)+ilogp(lili1)+ilogp(wili)
    如果我们考虑这些对数概率为相对应的二元的转化和发射指标特征的权重。即,我们可以构建一个 CRF 等同于任意 HMM, 对于每个HMM的转移概率 log ⁡ p ( l i = y ∣ l i − 1 = x ) \log p(l_i=y|l_{i-1}=x) logp(li=yli1=x),可以理解为只有两个输入的特征函数,每个特征函数的权重为 w x , y = log ⁡ p ( l i = y ∣ l i − 1 = x ) w_{x,y} = \log p(l_i=y|l_{i-1}=x) wx,y=logp(li=yli1=x)每个特征函数的输出都是1;

    类似地,对于每个 HMM 的发射概率 log ⁡ p ( w i ∣ l i ) \log p(w_i|l_i) logp(wili),也可以视作特征函数,每个特征函数的权重为 w x , z = log ⁡ p ( w i = z ∣ l i = x ) w_{x,z} = \log p(w_i=z|l_{i}=x) wx,z=logp(wi=zli=x);

    因此,由 CRF 计算的分数 p(l|s)使用这些特征函数是精确地成比例的对应于 HMM 计算的分数,所以每一个 HMM 是等同于一些 CRF的特征函数;

    CRFs 可以建模更丰富的标签分布,这里有两个原因:

    1. CRFs 可以定义更大的特征集合。然后 HMMs 必然是局部在本质上(因为它们被限制到二元的转换和发射特征函数,强迫每个单词仅依赖于当前的标签和每个标签仅依赖于之前的标签),CRFs 可以使用更多全局的特征。例如,一个特征在我们的 POS 标签的概率增长,一个句子首个单词标注为动词如果句子最后包含一个问号符号。
    2. CRFs可以有任意的权重 。 鉴于 HMM 的概率必须满足某些限制, 例如 0 < = p ( w i ∣ l i ) < = 1 , ∑ w P ( w i = w ∣ l i ) = 1 0<=p(w_i|l_i)<=1,\sum_w P(w_i=w|l_i)=1 0<=p(wili)<=1,wP(wi=wli)=1,但CRF 的权重是不限制的;

    HMM模型存在两个严格假设:

    • 输出观察值之间严格独立(之前概率图中的head-to-tail)
    • 状态的转移过程中当前状态只与前一状态有关(一阶马尔科夫模型)

    除此之外,HMM还会出现标注偏置问题:

    • 假设有三个状态(标签)a,b,c
    • 在语料库训练中,a转移到b的概率,大于a转移到c的概率(统计出来的),所以很受语料库统计的影响,可能会造成HMM在测试的时候只出现a到b的状态

    Bilstm-CRF命名实体识别代码实现

    数据预处理

    在这里插入图片描述

    训练模型

    在这里插入图片描述

    模型应用(维特比算法)

    在这里插入图片描述

    展开全文
  • 完整代码获取:公众号后台回复(命名实体识别demo代码解读) 主要部分 Embedding input: 所有文字的字典文件,{index:word,…}; 所有文字的embedding文件,{word:embedding,…}; output: 将字典中的文字全部用...
  • 裁判文书中的命名实体识别是自动化审判的关键一步,如何能够有效的分辨出案件的关键命名实体是本文的研究重点.因此本文针对财产纠纷审判案件,提出了一种基于SVM-BiLSTM-CRF的神经网络模型.首先利用SVM筛选出包含...
  • 中英文分词工具有很多,今天我们来使用Jieba、SnowNlp、nltk、thunlp、NLPIR、Stanford等六种工具来对给定中英文文本进行分词、词性标注与命名实体识别
  • 课程目标: 学习完本门课程,您将对自然语言处理技术有更深入的了解,彻底掌握中文命名实体识别技术。 适用人群: 自然语言处理从业者、深度学习爱好者 课程简介: 命名实体识别作为自然语言处理的基础技术之一,在...
  • 命名实体识别是指在文本中定位命名实体的边界并分类到预定义类型的集合的过程。实体的标注形式有BIOE等,其中B是body的缩写,I是in的缩写,O是output的缩写,E是expect的缩写。 NER的输入是一个句子对应的单词序列s=...

    命名实体识别是指在文本中定位命名实体的边界并分类到预定义类型的集合的过程。实体的标注形式有BIOE等,其中B是body的缩写,I是in的缩写,O是output的缩写,E是expect的缩写。

    NER的输入是一个句子对应的单词序列 s = < w 1 , w 2 , . . . w n > s=<w_1,w_2,...w_n> s=<w1,w2,...wn>,输出是一个三元组集合,其中每个元组形式为 < I s , I e , i t > <I_s, I_e,i_t> <Is,Ie,it>,表示 s s s中的一个命名实体,其中 I s I_s Is T e T_e Te分别代表命名实体在 s s s中的开始和结束的位置,而 t t t是实体的类型。

    对于NER任务,比较经典的方法是BILSTM-CRF,关于LSTM可以参见长短时记忆网络,CRF是一种判别式模型,直接建模并求解使 P ( Y ∣ X ) P(Y|X) P(YX)最大的 Y Y Y,在CRF中,每个 y t y_t yt仅取决于 y t − 1 y_{t-1} yt1,还取决于整个的输入 X X X。相比较与HMM,其计算速度会慢,但能够获取全局的特征信息。

    BILSTM-CRF的基本模型结构:
    第一层:分布式表示层:
    分布式表示层有词向量、字向量和混合表示几种方法。词向量可以参看word embedding。字向量通常使用RN和CNN进行提取,字向量是词向量的重要补充,尤其在中文这一类表意文字上的应用往往能够取得好的效果;
    第二层:BILSTM层
    第三层:CRF层

    展开全文
  • 基于半监督学习与CRF的应急预案命名实体识别
  • 【NLP】BiLSTM 命名实体识别 手写代码

    千次阅读 2022-04-23 17:57:53
    【参考:pytorch_BiLSTM 命名实体识别 手写代码_哔哩哔哩_bilibili】 【参考:shouxieai/nlp-bilstm_crf-ner: nlp-bilstm+crf-ner】 """ 2022/4/22 """ import os import numpy as np import torch import torch.nn...

    【参考:pytorch_BiLSTM 命名实体识别 手写代码_哔哩哔哩_bilibili

    【参考:shouxieai/nlp-bilstm_crf-ner: nlp-bilstm+crf-ner

    数据样例

    高 B-NAME
    勇 E-NAME
    : O
    男 O
    , O
    中 B-CONT
    国 M-CONT
    国 M-CONT
    籍 E-CONT
    , O
    无 O
    境 O
    外 O
    居 O
    留 O
    权 O
    , O
    
    """
    2022/4/22
    """
    import os
    
    import numpy as np
    import torch
    import torch.nn as nn
    from torch.utils.data import DataLoader, Dataset
    import torch.optim as optim
    from tqdm import tqdm
    
    
    def build_corpus(data_type, make_vocab=True, data_dir="data"):
        word_lists, tag_lists = [], []
        with open(os.path.join(data_dir, data_type + '.char.bmes'), 'r', encoding='utf-8') as f:
            word_list, tag_list = [], []
            for line in f:
                if line != '\n':  # 数据中每句话会使用一个换行隔开
                    word, tag = line.strip().split(" ")
                    word_list.append(word)
                    tag_list.append(tag)
                else:
                    word_lists.append(word_list)  # 添加每句话
                    tag_lists.append(tag_list)
                    word_list, tag_list = [], []  # 清空
    
        word_lists = sorted(word_lists, key=lambda x: len(x), reverse=False)
        tag_lists = sorted(tag_lists, key=lambda x: len(x), reverse=False)
    
        # 如果make_vocab为True,还需要返回word2id和tag2id
        if make_vocab:
            word2id = build_map(word_lists)
            tag2id = build_map(tag_lists)
            word2id['<UNK>'] = len(word2id)
            word2id['<PAD>'] = len(word2id)
            tag2id['<PAD>'] = len(tag2id)
            return word_lists, tag_lists, word2id, tag2id
    
        return word_lists, tag_lists
    
    
    def build_map(lists):
        """
        :param lists: 二维矩阵
        :return: 字典map
        """
        maps = {}
        for list in lists:
            for e in list:
                if e not in maps:
                    maps[e] = len(maps)  # 编号自动递增
        return maps
    
    
    class MyDataset(Dataset):
        def __init__(self, datas, tags, word2idx, tag2idx):
            self.datas = datas
            self.tags = tags
            self.word2idx = word2idx
            self.tag2idx = tag2idx
    
        def __getitem__(self, index):
            data = self.datas[index]
            tag = self.tags[index]
            # 如果word2idx中没有该词就用UNK代替
            data_index = [self.word2idx.get(i, self.word2idx["<UNK>"]) for i in data]  # 获取每句话所有字的索引
            tag_index = [self.tag2idx[i] for i in tag]
    
            return data_index, tag_index
    
        def __len__(self):
            return len(self.datas)
    
        def pro_batch_data(self, batch_datas):
            # 因为每句话的长度不一样,拼接数据维度不一致会导致错误,所以自己手动拼接 未完全理解
            datas = []
            tags = []
            batch_lens = []
    
            for data, tag in batch_datas:
                datas.append(data)
                tags.append(tag)
                batch_lens.append(len(data))
            batch_max_len = max(batch_lens)
    
            # 填充至相同长度
            datas = [i + [self.word2idx['<PAD>']] * (batch_max_len - len(i)) for i in datas]  # i是,每句话
            tags = [i + [self.tag2idx['<PAD>']] * (batch_max_len - len(i)) for i in tags]
    
            # return torch.IntTensor(datas), torch.LongTensor(tags)
            return torch.tensor(datas, dtype=torch.int64), torch.tensor(tags, dtype=torch.long)
    
    
    class Mymodel(nn.Module):
        def __init__(self, corpus_num, embedding_dim, hidden_num, class_num, bi=True):
            super(Mymodel, self).__init__()
            self.embedding = nn.Embedding(corpus_num, embedding_dim)
            self.lstm = nn.LSTM(input_size=embedding_dim,
                                hidden_size=hidden_num,
                                batch_first=True,
                                bidirectional=bi)
            if bi:
                self.classifier = nn.Linear(hidden_num * 2, class_num)
            else:
                self.classifier = nn.Linear(hidden_num, class_num)
    
        def forward(self, batch_data):
            x = self.embedding(batch_data)
            out, _ = self.lstm(x)
            predict = self.classifier(out)
            return predict
    
    
    if __name__ == "__main__":
        # 训练集
        train_data, train_tag, word2id, tag2id = build_corpus('train')
        id2tag = [i for i in tag2id]
        # 验证集
        dev_data, dev_tag = build_corpus('dev', make_vocab=False)
        corpus_num = len(train_data)
        class_num = len(train_tag)
    
        epochs = 20
        train_batch_size = 30
        dev_batch_size = 30
        embedding_dim = 100
        hidden_num = 107
        bi = True
        lr = 0.001
    
        train_dataset = MyDataset(train_data, train_tag, word2id, tag2id)
    
        train_dataloader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=False
                                      , collate_fn=train_dataset.pro_batch_data)
    
        dev_dataset = MyDataset(dev_data, dev_tag, word2id, tag2id)
    
        dev_dataloader = DataLoader(dev_dataset, batch_size=dev_batch_size, shuffle=False
                                    , collate_fn=dev_dataset.pro_batch_data)
    
        model = Mymodel(corpus_num, embedding_dim, hidden_num, class_num, bi)
        criterion = nn.CrossEntropyLoss()
        optim = optim.Adam(model.parameters(), lr=lr)
    
        if os.path.exists('model.pth') is False:
    
            for i in range(epochs):
                model.train()
                train_loss = 0
                for train_data, train_tag in tqdm(train_dataloader):
                    optim.zero_grad()
                    predict = model.forward(train_data)
                    # predict (5,4,3821) train_tag(5,4)
                    predict = predict.reshape(-1, predict.shape[-1])  # (20,3821)
                    train_tag = train_tag.reshape(-1)  # (20)
                    loss = criterion(predict, train_tag)
                    loss.backward()
                    optim.step()
    
                    train_loss += loss.item() / predict.size(0)
    
                train_loss = train_loss / len(train_dataloader.dataset)  # 计算平均loss
                print('Epoch: {} \tTraining Loss: {:.6f}'.format(i, train_loss))
            # 保存模型参数 【参考:[pytorch保存模型的两种方式_SCU-JJkinging的博客-CSDN博客](https://blog.csdn.net/qq_41845478/article/details/116023691)】
            torch.save({'model': model.state_dict()}, 'model.pth')
        else:
            # 读取模型
            # model = Mymodel()
            state_dict = torch.load('model.pth')
            model.load_state_dict(state_dict['model'])
    
        eval=True
        if eval:
        # 验证
            model.eval()
            with torch.no_grad():
                dev_loss = 0
                real_label = []
                predict_label = []
                for dev_data, dev_tag in tqdm(dev_dataloader):
                    predict = model.forward(dev_data)
                    # predict (5,4,3821) dev_tag(5,4)
                    predict = predict.reshape(-1, predict.shape[-1])  # (20,3821)
                    predcit_class = torch.argmax(predict, dim=1)
                    predict_label.append(predcit_class.numpy())
    
                    dev_tag = dev_tag.reshape(-1)  # (20,)
                    real_label.append(dev_tag.numpy())
    
                    loss = criterion(predict, dev_tag)
                    dev_loss += loss.item() / predict.size(0)
    
    
                real_label = np.concatenate(real_label)
                predict_label = np.concatenate(predict_label)
    
                acc = np.sum(real_label == predict_label) / len(predict_label)
                dev_loss = dev_loss / len(dev_dataloader.dataset)  # 计算平均loss
                print(f'dev_loss:{dev_loss},acc:{acc}')
                # dev_loss:0.11368986861924547,acc:0.9583595772972217
    
        while True:
            text = input("请输入:")
            text_index = [[word2id.get(i,word2id["<PAD>"]) for i in text]]
            text_index = torch.tensor(text_index,dtype=torch.int64)
            predict=model.forward(text_index)
            predict = torch.argmax(predict, dim=-1).reshape(-1)
            pre = [id2tag[i] for i in predict]
    
            print([f'{w}_{s}' for w,s in zip(text,pre)])
    

    效果不太理想

    请输入:一是加快和海口市政府及有关部门沟通衔接,就桂林洋校区的围墙边界、规划区土地使用等问题达成一致意见。二是组织地理与环境科学学院、生命科学学院、体育学院等有关教学单位实地查看,有效利用未开发的区域,作为培养学生的实训和实验基地。三是按照校园总体规划,进一步加强桂林洋校区基础设施的建设和管理工作,同时打造和谐向上的校园文化。
    ['一_O', '是_O', '加_O', '快_O', '和_O', '海_O', '口_M-ORG', '市_M-ORG', '政_M-ORG', '府_E-ORG', '及_O', '有_O', '关_O', '部_O', '门_O', '沟_O', '通_O', '衔_M-TITLE', '接_O', ',_O', '就_O', '桂_O', '林_O', '洋_O', '校_O', '区_O', '的_O', '围_O', '墙_O', '边_O', '界_O', '、_O', '规_B-ORG', '划_M-ORG', '区_M-ORG', '土_M-ORG', '地_M-ORG', '使_O', '用_O', '等_O', '问_O', '题_O', '达_O', '成_O', '一_O', '致_O', '意_O', '见_O', '。_O', '二_O', '是_O', '组_O', '织_O', '地_O', '理_O', '与_O', '环_O', '境_O', '科_O', '学_O', '学_O', '院_O', '、_O', '生_O', '命_M-ORG', '科_M-ORG', '学_M-ORG', '学_M-ORG', '院_E-ORG', '、_O', '体_B-ORG', '育_M-ORG', '学_M-ORG', '院_E-ORG', '等_O', '有_O', '关_O', '教_O', '学_O', '单_O', '位_O', '实_M-EDU', '地_M-EDU', '查_O', '看_O', ',_O', '有_O', '效_O', '利_O', '用_O', '未_O', '开_O', '发_O', '的_O', '区_O', '域_O', ',_O', '作_O', '为_O', '培_O', '养_O', '学_O', '生_O', '的_O', '实_O', '训_O', '和_O', '实_O', '验_O', '基_O', '地_O', '。_O', '三_O', '是_O', '按_O', '照_O', '校_O', '园_O', '总_O', '体_O', '规_O', '划_O', ',_O', '进_O', '一_O', '步_O', '加_O', '强_O', '桂_O', '林_O', '洋_O', '校_O', '区_O', '基_O', '础_O', '设_O', '施_E-TITLE', '的_O', '建_O', '设_O', '和_O', '管_O', '理_O', '工_O', '作_O', ',_O', '同_O', '时_O', '打_O', '造_O', '和_O', '谐_O', '向_M-ORG', '上_M-ORG', '的_O', '校_O', '园_E-ORG', '文_O', '化_E-TITLE', '。_O']
    请输入:会议指出,桂林洋校区基础设施建设已经取得重要进展,学生公寓、第二公共教学楼等设施相继投入使用,进一步改善了学生的学习和生活条件。为进一步落实省委“能力提升年”的安排部署,切实加快基础设施建设,更好服务全校师生。
    ['会_O', '议_O', '指_O', '出_O', ',_O', '桂_O', '林_M-ORG', '洋_M-ORG', '校_M-ORG', '区_O', '基_M-ORG', '础_M-ORG', '设_M-ORG', '施_M-ORG', '建_M-ORG', '设_M-ORG', '已_M-ORG', '经_M-ORG', '取_O', '得_O', '重_O', '要_O', '进_O', '展_O', ',_O', '学_O', '生_O', '公_O', '寓_O', '、_O', '第_B-ORG', '二_O', '公_M-ORG', '共_O', '教_O', '学_O', '楼_O', '等_O', '设_O', '施_O', '相_O', '继_M-ORG', '投_E-ORG', '入_O', '使_O', '用_E-TITLE', ',_O', '进_O', '一_O', '步_O', '改_O', '善_O', '了_O', '学_O', '生_O', '的_O', '学_O', '习_O', '和_O', '生_O', '活_O', '条_O', '件_O', '。_O', '为_O', '进_O', '一_O', '步_O', '落_O', '实_O', '省_O', '委_O', '“_O', '能_O', '力_O', '提_O', '升_O', '年_O', '”_O', '的_O', '安_O', '排_O', '部_O', '署_O', ',_O', '切_O', '实_O', '加_O', '快_O', '基_M-ORG', '础_O', '设_O', '施_M-TITLE', '建_E-ORG', '设_E-ORG', ',_O', '更_O', '好_O', '服_O', '务_O', '全_M-TITLE', '校_M-TITLE', '师_O', '生_O', '。_O']
    请输入:校领导过建春、刁晓平、陈险峰、李森、韩尚峰、刘汝兵、黄忆军、王任斌调研桂林洋校区基建工作并召开现场办公会,相关职能部门负责人参加调研
    ['校_O', '领_O', '导_O', '过_O', '建_O', '春_O', '、_O', '刁_O', '晓_M-ORG', '平_M-ORG', '、_O', '陈_M-ORG', '险_M-ORG', '峰_M-ORG', '、_O', '李_M-ORG', '森_M-ORG', '、_O', '韩_O', '尚_M-ORG', '峰_M-ORG', '、_M-ORG', '刘_M-ORG', '汝_M-ORG', '兵_E-NAME', '、_O', '黄_M-ORG', '忆_M-ORG', '军_M-ORG', '、_M-ORG', '王_M-ORG', '任_M-ORG', '斌_M-ORG', '调_M-ORG', '研_M-ORG', '桂_M-ORG', '林_M-ORG', '洋_M-ORG', '校_M-ORG', '区_M-ORG', '基_M-ORG', '建_M-ORG', '工_M-ORG', '作_M-ORG', '并_M-ORG', '召_M-ORG', '开_M-ORG', '现_O', '场_M-TITLE', '办_M-TITLE', '公_M-TITLE', '会_E-TITLE', ',_O', '相_O', '关_O', '职_O', '能_M-TITLE', '部_M-TITLE', '门_M-TITLE', '负_M-TITLE', '责_M-TITLE', '人_E-TITLE', '参_O', '加_O', '调_M-TITLE', '研_M-TITLE']
    
    
    展开全文
  • 对应这篇文章的数据集,小伙伴们自行取走: https://sito8.blog.csdn.net/article/details/123233758?spm=1001.2014.3001.5502
  • BERT-NER版本2使用Google的BERT进行命名实体识别(CoNLL-2003作为数据集)。 原始版本(请参阅old_version以获得更多详细信息)包含一些硬代码,并且缺少相应的注释,因此不方便理解。 因此,在此更新版本中,有一些...
  • 斯坦福NLP的信息提取,包括命名实体识别和关系提取等。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,003
精华内容 16,401
关键字:

命名实体识别代码