Python 全栈体系【四阶】(六十一)

第五章 深度学习

十三、自然语言处理(NLP)

5. NLP应用

5.2 文本情感分析

目标:利用训练数据集,对模型训练,从而实现对中文评论语句情感分析。情绪分为正面、负面两种

数据集:中文关于酒店的评论,5265笔用户评论数据,其中2822笔正面评价、其余为负面评价

步骤:同上一案例

模型选择:

在这里插入图片描述

代码:

【数据预处理】

# 中文情绪分析:数据预处理部分
import paddle
import paddle.dataset.imdb as imdb
import paddle.fluid as fluid
import numpy as np
import os
import random
from multiprocessing import cpu_count# 数据预处理,将中文文字解析出来,并进行编码转换为数字,每一行文字存入数组
mydict = {}  # 存放出现的字及编码,格式: 好,1
code = 1
data_file = "data/hotel_discuss2.csv"  # 原始样本路径
dict_file = "data/hotel_dict.txt" # 字典文件路径
encoding_file = "data/hotel_encoding.txt" # 编码后的样本文件路径
puncts = " \n"  # 要剔除的标点符号列表with open(data_file, "r", encoding="utf-8-sig") as f:for line in f.readlines():# print(line)trim_line = line.strip()for ch in trim_line:if ch in puncts:  # 符号不参与编码continueif ch in mydict:  # 已经在编码字典中continueelif len(ch) <= 0:continueelse:  # 当前文字没在字典中mydict[ch] = codecode += 1code += 1mydict["<unk>"] = code  # 未知字符# 循环结束后,将字典存入字典文件
with open(dict_file, "w", encoding="utf-8-sig") as f:f.write(str(mydict))print("数据字典保存完成!")# 将字典文件中的数据加载到mydict字典中
def load_dict():with open(dict_file, "r", encoding="utf-8-sig") as f:lines = f.readlines()new_dict = eval(lines[0])return new_dict# 对评论数据进行编码
new_dict = load_dict()  # 调用函数加载
with open(data_file, "r", encoding="utf-8-sig") as f:with open(encoding_file, "w", encoding="utf-8-sig") as fw:for line in f.readlines():label = line[0]  # 标签remark = line[1:-1]  # 评论for ch in remark:if ch in puncts:  # 符号不参与编码continueelse:fw.write(str(mydict[ch]))fw.write(",")fw.write("\t" + str(label) + "\n")  # 写入tab分隔符、标签、换行符print("数据预处理完成")

【模型定义与训练】

# 获取字典的长度
def get_dict_len(dict_path):with open(dict_path, 'r', encoding='utf-8-sig') as f:lines = f.readlines()new_dict = eval(lines[0])return len(new_dict.keys())# 创建数据读取器train_reader和test_reader
# 返回评论列表和标签
def data_mapper(sample):dt, lbl = sampleval = [int(word) for word in dt.split(",") if word.isdigit()]return val, int(lbl)# 随机从训练数据集文件中取出一行数据
def train_reader(train_list_path):def reader():with open(train_list_path, "r", encoding='utf-8-sig') as f:lines = f.readlines()np.random.shuffle(lines)  # 打乱数据for line in lines:data, label = line.split("\t")yield data, label# 返回xmap_readers, 能够使用多线程方式读取数据return paddle.reader.xmap_readers(data_mapper,  # 映射函数reader,  # 读取数据内容cpu_count(),  # 线程数量1024)  # 读取数据队列大小# 定义LSTM网络
def lstm_net(ipt, input_dim):ipt = fluid.layers.reshape(ipt, [-1, 1],inplace=True) # 是否替换,True则表示输入和返回是同一个对象# 词嵌入层emb = fluid.layers.embedding(input=ipt, size=[input_dim, 128], is_sparse=True)# 第一个全连接层fc1 = fluid.layers.fc(input=emb, size=128)# 第一分支:LSTM分支lstm1, _ = fluid.layers.dynamic_lstm(input=fc1, size=128)lstm2 = fluid.layers.sequence_pool(input=lstm1, pool_type="max")# 第二分支conv = fluid.layers.sequence_pool(input=fc1, pool_type="max")# 输出层:全连接out = fluid.layers.fc([conv, lstm2], size=2, act="softmax")return out# 定义输入数据,lod_level不为0指定输入数据为序列数据
dict_len = get_dict_len(dict_file)  # 获取数据字典长度
rmk = fluid.layers.data(name="rmk", shape=[1], dtype="int64", lod_level=1)
label = fluid.layers.data(name="label", shape=[1], dtype="int64")# 定义长短期记忆网络
model = lstm_net(rmk, dict_len)# 定义损失函数,情绪判断实际是一个分类任务,使用交叉熵作为损失函数
cost = fluid.layers.cross_entropy(input=model, label=label)
avg_cost = fluid.layers.mean(cost)  # 求损失值平均数
# layers.accuracy接口,用来评估预测准确率
acc = fluid.layers.accuracy(input=model, label=label)# 定义优化方法
# Adagrad(自适应学习率,前期放大梯度调节,后期缩小梯度调节)
optimizer = fluid.optimizer.AdagradOptimizer(learning_rate=0.001)
opt = optimizer.minimize(avg_cost)# 定义网络
# place = fluid.CPUPlace()
place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())  # 参数初始化# 定义reader
reader = train_reader(encoding_file)
batch_train_reader = paddle.batch(reader, batch_size=128)# 定义输入数据的维度,数据的顺序是一条句子数据对应一个标签
feeder = fluid.DataFeeder(place=place, feed_list=[rmk, label])for pass_id in range(40):for batch_id, data in enumerate(batch_train_reader()):train_cost, train_acc = exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost, acc])if batch_id % 20 == 0:print("pass_id: %d, batch_id: %d, cost: %0.5f, acc:%.5f" %(pass_id, batch_id, train_cost[0], train_acc))print("模型训练完成......")# 保存模型
model_save_dir = "model/chn_emotion_analyses.model"
if not os.path.exists(model_save_dir):print("create model path")os.makedirs(model_save_dir)fluid.io.save_inference_model(model_save_dir,  # 保存路径feeded_var_names=[rmk.name],target_vars=[model],executor=exe)  # Executorprint("模型保存完成, 保存路径: ", model_save_dir)

【推理预测】

import paddle
import paddle.fluid as fluid
import numpy as np
import os
import random
from multiprocessing import cpu_countdata_file = "data/hotel_discuss2.csv"
dict_file = "data/hotel_dict.txt"
encoding_file = "data/hotel_encoding.txt"
model_save_dir = "model/chn_emotion_analyses.model"def load_dict():with open(dict_file, "r", encoding="utf-8-sig") as f:lines = f.readlines()new_dict = eval(lines[0])return new_dict# 根据字典对字符串进行编码
def encode_by_dict(remark, dict_encoded):remark = remark.strip()if len(remark) <= 0:return []ret = []for ch in remark:if ch in dict_encoded:ret.append(dict_encoded[ch])else:ret.append(dict_encoded["<unk>"])return ret# 编码,预测
lods = []
new_dict = load_dict()
lods.append(encode_by_dict("总体来说房间非常干净,卫浴设施也相当不错,交通也比较便利", new_dict))
lods.append(encode_by_dict("酒店交通方便,环境也不错,正好是我们办事地点的旁边,感觉性价比还可以", new_dict))
lods.append(encode_by_dict("设施还可以,服务人员态度也好,交通还算便利", new_dict))
lods.append(encode_by_dict("酒店服务态度极差,设施很差", new_dict))
lods.append(encode_by_dict("我住过的最不好的酒店,以后决不住了", new_dict))
lods.append(encode_by_dict("说实在的我很失望,我想这家酒店以后无论如何我都不会再去了", new_dict))# 获取每句话的单词数量
base_shape = [[len(c) for c in lods]]# 生成预测数据
place = fluid.CPUPlace()
infer_exe = fluid.Executor(place)
infer_exe.run(fluid.default_startup_program())tensor_words = fluid.create_lod_tensor(lods, base_shape, place)infer_program, feed_target_names, fetch_targets = fluid.io.load_inference_model(dirname=model_save_dir, executor=infer_exe)
# tvar = np.array(fetch_targets, dtype="int64")
results = infer_exe.run(program=infer_program,feed={feed_target_names[0]: tensor_words},fetch_list=fetch_targets)# 打印每句话的正负面预测概率
for i, r in enumerate(results[0]):print("负面: %0.5f, 正面: %0.5f" % (r[0], r[1]))

6. 附录

6.1 附录一:相关数学知识

向量余弦相似度

余弦相似度使用来度量向量相似度的指标,当两个向量夹角越大相似度越低;当两个向量夹角越小,相似度越高。

在这里插入图片描述

在三角形中,余弦值计算方式为 c o s θ = a 2 + b 2 − c 2 2 a b cos \theta = \frac{a^2 + b^2 - c^2}{2ab} cosθ=2aba2+b2c2,向量夹角余弦计算公式为:

c o s θ = a b ∣ ∣ a ∣ ∣ × ∣ ∣ b ∣ ∣ cos \theta = \frac{ab}{||a|| \times ||b||} cosθ=∣∣a∣∣×∣∣b∣∣ab

分子为两个向量的内积,分母是两个向量模长的乘积。

在这里插入图片描述

其推导过程如下:

c o s θ = a 2 + b 2 − c 2 2 a b = x 1 2 + y 1 2 + x 2 2 + y 2 2 + ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 2 x 1 2 + y 1 2 x 2 2 + y 2 2 = 2 x 1 x 2 + 2 y 1 y 2 2 x 1 2 + y 1 2 x 2 2 + y 2 2 = a b ∣ ∣ a ∣ ∣ × ∣ ∣ b ∣ ∣ cos \theta = \frac{a^2 + b^2 - c^2}{2ab} \\ = \frac{\sqrt{x_1^2 + y_1^2} + \sqrt{x_2^2 + y_2^2 }+ \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}}{2 \sqrt{x_1^2 + y_1^2} \sqrt{x_2^2 + y_2^2}} \\ = \frac{2 x_1 x_2 + 2 y_1 y_2}{2 \sqrt{x_1^2 + y_1^2} \sqrt{x_2^2 + y_2^2}} = \frac{ab}{||a|| \times ||b||} cosθ=2aba2+b2c2=2x12+y12 x22+y22 x12+y12 +x22+y22 +(x1x2)2+(y1y2)2 =2x12+y12 x22+y22 2x1x2+2y1y2=∣∣a∣∣×∣∣b∣∣ab

以上是二维向量的计算过程,推广到N维向量,分子部分依然是向量的内积,分母部分依然是两个向量模长的乘积。由此可计算文本的余弦相似度。

6.2 附录二:参考文献

1)《Python自然语言处理实践——核心技术与算法》 ,涂铭、刘祥、刘树春 著 ,机械工业出版社

2)《Tensorflow自然语言处理》,【澳】图珊·加内格达拉,机械工业出版社

3)《深度学习之美》,张玉宏,中国工信出版集团 / 电子工业出版社

4)网络部分资源

6.3 附录三:专业词汇列表
英文简写英文全写中文
NLPNature Language Processing自然语言处理
NERNamed Entities Recognition命名实体识别
PoSpart-of-speech tagging词性标记
MTMachine Translation机器翻译
TF-IDFTerm Frequency-Inverse Document Frequency词频-逆文档频率
Text Rank文本排名算法
One-hot独热编码
BOWBag-of-Words Model词袋模型
N-GramN元模型
word embedding词嵌入
NNLMNeural Network Language Model神经网络语言模型
HMMHidden Markov Model隐马尔可夫模型
RNNRecurrent Neural Networks循环神经网络
Skip-gram跳字模型
CBOWContinous Bag of Words连续词袋模型
LSTMLong Short Term Memory长短期记忆模型
GRUGated Recurrent Unit门控环单元
BRNNBi-recurrent neural network双向循环神经网络
FMMForward Maximum Matching正向最大匹配
RMMReverse Maximum Matching逆向最大匹配
Bi-MMBi-directional Maximum Matching双向最大匹配法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/860635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Servlet开发javaweb,请求常见错误详解及其解决办法【404、405、500】

Servlet报错的情况多种多样&#xff0c;涵盖了配置错误、代码逻辑错误、资源未找到、权限问题等多个方面。以下是一些常见的Servlet报错情况及其可能的原因和解决方法&#xff1a; 404 Not Found: 错误原因图示&#xff1a; URL映射 发送请求&#xff0c;出现404错误 原因: 请…

基于jeecgboot-vue3的Flowable流程-自定义业务表单处理(一)支持同一个业务多个关联流程的选择支持

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 这部分先讲讲支持自定义业务表单一个业务服务表单多个流程的支持处理 1、后端mapper部分 如下&#xff0c;修改selectSysCustomFormByServiceName为list对象&#xff0c;以便支持多个 &…

通信系统网络架构_1.局域网网络架构

当今&#xff0c;通信网络从大的方面主要包括局域网、广域网、移动通信网等网络形式。不同的网络会采用不同的技术进行网络构建。以下针对不同的网络给出各自的网络架构以及所采用的技术。 1.概述 局域网&#xff0c;即计算机局部区域网络&#xff0c;是一种为单一机构所拥有的…

Simufact Additive增材制造支撑创建功能

增材制造工艺作为近年来制造行业的顶流&#xff0c;一直备受各行业关注。除了率先大范围展开增材制造应用的航空行业&#xff0c;在汽车、电子乃至医疗行业也都有了不俗的进展。深谙增材制造工艺的学者都直言&#xff1a;使用3D打印简单&#xff0c;但应用好比较难。那是因为这…

【高校科研前沿】四川大学刘超研究员为一作在《Geophys. Res. Lett.》发表团队成果:植被形态影响河床泥沙输运

文章简介 论文名称&#xff1a;Plant morphology impacts bedload sediment transport 第一作者及单位&#xff1a;刘超&#xff08;研究员|四川大学水利水电学院&#xff09; 通讯作者及单位&#xff1a;Yuqi Shan&#xff08;四川大学灾后重建与管理研究所&#xff09; 文…

【HashMap和HashSetyi以及散列表的拉链法,线性探测法详解】

&#x1f308;个人主页&#xff1a;SKY-30 ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 &…

昇思25天学习打卡营第2天 | 张量Tensor

张量Tensor 张量&#xff08;Tensor&#xff09;基础 张量是MindSpore中的基本数据结构的一种&#xff0c;类似于NumPy中数组和矩阵非常相似。它具有以下重要属性&#xff1a; 形状&#xff08;shape&#xff09;和数据类型&#xff08;dtype&#xff09;&#xff1a;每个张量…

如何找到合适的Python第三方库?

找合适的Python库其实很简单&#xff0c;按照以下三步法&#xff0c;你能找到90%的Python库。 1、百度谷歌搜索 明确自己的需求&#xff0c;用Python来干什么&#xff0c;力求简短明了。比如定位“数据分析”&#xff0c;然后去搜索关键词【Python数据分析第三方库】&#xf…

基于 JWT 进行身份验证

一、JWT 介绍 JWT 本质上就是一组字串&#xff0c;通过&#xff08;.&#xff09;切分成三个为 Base64 编码的部分&#xff1a; Header : 描述 JWT 的元数据&#xff0c;定义了生成签名的算法以及 Token 的类型。Payload : 用来存放实际需要传递的数据Signature&#xff08;签…

考研数学|张宇和武忠祥,强化能不能同时跟?

可以说你跟武老师学明白了&#xff0c;120完全没问题&#xff01;如果追求更高&#xff0c;宇哥的怀抱也想你敞开&#xff01; 学长我21年一战数学83&#xff0c;总分没过线&#xff0c;22年二战143&#xff0c;逆袭上岸211&#xff01;市面上的老师我基本都听过&#xff0c;最…

微深节能 料场堆取料无人操作系统 格雷母线

格雷母线高精度位移检测系统在料场堆取料中的应用是一个重要的技术进步&#xff0c;它极大地提升了堆取料作业的自动化和精确性。 一、格雷母线定位系统概述 格雷母线高精度位移测量系统&#xff0c;包括格雷母线、天线箱、地址解码器、地址编码器四个部分组成。 格雷母线类似一…

Java养老护理助浴陪诊小程序APP源码

&#x1f496;护理助浴陪诊小程序&#x1f496; 一、引言&#xff1a;养老新趋势&#x1f331; 在快节奏的现代生活中&#xff0c;养老问题逐渐成为了社会关注的焦点。如何为老年人提供便捷、贴心的服务&#xff0c;让他们晚年生活更加安心、舒适&#xff0c;是我们每个人都需…

篮球联盟管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;球员管理&#xff0c;用户管理&#xff0c;球队管理&#xff0c;论坛管理&#xff0c;篮球资讯管理&#xff0c;基础数据管理 前台账户功能包括&#xff1a;系统首页&#xff0…

Transformer常见面试题

目录 1.Transformer为何使用多头注意力机制&#xff1f;&#xff08;为什么不使用一个头&#xff09; 2.Transformer为什么Q和K使用不同的权重矩阵生成&#xff0c;为何不能使用同一个值进行自身的点乘&#xff1f; &#xff08;注意和第一个问题的区别&#xff09; 3.Transf…

git提交新仓库代码,提示无权限,但用户名已修改

目录 1 用户名无权限 2 删除用户凭据 2.1 打开控制面板 2.2 找到“凭据管理器” 2.3 删除git历史 3 npm工具库添加git仓库指引 1 用户名无权限 之前因为时间的原因&#xff0c;js-tool-big-box工具库没有提交到github上去&#xff0c;今天想着往上提交一下&#xff0c;但…

Linux系统中根下的目录结构介绍

一、Linux的路径分隔符 Linux系统中使用正斜杠(/)作为路径分隔符&#xff1b;每个目录的后面都默认带有一个正斜杠&#xff08;如&#xff1a;需要进入opt目录可以分别使用【cd /opt】或【cd /opt/】&#xff09; 二、Linux根目录下各个目录结构介绍 红色标识的文件夹为Linux的…

“开源AI”到底是什么意思

开源与专有软件之间的斗争早已为人所熟知。然而&#xff0c;长期以来弥漫在软件圈的紧张关系已经渗透到了人工智能领域&#xff0c;部分原因在于没有人能在AI背景下就“开源”的真正含义达成一致。 相关阅读&#xff1a;GPT-4o通过整合文本、音频和视觉实现人性化的AI交互&…

PTP时间同步协议简介

注意&#xff0c;上图中 t1 t4 都是主机时间。 t2 t3 都是从机时间。 总延迟为 (t4 - t1) - (t3 - t2) 单边的平均延迟为 ((t4 - t1) - (t3 - t2) ) / 2&#xff0c;公式d1 两边的时钟偏差为 (((t3 t2) / 2)) - ((t4 t1) / 2) 也可以通过下面2个式子 t2 offset delay t1…

Orangepi Zero2 全志H616 的初识

目录 一、全志H616简介 1.1 为什么学&#xff1a; 1.2 学什么&#xff1a; 1.3 全志H616平台介绍&#xff1a; 二、刷机 系统启动和初始化配置 2.1 需要的工具&#xff1a; 2.2 工具安装&#xff1a; 2.3 刷机&#xff1a; 2.4 登录系统&#xff1a; 2.5 修改登录密码…

Prometheus:开源监控解决方案的力量

前言 在当今高度数字化和云原生应用的时代&#xff0c;监控系统是确保系统稳定性和性能的关键组成部分。而 Prometheus 作为一种开源的监控解决方案&#xff0c;正在成为越来越多企业和开发者的首选。本文将深入探讨 Prometheus 的特性、优势以及如何利用它来构建强大的监控系…