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)模型,它是sma指标公式源码一种用于标注或分析序列数据的判别式概率模型。在NER中,CRF通过一系列特征预测每个词语的标签,这些标签对应着特定场景的实体类型。然而,特征工程成为关键挑战,需要根据场景人工提取特征,如基于词性或特定规则。c语言printf 源码深度学习的引入简化了这一过程,通过自动学习特征,显著提高了NER的性能。以下将深入探讨基于深度学习的NER实现。
在深度学习框架中,如TensorFlow,利用双向循环神经网络(Bi-RNN)与条件随机场(CRF)进行NER任务的解决,展示了其优越性。Bi-RNN能够捕获序列中的前后文信息,而CRF则用于预测序列标签,两者结合能够高效地识别命名实体。深度学习的好看的网站源码自动化特征学习特性,使得开发者无需人工提取特征,简化了模型构建过程。
面对深度学习模型对输入数据类型的要求,通常采用预训练词向量(如gensim word2vec、glove等)将文本转换为数值表示。对于训练数据不足的问题,通过从大型新闻集等资源中获取数据进行预训练词向量,可以有效提升模型泛化能力。对于未见过的词,预训练词向量能够通过词的上下文信息提供一定支持,减少未知词对模型性能的影响。
整个流程包括数据预处理、android原生应用 源码特征向量化、模型训练和评估。实现细节可通过访问github.com/shiyybua/NER获取,该仓库提供有中文注释的代码,实现简单且易于上手。理解深度学习在NER任务中的应用,掌握从数据预处理到模型部署的全过程,将有助于提高命名实体识别的准确性和效率。
NLP.TM[] | 条件随机场知识整理(超长文)
在近期的项目中,我利用条件随机场(CRF)解决了一个任务,取得了不错的效果,因此决定整理一下我对CRF的装饰公司php源码理解和实践经验。本文将从理论出发,介绍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的工作原理,不仅能够解决具体问题,还能够为后续的自然语言处理任务提供坚实的基础。
2024-12-24 08:27
2024-12-24 08:27
2024-12-24 08:16
2024-12-24 07:28
2024-12-24 07:27