丰都网站建设哪家好,网站建设费用低设计好,网站开发和前端和数据媒体,wordpress中文名自然语言处理#xff08;Natural Language Processing#xff0c;简称NLP#xff09;是计算机科学与语言学中关注于计算机与人类语言间转换的领域。其主要应用于#xff1a;语音助手、机器翻译、搜索引擎、智能问答等。
文本预处理概述
文本语料在输送给模型前一般需要一…自然语言处理Natural Language Processing简称NLP是计算机科学与语言学中关注于计算机与人类语言间转换的领域。其主要应用于语音助手、机器翻译、搜索引擎、智能问答等。
文本预处理概述
文本语料在输送给模型前一般需要一系列的预处理工作才能符合模型输入的要求如将文本转化成模型需要的张量规范张量的尺寸等而且科学的文本预处理环节还将有效指导模型超参数的选择提升模型的评估指标。
文本处理的基本方法
分词概述 分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中单词之间是以空格作为自然分界符的而中文只是字、句和段能通过明显的分界符来简单划界唯独词没有一个形式上的分界符分词过程就是找到这样分界符的过程。分词的作用词作为语言语义理解的最小单元是人类理解文本语言的基础。因此也是AI解决NLP领域高阶任务如自动问答机器翻译文本生成的重要基础环节。流行中文分词工具jieba的特性 支持多种分词模式精确模式、全模式、搜索引擎模式支持中文繁体分词支持用户自定义词典 命名实体识别
命名实体通常将人名地名机构名等专有名词统称命名实体。命名实体识别(Named Entity Recognition简称NER)就是识别出一段文本中可能存在的命名实体。命名实体识别的作用同词汇一样命名实体也是人类理解文本的基础单元因此也是AI解决NLP领域高阶任务的重要基础环节。
词性标注
词性: 语言中对词的一种分类方法以语法特征为主要依据、兼顾词汇意义对词进行划分的结果常见的词性有14种, 如: 名词, 动词, 形容词等。词性标注(Part-Of-Speech tagging, 简称POS)就是标注出一段文本中每个词汇的词性。词性标注的作用词性标注以分词为基础,是对文本语言的另一个角度的理解因此也常常成为AI解决NLP领域高阶任务的重要基础环节。
文本张量表示方法
文本张量表示将一段文本使用张量进行表示其中一般将词汇为表示成向量称作词向量再由各个词向量按顺序组成矩阵形成文本表示。文本张量表示的作用将文本表示成张量矩阵形式能够使语言文本可以作为计算机处理程序的输入进行接下来一系列的解析工作。文本张量表示的方法one-hot编码、Word2vec、Word Embedding
one-hot编码 one-hot词向量表示又称独热编码将每个词表示成具有n个元素的向量这个词向量中只有一个元素是1其他元素都是0不同词汇元素为0的位置不同其中n的大小是整个语料中不同词汇的总数。one-hot编码的优劣势 优势操作简单容易理解劣势完全割裂了词与词之间的联系而且在大语料集下每个向量的长度过大占据大量内存 Word2vec word2vec是一种流行的将词汇表示成向量的无监督训练方法该过程将构建神经网络模型将网络参数作为词汇的向量表示它包含CBOW和skipgram两种训练模式。CBOW(Continuous bag of words)模式给定一段用于训练的文本语料再选定某段长度(窗口)作为研究对象使用上下文词汇预测目标词汇。CBOW模式下的word2vec过程说明 假设给定的训练语料只有一句话: Hope can set you free (愿你自由成长)窗口大小为3因此模型的第一个训练样本来自Hope you set因为是CBOW模式所以将使用Hope和set作为输入you作为输出在模型训练时 Hopesetyou等词汇都使用它们的one-hot编码。如图所示每个one-hot编码的单词与各自的变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘之后再相加, 得到上下文表示矩阵(3x1)。接着, 将上下文表示矩阵与变换矩阵(参数矩阵5x3, 所有的变换矩阵共享参数)相乘, 得到5x1的结果矩阵, 它将与真正的目标矩阵即you的one-hot编码矩阵(5x1)进行损失的计算然后更新网络参数完成一次模型迭代。最后窗口按序向后移动重新更新参数直到所有语料被遍历完成得到最终的变换矩阵(3x5)这个变换矩阵与每个词汇的one-hot编码(5x1)相乘得到的3x1的矩阵就是该词汇的word2vec张量表示。 skipgram模式给定一段用于训练的文本语料再选定某段长度(窗口)作为研究对象使用目标词汇预测上下文词汇。skipgram模式下的word2vec过程说明 假设给定的训练语料只有一句话: Hope can set you free (愿你自由成长)窗口大小为3因此模型的第一个训练样本来自Hope you set因为是skipgram模式所以将使用you作为输入 hope和set作为输出在模型训练时 Hopesetyou等词汇都使用它们的one-hot编码。如图所示将you的one-hot编码与变换矩阵(即参数矩阵3x5这里的3是指最后得到的词向量维度)相乘, 得到目标词汇表示矩阵(3x1)。接着, 将目标词汇表示矩阵与多个变换矩阵(参数矩阵5x3)相乘, 得到多个5x1的结果矩阵, 它将与我们hope和set对应的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模 型迭代。最后窗口按序向后移动重新更新参数直到所有语料被遍历完成得到最终的变换矩阵即参数矩阵(3x5)这个变换矩阵与每个词汇的one-hot编码(5x1)相乘得到的3x1的矩阵就是该词汇的word2vec张量表示。 使用fasttext工具实现word2vec的训练和使用 第一步: 获取训练数据第二步: 训练词向量第三步: 模型超参数设定第四步: 模型效果检验第五步: 模型的保存与重加载
word embedding(词嵌入)
word embedding(词嵌入) 通过一定的方式将词汇映射到指定维度(一般是更高维度)的空间。广义的word embedding包括所有密集词汇向量的表示方法如之前学习的word2vec即可认为是word embedding的一种。狭义的word embedding是指在神经网络中加入的embedding层对整个网络进行训练的同时产生的embedding矩阵(embedding层的参数)这个embedding矩阵就是训练过程中所有输入词汇的向量表示组成的矩阵。word embedding的可视化分析 通过使用tensorboard可视化嵌入的词向量。在终端启动tensorboard服务。浏览器展示并可以使用右侧近邻词汇功能检验效果。
文本数据分析
分析作用与方法
文本数据分析的作用 文本数据分析能够有效帮助理解数据语料快速检查出语料可能存在的问题并指导之后模型训练过程中一些超参数的选择。常用的几种文本数据分析方法 标签数量分布句子长度分布词频统计与关键词词云
文本特征处理
文本特征处理的作用 文本特征处理包括为语料添加具有普适性的文本特征如n-gram特征以及对加入特征之后的文本语料进行必要的处理如长度规范。这些特征处理工作能够有效的将重要的文本特征加入模型训练中增强模型评估指标。常见的文本特征处理方法 添加n-gram特征文本长度规范
n-gram特征
n-gram特征给定一段文本序列其中n个词或字的相邻共现特征即n-gram特征常用的n-gram特征是bi-gram和tri-gram特征分别对应n为2和3。提取n-gram特征的函数create_ngram_set # 一般n-gram中的n取2或者3, 这里取2为例
ngram_range 2def create_ngram_set(input_list):description: 从数值列表中提取所有的n-gram特征:param input_list: 输入的数值列表, 可以看作是词汇映射后的列表, 里面每个数字的取值范围为[1, 25000]:return: n-gram特征组成的集合eg: create_ngram_set([1, 4, 9, 4, 1, 4]){(4, 9), (4, 1), (1, 4), (9, 4)}return set(zip(*[input_list[i:] for i in range(ngram_range)]))
文本长度规范
文本长度规范及其作用一般模型的输入需要等尺寸大小的矩阵因此在进入模型前需要对每条文本数值映射后的长度进行规范此时将根据句子长度分布分析出覆盖绝大多数文本的合理长度对超长文本进行截断对不足文本进行补齐(一般使用数字0)这个过程就是文本长度规范。文本长度规范的实现函数padding from keras.preprocessing import sequence# cutlen根据数据分析中句子长度分布覆盖90%左右语料的最短长度.
# 这里假定cutlen为10
cutlen 10def padding(x_train):description: 对输入文本张量进行长度规范:param x_train: 文本的张量表示, 形如: [[1, 32, 32, 61], [2, 54, 21, 7, 19]]:return: 进行截断补齐后的文本张量表示 # 使用sequence.pad_sequences即可完成return sequence.pad_sequences(x_train, cutlen)
文本数据增强
回译数据增强法
常见的文本数据增强方法回译数据增强法。回译数据增强目前是文本数据增强方面效果较好的增强方法一般基于google翻译接口将文本数据翻译成另外一种语言(一般选择小语种)之后再翻译回原语言即可认为得到与与原语料同标签的新语料新语料加入到原数据集中即可认为是对原数据集数据增强。回译数据增强优势操作简便获得新语料质量高。回译数据增强存在的问题在短文本回译过程中新语料与原语料可能存在很高的重复率并不能有效增大样本的特征空间。高重复率解决办法进行连续的多语言翻译如中文→韩文→日语→英文→中文根据经验最多只采用3次连续翻译更多的翻译次数将产生效率低下语义失真等问题。
jieba词性对照表
jieba词性对照表 - a 形容词 - ad 副形词 - ag 形容词性语素 - an 名形词 - b 区别词 - c 连词 - d 副词 - df - dg 副语素 - e 叹词 - f 方位词 - g 语素 - h 前接成分 - i 成语 - j 简称略称 - k 后接成分 - l 习用语 - m 数词 - mg - mq 数量词 - n 名词 - ng 名词性语素 - nr 人名 - nrfg - nrt - ns 地名 - nt 机构团体名 - nz 其他专名 - o 拟声词 - p 介词 - q 量词 - r 代词 - rg 代词性语素 - rr 人称代词 - rz 指示代词 - s 处所词 - t 时间词 - tg 时语素 - u 助词 - ud 结构助词 得 - ug 时态助词 - uj 结构助词 的 - ul 时态助词 了 - uv 结构助词 地 - uz 时态助词 着 - v 动词 - vd 副动词 - vg 动词性语素 - vi 不及物动词 - vn 名动词 - vq - x 非语素词 - y 语气词 - z 状态词 - zg hanlp词性对照表 【Proper Noun——NR专有名词】 【Temporal Noun——NT时间名词】 【Localizer——LC定位词】如“内”“左右” 【Pronoun——PN代词】 【Determiner——DT限定词】如“这”“全体” 【Cardinal Number——CD量词】 【Ordinal Number——OD次序词】如“第三十一” 【Measure word——M单位词】如“杯” 【VerbVAVCVEVV动词】 【AdverbAD副词】如“近”“极大” 【PrepositionP介词】如“随着” 【Subordinating conjunctionsCS从属连词】 【ConjuctionsCC连词】如“和” 【ParticleDEC,DEG,DEV,DER,AS,SP,ETC,MSP小品词】如“的话” 【InterjectionsIJ感叹词】如“哈” 【onomatopoeiaON拟声词】如“哗啦啦” 【Other Noun-modifierJJ】如“发稿/JJ 时间/NN” 【PunctuationPU标点符号】 【Foreign wordFW外国词语】如“OK 新闻主题分类案例
加载本地数据
from torchtext.legacy.datasets.text_classification import _csv_iterator, _create_data_from_iterator, \TextClassificationDataset
from torchtext.utils import extract_archive
from torchtext.vocab import build_vocab_from_iterator, Vocab# 从本地加载数据的方式本地数据在虚拟机/root/data/ag_news_csv中
# 定义加载函数
def setup_datasets(ngrams2, vocab_trainNone, vocab_testNone, include_unkFalse):train_csv_path data/ag_news_csv/train.csvtest_csv_path data/ag_news_csv/test.csvif vocab_train is None:vocab_train build_vocab_from_iterator(_csv_iterator(train_csv_path, ngrams))else:if not isinstance(vocab, Vocab):raise TypeError(Passed vocabulary is not of type Vocab)if vocab_test is None:vocab_test build_vocab_from_iterator(_csv_iterator(test_csv_path, ngrams))else:if not isinstance(vocab, Vocab):raise TypeError(Passed vocabulary is not of type Vocab)train_data, train_labels _create_data_from_iterator(vocab_train, _csv_iterator(train_csv_path, ngrams, yield_clsTrue), include_unk)test_data, test_labels _create_data_from_iterator(vocab_test, _csv_iterator(test_csv_path, ngrams, yield_clsTrue), include_unk)if len(train_labels ^ test_labels) 0:raise ValueError(Training and test labels dont match)return (TextClassificationDataset(vocab_train, train_data, train_labels),TextClassificationDataset(vocab_test, test_data, test_labels))# 调用函数, 加载本地数据
train_dataset, test_dataset setup_datasets()
print(train_dataset, train_dataset)
构建带有Embedding层的文本分类模型
# 导入必备的torch模型构建工具
import torch.nn as nn
import torch.nn.functional as F# 指定BATCH_SIZE的大小
BATCH_SIZE 16# 进行可用设备检测, 有GPU的话将优先使用GPU
device torch.device(cuda if torch.cuda.is_available() else cpu)class TextSentiment(nn.Module):文本分类模型def __init__(self, vocab_size, embed_dim, num_class):description: 类的初始化函数:param vocab_size: 整个语料包含的不同词汇总数:param embed_dim: 指定词嵌入的维度:param num_class: 文本分类的类别总数super().__init__()# 实例化embedding层, sparseTrue代表每次对该层求解梯度时, 只更新部分权重.self.embedding nn.Embedding(vocab_size, embed_dim, sparseTrue)# 实例化线性层, 参数分别是embed_dim和num_class.self.fc nn.Linear(embed_dim, num_class)# 为各层初始化权重self.init_weights()def init_weights(self):初始化权重函数# 指定初始权重的取值范围数initrange 0.5# 各层的权重参数都是初始化为均匀分布self.embedding.weight.data.uniform_(-initrange, initrange)self.fc.weight.data.uniform_(-initrange, initrange)# 偏置初始化为0self.fc.bias.data.zero_()def forward(self, text)::param text: 文本数值映射后的结果:return: 与类别数尺寸相同的张量, 用以判断文本类别# 获得embedding的结果embedded# embedded.shape# (m, 32) 其中m是BATCH_SIZE大小的数据中词汇总数embedded self.embedding(text)# 接下来我们需要将(m, 32)转化成(BATCH_SIZE, 32)# 以便通过fc层后能计算相应的损失# 首先, 我们已知m的值远大于BATCH_SIZE16,# 用m整除BATCH_SIZE, 获得m中共包含c个BATCH_SIZEc embedded.size(0) // BATCH_SIZE# 之后再从embedded中取c*BATCH_SIZE个向量得到新的embedded# 这个新的embedded中的向量个数可以整除BATCH_SIZEembedded embedded[:BATCH_SIZE * c]# 因为我们想利用平均池化的方法求embedded中指定行数的列的平均数,# 但平均池化方法是作用在行上的, 并且需要3维输入# 因此我们对新的embedded进行转置并拓展维度embedded embedded.transpose(1, 0).unsqueeze(0)# 然后就是调用平均池化的方法, 并且核的大小为c# 即取每c的元素计算一次均值作为结果embedded F.avg_pool1d(embedded, kernel_sizec)# 最后还需要减去新增的维度, 然后转置回去输送给fc层return self.fc(embedded[0].transpose(1, 0))# 获得整个语料包含的不同词汇总数
VOCAB_SIZE len(train_dataset.get_vocab())
# 指定词嵌入维度
EMBED_DIM 32
# 获得类别总数
NUN_CLASS len(train_dataset.get_labels())
# 实例化模型
model TextSentiment(VOCAB_SIZE, EMBED_DIM, NUN_CLASS).to(device)
对数据进行batch处理
def generate_batch(batch):description: 生成batch数据函数:param batch: 由样本张量和对应标签的元组组成的batch_size大小的列表形如:[(label1, sample1), (lable2, sample2), ..., (labelN, sampleN)]return: 样本张量和标签各自的列表形式(张量)形如:text tensor([sample1, sample2, ..., sampleN])label tensor([label1, label2, ..., labelN])# 从batch中获得标签张量label torch.tensor([entry[0] for entry in batch])# 从batch中获得样本张量text [entry[1] for entry in batch]text torch.cat(text)# 返回结果return text, label# 假设一个输入:
batch [(1, torch.tensor([3, 23, 2, 8])), (0, torch.tensor([3, 45, 21, 6]))]
res generate_batch(batch)
print(res)
构建训练与验证函数
# 导入torch中的数据加载器方法
from torch.utils.data import DataLoaderdef train(train_data):模型训练函数# 初始化训练损失和准确率为0train_loss 0train_acc 0# 使用数据加载器生成BATCH_SIZE大小的数据进行批次训练# data就是N多个generate_batch函数处理后的BATCH_SIZE大小的数据生成器data DataLoader(train_data, batch_sizeBATCH_SIZE, shuffleTrue,collate_fngenerate_batch)# 对data进行循环遍历, 使用每个batch的数据进行参数更新for i, (text, cls) in enumerate(data):# 设置优化器初始梯度为0optimizer.zero_grad()# 模型输入一个批次数据, 获得输出output model(text)# 根据真实标签与模型输出计算损失loss criterion(output, cls)# 将该批次的损失加到总损失中train_loss loss.item()# 误差反向传播loss.backward()# 参数进行更新optimizer.step()# 将该批次的准确率加到总准确率中train_acc (output.argmax(1) cls).sum().item()# 调整优化器学习率 scheduler.step()# 返回本轮训练的平均损失和平均准确率return train_loss / len(train_data), train_acc / len(train_data)def valid(valid_data):模型验证函数# 初始化验证损失和准确率为0loss 0acc 0# 和训练相同, 使用DataLoader获得训练数据生成器data DataLoader(valid_data, batch_sizeBATCH_SIZE, collate_fngenerate_batch)# 按批次取出数据验证for text, cls in data:# 验证阶段, 不再求解梯度with torch.no_grad():# 使用模型获得输出output model(text)# 计算损失loss criterion(output, cls)# 将损失和准确率加到总损失和准确率中loss loss.item()acc (output.argmax(1) cls).sum().item()# 返回本轮验证的平均损失和平均准确率return loss / len(valid_data), acc / len(valid_data)
进行模型训练和验证
# 导入时间工具包
import time# 导入数据随机划分方法工具
from torch.utils.data.dataset import random_split# 指定训练轮数
N_EPOCHS 10# 定义初始的验证损失
min_valid_loss float(inf)# 选择损失函数, 这里选择预定义的交叉熵损失函数
criterion torch.nn.CrossEntropyLoss().to(device)
# 选择随机梯度下降优化器
optimizer torch.optim.SGD(model.parameters(), lr4.0)
# 选择优化器步长调节方法StepLR, 用来衰减学习率
scheduler torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma0.9)# 从train_dataset取出0.95作为训练集, 先取其长度
train_len int(len(train_dataset) * 0.95)# 然后使用random_split进行乱序划分, 得到对应的训练集和验证集
sub_train_, sub_valid_ \random_split(train_dataset, [train_len, len(train_dataset) - train_len])# 开始每一轮训练
for epoch in range(N_EPOCHS):# 记录概论训练的开始时间start_time time.time()# 调用train和valid函数得到训练和验证的平均损失, 平均准确率train_loss, train_acc train(sub_train_)valid_loss, valid_acc valid(sub_valid_)# 计算训练和验证的总耗时(秒)secs int(time.time() - start_time)# 用分钟和秒表示mins secs / 60secs secs % 60# 打印训练和验证耗时平均损失平均准确率print(Epoch: %d % (epoch 1), | time in %d minutes, %d seconds % (mins, secs))print(f\tLoss: {train_loss:.4f}(train)\t|\tAcc: {train_acc * 100:.1f}%(train))print(f\tLoss: {valid_loss:.4f}(valid)\t|\tAcc: {valid_acc * 100:.1f}%(valid))
查看embedding层嵌入的词向量
# 打印从模型的状态字典中获得的Embedding矩阵
print(model.state_dict()[embedding.weight])