ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于深度学习的情感分析在智慧养老系统中的应用

2026/9/10 12:21:34 拓冰建站 浏览量
基于深度学习的情感分析在智慧养老系统中的应用 简介这是一份基于情感分析的智慧养老系统深度学习课程设计项目包含Python源码、设计文档和演示PPT等完整材料适合计算机相关专业的在校学生、教师或企业员工用于课程设计、期末大作业、毕业设计及项目立项演示。项目由个人大三学期课程设计整理而来经导师指导与评审获得高分代码完整且功能验证稳定可靠可直接运行参考。资源包为zip格式整体约632.41MB内含项目源码、设计文档、答辩PPT等文件目录结构清晰便于检索学习。目前已有414人学习下载。资源既适合基础薄弱者对照学习情感分析、系统开发与部署流程也适合有一定基础者在此基础上进行二次开发和功能扩展可结合设计文档快速把握模块划分与实现细节是一份高质量的实践范例。1. 情感分析在养老场景的价值从情绪监测到服务优化智慧养老系统在多数人印象里是智能手环、睡眠监测、跌倒报警这类物联网应用但真正难做的不是硬件接入而是对老人“心里状态”的量化。基于情感分析的智慧养老系统本质是把老人日常产生的文本数据——比如对话记录、护工日志、家属留言、问卷量表——交给深度学习模型做情绪极性判断再把结果落到养老服务流程里。当老人连续出现低落情绪时系统向照护人员推送预警甚至自动调整餐饮、活动安排这才是有数据支撑的智慧养老。对毕设而言识别模型的构建、训练、评估和系统集成才是工作量所在也是答辩时最能展示能力的地方。适合正在准备深度学习或自然语言处理方向毕业设计的同学也适合想快速把情绪识别接入业务系统的开发人员参考。2. 系统架构与数据流设计情感分析模型的输入从哪里来养老场景的情感分析不是直接在浏览器里调用一个现成大模型就结束的必须有一个完整的数据管道。老人不会像电商评论那样写整齐的评价文本他们的情绪信息往往藏在语音转写后的对话里、每日心情打卡的短句中、甚至填写问卷时随手写下的几个词语。这个系统的架构要解决三个问题如何拿到文本数据、如何把数据变成模型能读懂的向量、如何把模型的输出变成服务动作。2.1 多源文本数据的采集与清洗常见的数据来源有三类。第一类是语音转写记录养老院的陪护机器人或智能音箱会将对话转成中文文本第二类是问卷调查的主观题比如“今天最开心的事是什么”第三类是在线留言板家属或老人在系统里留下的反馈。这些数据的共同问题是口语化严重、句子极短、夹杂方言和重复词。数据清洗阶段需要做几件事统一用jieba分词去掉停用词把表情符号转换为文本标记比如用[happy]代替笑脸。这里要注意老人表达情绪往往依赖语气词连词如“唉”“哎哟”在通用语料里是停用词但在养老服务场景中是负面情绪信号不能直接删。建议先做一轮词频分析看语料库里哪些词是明显的情绪词再决定停用词表。2.1.1 标签体系怎么设计情感类别不能只分“正面/负面”二类。养老场景更关注的是细粒度情绪喜悦、平静、焦虑、孤独、烦躁。推荐使用四分类加一个“其他”兜底类类别少了看不出问题类别多了标注成本高且模型难以收敛。实际标注时一条文本可以由两名同学同时标不一致的部分讨论后决定这种一致性校验在答辩时可以作为数据质量控制的亮点。2.1.2 数据数量级与标注工作量如果做毕设不要幻想从零收集几万条养老对话。常见做法是使用开源的中文情感语料作为基础比如电商评论或微博情绪分类数据集再手工补充几百条养老场景特有句子比如“今天儿子没来电话”“隔壁老王走了”。模型先在通用语料上预训练再用小规模养老语料微调这样可以解决数据不足的问题而且训练曲线有明显的变化过程适合在论文里呈现。2.2 模型在系统架构中的位置情感分析模块是系统的决策中枢。输入的文本经过预处理变成向量后由模型输出每个情绪类别的概率系统根据概率判断是否触发预警。整个流程按顺序执行前一级的结果直接影响下一级的行为。系统模块输入输出技术要点数据采集层原始对话/问卷/留言格式化文本语音转写工具需做方言适配预处理模块格式化文本分词后的索引序列保留语气词构建领域停用词表情感分析模型索引序列情绪类别与置信度使用双向LSTM或BERT业务决策模块情绪类别与置信度预警/记录/建议设定阈值避免误报服务执行模块预警信息通知护工或调整服务人工复核后再执行2.3 预警阈值的业务含义预警不是模型输出负面就立刻通知这会带来大量误报。经验做法是设置一个连续负面情绪判定机制——比如10分钟内出现2次以上负面情绪或单条文本负面概率超过0.85才触发预警。这样既避免漏报也保证护工不会被频繁打扰。这个规则在系统设计文档中很重要因为它演示了“模型输出”到“业务决策”之间的完整转换。3. 深度学习模型设计与训练从词向量到LSTM的落地路径情感分析模型的选型决定了整个系统的效果上限。对于养老场景文本短、口语化、类别不均衡常见的做法是使用预测练词向量加双向LSTM的结构。在标题涉及的深度学习毕设背景下相比直接调用BERTLSTM结构更容易被讲清楚原理训练速度也适合普通电脑完成。当然如果机器配置足够也可以用bert-base-chinese做微调但在文档中应给出两种方案的对比。3.1 词向量的选择与处理养老场景的词汇和通用领域差异明显。使用通用的中文预训练词向量时“孤独”“惦记”“闷”这类词往往没有准确的语义映射因此需要自己统计语料并训练word2vec。语料量不够也不必担心这里的作用不是让词向量更精准而是让词表里每个词都有一个初始向量参与训练模型在微调阶段会自动调整它们。from gensim.models import Word2Vec import jieba sentences [ list(jieba.cut(今天儿子没来看我有点难过)), list(jieba.cut(护工阿姨陪我聊了很久很开心)), list(jieba.cut(最近晚上总是睡不着心里发慌)) ] model Word2Vec(sentences, vector_size128, window5, min_count1, sg1) word2idx {word: index 2 for index, word in enumerate(model.wv.index_to_key)} word2idx[PAD] 0 word2idx[UNK] 1vector_size128表示词向量的维度过小会损失语义信息过大会增加训练量128 是一个相对平衡的值。window5表示考虑前后各5个词作为上下文口语化短句本身长度有限窗口设为3到5都比较合适。min_count1保证所有词都保留因为养老语料中的词频普遍较低如果设得太高大部分词会被过滤掉。sg1使用skip-gram模型适合语料量较小时更好地捕捉词义。3.2 分类模型结构双向LSTM与注意力加权双向LSTM适合处理短文本因为句子前后两个方向的上下文都能被捕捉到比如“爷爷今天很开心”和“今天爷爷很开心”语义相同但词序不同双向结构能让模型更稳定地学习这类模式。为了提升重要词在分类中的权重可以在LSTM输出层加一个简单的注意力机制。import torch import torch.nn as nn import torch.nn.functional as F class SentimentLSTM(nn.Module): def __init__(self, vocab_size, embed_size, hidden_size, num_classes, num_layers2): super().__init__() self.embedding nn.Embedding(vocab_size, embed_size, padding_idx0) self.lstm nn.LSTM(embed_size, hidden_size, num_layers, batch_firstTrue, bidirectionalTrue, dropout0.5) self.attn nn.Linear(hidden_size * 2, hidden_size * 2) self.fc nn.Linear(hidden_size * 2, num_classes) self.dropout nn.Dropout(0.5) def forward(self, x): emb self.embedding(x) out, _ self.lstm(emb) attn_scores torch.tanh(self.attn(out)) attn_weights F.softmax(attn_scores, dim1) context torch.sum(attn_weights * out, dim1) out self.dropout(context) return self.fc(out)padding_idx0让填充位置的词向量在反向传播时不更新避免无意义的计算。LSTM层设dropout0.5防止过拟合但注意只有层数大于1时该参数才生效。注意力机制对最终分类的贡献是让模型更关注情绪词所在的位置比如“难过”比“今天”得到的注意力分数更高。这个结构在论文里画图展示时比直接堆叠LSTM更完整。3.3 训练脚本与关键参数调整训练时使用交叉熵损失函数和Adam优化器学习率设为2e-3。如果模型在前几个epoch内损失不下降首先检查学习率如果发现训练集准确率很高但验证集很低则说明过拟合需要增加dropout或减小模型规模。model SentimentLSTM(len(word2idx), 128, 256, num_classes5) optimizer torch.optim.Adam(model.parameters(), lr2e-3) criterion nn.CrossEntropyLoss() for epoch in range(30): for batch_x, batch_y in train_loader: outputs model(batch_x) loss criterion(outputs, batch_y) optimizer.zero_grad() loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) optimizer.step()clip_grad_norm_是文本分类中的常用技巧把梯度范数限制在1.0以内防止梯度爆炸。学习率2e-3比图像任务常用的1e-3稍高因为文本特征的稀疏性导致模型更新幅度天然偏小。训练大约20到30个epoch即可收敛不需要像图像模型一样训练数百轮。注意如果训练过程中损失出现明显震荡优先降低学习率到5e-4而不是增加训练轮次。养老文本数据量小模型很容易在后期过拟合。3.4 不均衡标签的处理思路养老场景中“平静”类样本远多于“孤独”“烦躁”类模型会倾向于把所有样本都预测为多数类。最简单的处理方法是计算每个类别的权重让少数类在损失函数中获得更高的权重。nn.CrossEntropyLoss直接支持weight参数传入各类别样本数倒数的归一化结果即可不需要修改其他任何代码。4. Python推理代码与业务接口封装模型训练完成后需要把模型应用到实际输入上。这一步要写两个模块一个是针对单条文本的情感推理函数另一个是把推理函数暴露成API接口方便系统调用。这部分也是毕设源码里最容易被检查的地方评审老师会看模型是不是只在一个固定脚本里运行封装是否完整。4.1 单条文本的情感推理推理代码要把“用户输入文本”走完整个流程分词、映射到索引、转tensor、模型前向传播、概率转换。一个常见的错误是训练时做了分词和词表映射推理时却忘了做同样处理导致输入维度对不上。import torch import jieba def predict_sentiment(text, model, word2idx, devicecpu): tokens list(jieba.cut(text)) ids [word2idx.get(w, word2idx[UNK]) for w in tokens] ids ids[:50] [0] * max(0, 50 - len(ids)) ids_tensor torch.tensor([ids], dtypetorch.long).to(device) model.eval() with torch.no_grad(): logits model(ids_tensor) probs torch.softmax(logits, dim1).squeeze(0) emotion_map {0: 喜悦, 1: 平静, 2: 焦虑, 3: 孤独, 4: 烦躁} pred torch.argmax(probs).item() return emotion_map[pred], probs[pred].item() print(predict_sentiment(今天护工小李帮我晒了被子心里很暖和, model, word2idx))代码里把句子截断或补齐到50个词这是训练时设置的max_len。如果训练时用的是max_len100这里必须一致否则模型会报维度错误。model.eval()和with torch.no_grad()必须同时使用前者关闭dropout后者停止梯度计算推理速度会快不少。4.1.1 推理时需要注意的编码问题Windows 环境下经常遇到中文乱码建议在脚本开头指定sys.stdout.reconfigure(encodingutf-8)。如果模型文件是通过GPU训练的在CPU机器上加载时需要加map_locationcpu参数否则会报设备不匹配的错误。4.2 用 Flask 封装成 REST API智慧养老系统的前端和后端是分离的后端需要提供接口让管理页面或者小程序调用。用Flask搭建一个最小的推理服务接收JSON格式的请求返回情绪标签和置信度。from flask import Flask, request, jsonify app Flask(__name__) def load_model(): global model, word2idx model SentimentLSTM(len(word2idx), 128, 256, num_classes5) model.load_state_dict(torch.load(model.pth, map_locationcpu)) model.eval() app.route(/analyze, methods[POST]) def analyze(): data request.get_json() text data.get(text, ) if not text: return jsonify({error: text is required}), 400 emotion, confidence predict_sentiment(text, model, word2idx) return jsonify({emotion: emotion, confidence: confidence}) if __name__ __main__: load_model() app.run(host0.0.0.0, port5000)load_model()在服务启动前执行一次不要在每个请求里重新加载模型否则并发量大时会直接卡死。text参数做非空校验是必要的前端不知道什么时候会发来空字符串。confidence返回的是概率值调用方可以根据它决定是否触发预警比如低于0.6时忽略结果。注意port5000常用于开发环境部署到服务器时需要改到其他端口避免和冲突。4.3 接口测试与错误排查用curl或Postman测试接口是最快的方式成功后可以在浏览器中直接看到JSON结果。curl -X POST http://127.0.0.1:5000/analyze \ -H Content-Type: application/json \ -d {text: 晚上一个人在屋里有点想孩子}返回结果示例{confidence: 0.82, emotion: 孤独}如果接口返回500错误先查看Flask控制台输出最常见的错误是模型加载路径不对。建议在load_model()里加一段路径检查确保model.pth文件存在再继续执行。另外第一次启动会加载模型和词向量需要几秒钟前端调用时要设置合理的超时时间。5. 模型评估与智慧养老系统的验证方法毕设答辩时评审老师通常不会只看系统能不能运行他们更关心模型的效果如何以及选用的指标是否有说服力。评估不能只汇报准确率养老服务中对负面情绪识别的召回率同样重要——漏报一次孤独情绪可能导致一次心理危机。因此评估章节需要多维度展示模型表现。5.1 评估指标的选择准确率与加权F1在情绪类别不均衡的数据集上准确率是容易骗人的指标。假设“平静”占80%模型把所有样本都判断为“平静”准确率也有80%但这毫无意义。正确做法是关注每个类别的精确率和召回率尤其是负面类别。加权F1值综合考虑了各类别的表现也适用于不均衡场景。类别精确率召回率F1喜悦0.870.720.79平静0.880.940.91焦虑0.680.710.69孤独0.750.640.69烦躁0.710.520.60可以看到“平静”与“喜悦”的F1值较高“烦躁”类F1只有0.60说明模型对负面情绪的区分度还不够。这类结果是可以接受的毕竟数据量有限重要的是在论文里给出后续优化方向比如扩充训练语料或引入多模态情感分析中的语音特征来辅助文本判断。5.2 阈值调整如何权衡预警的灵敏度模型输出的概率值本身只是一个连续分数在实际业务系统里需要设定一个阈值来决定是否触发预警。这个阈值不能拍脑袋定要用验证集画出P-R曲线然后找到精确率和召回率的平衡点。from sklearn.metrics import precision_recall_curve import numpy as np probs_list [] # 保存验证集的负面概率 labels_list [] # 保存真实标签1为负面 precision, recall, thresholds precision_recall_curve(labels_list, probs_list) f1_scores 2 * (precision * recall) / (precision recall) best_threshold thresholds[np.argmax(f1_scores)] print(f最佳阈值: {best_threshold:.3f})示例中主要原理是算每个候选阈值下的F1值取最大值对应的阈值作为业务配置。实际部署时还可以在最佳阈值的基础上提高一点比如从0.4提高到0.5以减少误报。原因是养老场景里误报会导致护工对预警信息脱敏频繁的假警报比漏报更容易破坏信任。5.3 常见部署问题与排查顺序系统接入真实数据后模型的准确率通常会比测试集里低一些原因在于真实对话长度更长、噪声更多且包含了大量在训练集里没见过的人名和地名。以下是按出现频率排序的排查顺序文本预处理是否一致。训练时对句子做了哪些清洗部署时也保持一致比如是否保留了标点。词表中的未登录词比例。如果超过20%说明词表覆盖度太低需要重新训练word2vec。检查模型的预测置信度分布。如果大多数样本的置信度都在0.5附近说明模型训练不充分。查看是不是输入文本中包含大量数字或URL被分成了多个无用词干扰注意力的计算。提示养老场景的对话文本往往有很强的时段特征早上的心情普遍比晚上好。部署时可以考虑按不同时段分别设置阈值早晨负向概率超过0.7预警晚上超过0.6就预警。6. 模型的持续优化与跨场景复用最后一个环节要解决的是模型交付后的维护问题。很多毕设项目答辩结束就停止了但系统在真实使用中需要持续迭代。这里的核心技巧是建立一个数据回流的闭环每次预警后护工标记这条预警是否准确把标记结果定期加入训练集重新微调模型。通过几个月的积累领域数据增加后模型精度会明显提升。一个值得写进论文的技巧是迁移学习。先在大规模通用中文情感语料上做多分类预训练保存模型参数然后在标注好的养老对话数据上只微调最后一层全连接层。这种方法在小样本条件下效果显著而且训练时间很短。更进阶的做法是使用大模型的伪标注能力拿通用大模型生成几组养老服务场景的模拟对话筛选其中置信度高的样本作为训练辅助数据再结合少量人工标注数据训练最终模型。如果后续想拓展方向可以尝试把文本情感分析和语音语速特征做简单的融合比如老人在说出“没事”时语速变慢这在多模态情感分析中是一个典型的判断线索。别人用文本识别不到的情绪波动结合语气特征后往往能暴露出来。这个功能在实际养老系统里很有应用价值也是从普通还能跑的系统走向真正被使用的系统的关键分水岭。本文还有配套的精品资源点击获取