1.NLPå½åä½è¯å«bilstm+crf
2.基于深度学习的命名实体识别详解(附Github代码)
3.NLP.TM[19] | 条件随机场知识整理(超长文)
NLPå½åä½è¯å«bilstm+crf
"""NLPå½åä½è¯å«bilstm+crf
1ãåå¤æ°æ®ï¼origin_handle_entities()
读åæºæ°æ®æ件ï¼æ人åï¼å°åï¼æºæåå并起æ¥
2ã读åå¤çåçæ°æ®ï¼origin_handle_mark()
æé¢å¤çåççææ¬æ 注æBMOçæ ¼å¼ï¼
B(begin)ãM(middle)ãE(end)ãO(other)
3ãå¥åååï¼sentence_split()
æç §æå®çæ ¼å¼ï¼æ¯å¦æ ç¹çå 容对æ°æ®å®æåå
4ãä¿åæ°æ®
a.å°æ 注çå¥åæåèªæå表å对åºçæ 注åºå
b.å建è¯æ±è¡¨åæ ç¾
c.ææ¬çåéå表示
d.ååè®ç»éåæµè¯é
e.ä¿åæäºè¿å¶pklæ件
5ãå è½½æ°æ®
6ãè®ç»æ¨¡åBiLSTM&HMM
7ãä¿åè®ç»åç模åç¨äºé¢æµ
8ãé¢æµ
"""
import codecs
import re
import collections
import pickle
import TorchCRF as CRF
import numpy as np
from tensorflow.keras.preprocessing.sequence import pad_sequences #使ç¨tensorflowçpad_sequencesè¿è¡æ°æ®å¯¹é½ tensorflow2.3.1
from sklearn.model_selection import train_test_split
def origin_handle_entities():
with open('renmin.txt','r',encoding='utf-8') as inp,
open('middle/renmin2.txt','w',encoding='utf-8')
as outp:
#读åæºæ件ä¸çæ°æ®
for line in inp.readlines():
#æç §ç©ºæ ¼åå
line = line.split(' ')
i = 1
while i < len(line) - 1:
if line[i][0] == '[':
outp.write(line[i].split('/')[0][1:])
i += 1
while i < len(line) - 1 and line[i].find(']') == -1:
if line[i] !='':
#print(line[i].split('/')[0])
outp.write(line[i].split('/')[0])
i += 1
outp.write(line[i].split('/')[0].strip()+'/'+line[i])
elif line[i].split('/')[1] == 'nr':
word = line[i].split('/')[0]
i += 1
if i < len(line) - 1 and line[i].split('/')[1] == 'nr':
outp.write(word + line[i].split('/')[0] + 'nr')
else:
outp.write(word + '/nr ')
continue
else:
outp.write(line[i] + '/no ')
i += 1
outp.write('\n')
import codecs
def origin_handle_mark():
"""
1ã读åæ°æ®é¢å¤çåçrenmin2.txt
2ãå°æ 注好çæ°æ®åå ¥renmin3.txt
a.æå¼è¾å ¥åè¾åºæ件
b.éåè¾å ¥æ件renmin2.txt
:return:
"""
with codecs.open('middle/renmin2.txt','r',encoding='utf-8') as inp,
codecs.open('middle/renmin3.txt','w',encoding='utf-8') as outp:
#########å¥ååå###################################
import re
def sentence_split():
with codecs.open('middel/renmin3.txt','r',encoding='utf-8') as inp,
codecs.open('middle/renmin4.txt','w',encoding='utf-8') as outp:
#ææ¬æ件çå 容设置为对åºçutf-8ç¼ç ï¼python3ï¼å encodeï¼ådecode
texts = inp.read().encode('utf-8').decode('utf-8')
#ååå¥å
sentences =
re.split('[ï¼ãï¼ï¼ã''""ï¼]/[0]'.encode('utf-8').decode('utf-8'),
texts)
for sentence in sentences:
if sentence != ' ':
outp.write(sentence.strip() + '\n')
def data_to_pkl():
"""
å°ææ¬æ°æ®ä¿åæäºè¿å¶pklæ件
:return:
"""
def main():
# æ°æ®æ¸ æ´
origin_handle_entities()
#æ°æ®æ 注ï¼åï¼
origin_handle_mark()
# å¥ååå
sentence_split()
# æ°æ®è½¬æ¢
data_to_pkl()
if name== 'main':
main()
##################################################################################################
def load_data():
pickle_path = '../data_target_pkl/renmindata.pkl'
with open(pickle_path,'rb') as inp:
word2id,id2word,tag2id,id2tag,x_train,y_train,x_test,y_test,x_valid,y_valid =pickle.load(inp)
def main():
word2id = load_data()
print(len(word2id))
if name== 'main':
main()
#######################################################################################
import torch
import torch.nn as nn
from torch.utils.data import Dataset # æ¹é读åæ°æ®
class NERDataSet(Dataset):
"""
X:è¡¨ç¤ºæ ·æ¬ï¼Y:表示æ ç¾
"""
def init(self,X,Y, args, *kwargs):
"""
class Config():
embedding_dim = #è¯åéç维度
hidden_dim =
config = Config()
class NERLSTM_CRF(nn.Module):
"""
1ãè¾å ¥å±
2ãè¯æ å°ï¼Embeddingï¼vocab_sizeï¼embedding_dimï¼ï¼
3ãLSTM
4ãå ¨è¿æ¥å±
"""
def init(self):
super(NERLSTM_CRF,self).init()
self.embeding_dim = config.embeding_dim
self.hidden_dim = config.hidden_dim
self.vocab_size = config.vocab_size
self.num_tags = config.num_tags
##################################################
from torch.utils.data import DataLoader #æ¹éå è½½æ°æ®
import torch
import torch.optim as op
def utils_to_train():
device = torch.device('cpu')
max_epoch = 1
batch_size =
num_workers =4 #å¼å¯å 个线ç¨åæ§è¡ç¨åº
def parse_tags(text,path):
id2tag = load_data()
tags = [id2tag[idx] for idx in path]
##################################################
from sklearn.metrics import classification_report,precision_score,recall_score,f1_score
word2id = load_data()[0]
max_epoch,device,train_data_loader,valid_data_loader,test_data_loader,model = utils_to_train()
class ChineseNER(object):
def train(self):
for epoch in range(max_epoch):
基于深度学习的命名实体识别详解(附Github代码)
命名实体识别(NER)作为自然语言处理的基石,广泛应用于人名、地名识别,电商产品命名以及药物名称解析等领域。传统的NER解决方案常采用条件随机场(CRF)模型,它是中医知识网站源码一种用于标注或分析序列数据的判别式概率模型。在NER中,CRF通过一系列特征预测每个词语的标签,这些标签对应着特定场景的实体类型。然而,特征工程成为关键挑战,需要根据场景人工提取特征,如基于词性或特定规则。aspx源码加密深度学习的引入简化了这一过程,通过自动学习特征,显著提高了NER的性能。以下将深入探讨基于深度学习的NER实现。
在深度学习框架中,如TensorFlow,利用双向循环神经网络(Bi-RNN)与条件随机场(CRF)进行NER任务的解决,展示了其优越性。Bi-RNN能够捕获序列中的前后文信息,而CRF则用于预测序列标签,两者结合能够高效地识别命名实体。深度学习的空包源码系统自动化特征学习特性,使得开发者无需人工提取特征,简化了模型构建过程。
面对深度学习模型对输入数据类型的要求,通常采用预训练词向量(如gensim word2vec、glove等)将文本转换为数值表示。对于训练数据不足的问题,通过从大型新闻集等资源中获取数据进行预训练词向量,可以有效提升模型泛化能力。对于未见过的词,预训练词向量能够通过词的上下文信息提供一定支持,减少未知词对模型性能的影响。
整个流程包括数据预处理、eclipse源码学习特征向量化、模型训练和评估。实现细节可通过访问github.com/shiyybua/NER获取,该仓库提供有中文注释的代码,实现简单且易于上手。理解深度学习在NER任务中的应用,掌握从数据预处理到模型部署的全过程,将有助于提高命名实体识别的准确性和效率。
NLP.TM[] | 条件随机场知识整理(超长文)
在近期的项目中,我利用条件随机场(CRF)解决了一个任务,取得了不错的效果,因此决定整理一下我对CRF的dll辅助源码理解和实践经验。本文将从理论出发,介绍CRF的基本概念、理论框架,以及如何在实际问题中应用CRF。
### 理论框架
条件随机场(CRF)是一种基于概率的序列标注模型,它从概率无向图出发,通过引入条件随机场的概念,定义了在已知特定位置的标签和其相邻标签的条件下,不同标签出现的概率。CRF尤其适用于序列标注问题,如命名实体识别、句子分词等。
#### 条件随机场定义
CRF定义的核心是对于给定位置的标签Y,其在已知特征和相邻标签条件下出现的概率,与已知特征但相邻标签不同条件下出现的概率是相同的。这种定义在链式条件随机场中表现得更为清晰。理解这一定义是基础,但还不够,为了进行预测,我们还需要知道P(y|x)的直接关系,这里需要引入图论中的“团”概念来分解问题。
#### 条件随机场形式
CRF的参数化形式通过Hammersley-Clifford定理给出,其中的势函数一般采用指数函数形式。通过数学期望的概念,我们可以推导出线性链条件随机场的参数化形式。参数化形式由特征函数和权重组成,权重被抽象为待估参数,最终得到的公式为:
矩阵形式的CRF参数化表达式为:
这里的公式展示了CRF如何通过特征函数和权重矩阵来描述概率分布,为后续的模型训练和预测提供了数学基础。
### 条件随机场作为判别模型
虽然CRF在形式上与生成模型相似,但实际上它是一个判别模型。判别模型与生成模型的区别在于训练过程和目标不同。CRF通过最小化损失函数来学习参数,而不需要联合概率分布,这使其成为判别模型。
判别模型的核心在于直接学习输入特征到输出标签的映射关系,通过优化损失函数实现参数学习。CRF通过损失函数的最小化,学习到特征与标签之间的关系,从而直接进行预测。
### 实际应用
CRF在实际应用中,有多种实现方式,如TensorFlow和CRF++。TensorFlow提供了CRF接口,通过`tf.contrib.crf.crf_log_likelihood`接口计算对数似然值,使用维特比算法进行预测。而CRF++则是一个基于C++的序列标注工具,支持多种编程语言接口,通过构建规则模板来定义CRF结构。
#### TensorFlow实现
在TensorFlow中实现CRF主要通过`crf_log_likelihood`接口计算对数似然值,以及使用维特比算法进行预测。关键在于正确设置输入向量和状态转移矩阵。
#### CRF++实现
CRF++提供了序列标注功能,通过构建规则模板来定义CRF结构。使用规则模板可以轻松地设置CRF参数,进行训练和测试。CRF++通过命令行工具`crf_learn`和`crf_test`进行模型训练和预测。
### 总结
通过理论学习和实际应用,我们掌握了条件随机场的核心概念和使用方法。无论是TensorFlow还是CRF++,它们都提供了实现序列标注任务的强大工具。理解CRF的工作原理,不仅能够解决具体问题,还能够为后续的自然语言处理任务提供坚实的基础。