ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于情感词典与机器学习的视频弹幕情感极性分析

基于情感词典与机器学习的视频弹幕情感极性分析 简介本资源是一份面向高校NLP课程学习者与初学者的自然语言处理期末大作业实践方案聚焦视频弹幕这一典型短文本场景完成端到端的情感极性分析任务。资源包含完整可运行代码、详细文档说明及配套数据集覆盖数据爬取、清洗、停用词处理、情感词典匹配与结果可视化全流程特别适合作为课程设计或期末大作业提交材料。压缩包共15个文件3.82MB含6个核心Python脚本如数据爬取.py、情感分析.py、词云图生成.py、3个文本类资源含正负样本语料与停用词表、2个Excel格式原始与结果数据表、1个Markdown说明文档、1张界面示意图及1个二进制模型文件结构清晰、模块解耦、注释详尽。已有514人学习下载代码逻辑直白、部署简易无需复杂环境配置即可本地运行兼顾教学规范性与工程实用性。1. 项目概述与整体设计思路1.1 为什么选视频弹幕来做情感极性分析NLP大作业选什么题目其实是件挺纠结的事。选经典的情感分析吧用现成的IMDB影评数据集一跑准确率刷到90%以上很容易但做完之后自己心里清楚除了调了几个库什么都没真正学会。选太难的方向吧又怕时间不够代码写不出来答辩的时候被老师问住。我们组当时商量了很久最后定了一个看起来“小众”但实际非常有意思的方向视频弹幕的情感极性分析。弹幕这个东西和传统的影评、商品评论差别很大。它本质上是一种短文本一条弹幕往往只有几个字到十几个字像“哈哈哈哈”、“泪目”、“就这”、“爷青回”信息密度极高但语法极不完整。传统的情感分析模型在长文本上表现不错到了这种碎片化的短文本上经常翻车。而且弹幕里充斥着网络新词、谐音梗、表情符号、英文缩写比如“yyds”、“绝绝子”、“破防了”、“awsl”这些词在常规的词典里根本查不到。正因为这样把它作为大作业题目既有难度又有展示空间做出来之后可以讲的东西非常多。从实际效果来看弹幕情感分析也确实有应用场景。视频平台可以通过它实时监控用户对内容的情感反馈判断哪一段内容是观众喜欢的哪一段让观众反感甚至可以辅助内容推荐和弹幕氛围管理。对主播和UP主来说弹幕情感分布也是调整内容方向的重要参考。所以这个题目不是拍脑袋选的背后有真实的业务逻辑。1.2 情感极性分析的主流技术路线与选型定了题目之后接下来就是选技术路线。这里其实就两条路一条是传统的基于情感词典的方法另一条是基于机器学习或深度学习的方法。基于情感词典的方法核心思想是构建一个带情感极性分值的情感词库比如“喜欢”是2分“讨厌”是-2分然后对一条文本进行分词匹配情感词累加得分再结合否定词、程度副词做调整。这种方法的优点是简单、可解释性强代码量不大适合大作业展示而且不依赖大规模标注数据。缺点是词典覆盖率有限对网络新词比较无力需要不断扩充词典。基于机器学习的方法常见做法是把文本转成TF-IDF向量或者Word2Vec向量然后用SVM、朴素贝叶斯、随机森林等分类器训练。再进阶一点直接用BERT这类预训练模型做文本分类。BERT的效果确实好但问题也很现实需要GPU训练时间长而且大作业如果直接调HuggingFace的库跑一个BERT代码层面能展示的东西很少答辩时容易被追问“你原理讲不清楚”反而扣分。我们最终采用的是“词典法为主、机器学习为辅”的混合路线。主体功能用情感词典法实现保证代码自己写得出来、逻辑讲得清楚同时在实验部分用TF-IDF朴素贝叶斯做一个对照实验对比两种方法的准确率差异。这样一来大作业的技术含量和完整性都拉满了工作量也合理不会把自己陷在模型调参的泥潭里。2. 数据获取与预处理2.1 弹幕数据从哪来采集方案对比做弹幕情感分析第一步得先有数据。市面上的公开弹幕数据集很少所以必须自己动手采集。当时我们调研了几个主流视频平台的弹幕接口发现大部分平台都有Web端接口可以通过视频CID视频编号拉取弹幕列表一般是XML或JSON格式里面包含弹幕内容、发送时间、弹幕ID等字段。采集方式可以自己用Python的requests库写爬虫也可以用现成的开源工具。考虑到大作业的场景我不太建议直接用别人打包好的工具一把梭因为老师问起来“数据怎么来的”如果答不上来印象分会打折扣。自己写一个简单的爬虫其实不难核心逻辑就是两步第一步根据视频页面地址解析出CID第二步请求弹幕接口解析XML。给大家一个参考实现框架import requests import re import xml.etree.ElementTree as ET def get_video_cid(url): # 请求视频页面提取cid参数 resp requests.get(url, headers{User-Agent: Mozilla/5.0}) cid re.search(rcid:(\d), resp.text) if cid: return cid.group(1) return None def fetch_danmaku(cid): # 根据cid请求弹幕接口 api_url fhttps://comment.bilibili.com/{cid}.xml resp requests.get(api_url, headers{User-Agent: Mozilla/5.0}) resp.encoding utf-8 root ET.fromstring(resp.text) contents [] for d in root.iter(d): contents.append(d.text) return contents if __name__ __main__: url 你的视频链接 cid get_video_cid(url) if cid: danmaku_list fetch_danmaku(cid) print(f共获取 {len(danmaku_list)} 条弹幕) # 保存到本地 with open(danmaku.txt, w, encodingutf-8) as f: f.write(\n.join(danmaku_list))实际操作下来要注意两点第一弹幕接口的返回量是有限制的一个视频最多只能拉取最近的一部分弹幕不同平台规则不一样我们当时选择的是几个热门视频分别拉取凑了大概2万多条第二爬虫请求频率不要太高加一个time.sleep()休眠避免给平台服务器造成压力这既是礼貌也是降低被封IP的风险。2.2 数据清洗把脏数据挡在门外采集完原始弹幕之后你会发现数据质量非常“感人”。最常见的几类脏数据包括纯表情符号串比如“”这种没有文字内容的、无意义的乱码字符、广告信息、重复弹幕等等。如果不做清洗后面分词和情感判定的准确率都会受到干扰。清洗的步骤我们分了四步走去空白去掉字符串首尾空格、全角空格、换行符。去纯符号如果一条弹幕去掉非中文字符和英文字母后长度为0直接丢弃。去重复把完全相同的弹幕合并统计次数既节省空间也方便后面按权重计算。统一格式全角英文字母转半角繁体转简体用OpenCC库大写转小写。清洗后的数据量会缩水不少但这都是正常现象。我记得当时2万多条原始弹幕清洗完剩下1.6万条左右去掉的约20%基本都是纯表情和无意义符号。这个比例在弹幕场景中非常典型不用心疼。2.3 分词和停用词过滤的细节弹幕是中文短文本处理之前必须分词。我们用的是jieba分词这几乎是中文NLP工作量最低、效果最均衡的工具。不过需要注意默认的jieba词典对弹幕中的网络新词支持并不好“绝绝子”这种词会被切成“绝绝”和“子”所以必须加载自定义词典。自定义词典的格式很简单每个词一行可以包含词频和词性绝绝子 100 n 破防了 100 v yyds 50 x 爷青回 50 x把用户自定义词典加到jieba里分词准确率会有明显提升。这里有个小技巧如果你不确定一个词该不该加进自定义词典可以先跑一遍分词结果把明显被切碎的网络热词记下来统一加进去迭代两三轮基本就稳定了。停用词表也是必须的。弹幕里的“的”、“了”、“吗”、“啊”这类语气词和助词对情感判定没有贡献反而会干扰情感词的匹配。哈工大停用词表、百度停用词表都可以直接用但要注意在这些通用停用词表的基础上把弹幕特有的高频无用词也加进去比如“哈哈哈哈”、“666”这类虽然是语气词但有一定的情感色彩是否清洗取决于你的策略。我们当时的处理是保留“哈哈哈哈”这类能反映积极情绪的表情性词汇因为它们本身带有明显的情感倾向先单独挑出来做规则匹配再把剩下的部分去停用词。3. 情感判定核心模块实现3.1 情感词典的构建从基础词库到弹幕特色词库情感词典是整个项目的灵魂词典的质量直接决定了情感分析的效果。通常我们不会从一个空词典开始而是使用学术界公开的基础情感词典再结合弹幕语料进行扩充。我们使用的两个基础词典一个是知网HowNet情感词典包含正面情感词、负面情感词、程度级别词等覆盖面很广另一个是大连理工大学的中文情感词汇本体库这个更细把情感分成了乐、好、怒、哀、惧、恶、惊七大类并且每个词都标注了情感极性0中性、1正、2负、3兼有和情感强度1到9。把这两个词典合并去重就得到了一个规模不小的基础词库。但光有基础词库远远不够。前面提过弹幕里的“yyds”、“awsl”、“破防了”、“emo了”这些词在正常词典里是查不到的。我们在清洗完弹幕语料之后做了一个高频词统计把出现次数Top 300的词挑出来人工过了一遍把明显带有情感倾向的词挑出来人工标注情感极性补充到词典里。这一步工作量不算大但对效果的提升非常明显。这里分享一个扩充词典的经验情感词不全是一眼看穿的“绝绝子”是正面“夺笋”是调侃性的负面“摆烂”是消极的负面“海王”偏贬义“宝藏”偏褒义。如果你拿不准某个词的情感倾向可以把这个词的所有语境弹幕拉出来看一遍根据多数语境判断不要凭印象拍脑袋。3.2 情感打分策略不止是加加减减情感极性分析的核心算法逻辑并不复杂基本流程是对分词后的词序列逐个匹配情感词典中的情感词累加情感得分同时考虑程度副词和否定词的影响。但这里有一个非常经典的坑简单加加减减会翻车。举个简单的例子“这部电影一点也不好看”分词后是“这/部/电影/一点/也/不/好看”其中“好看”是正面词1“不”是否定词。如果规则是“否定词使情感词得分反转”那结果就是-1判定为负面这刚好是对的。那再来一句“我不要太喜欢这部电影”“不要”会反转“喜欢”得到-1但这句话的真实含义其实是“我非常喜欢”情感是正面的。这就是中文否定词的复杂性口语化表达中“不要太好”往往是反讽或加强语气。我们当时的处理策略是建立否定词和程度副词的映射表设置一个滑动窗口。具体规则如下在情感词前一个窗口内我们取前面2个词如果出现“不”、“没”、“无”、“莫”、“非”等否定词情感得分乘以-1。如果出现“很”、“非常”、“极其”、“超级”、“太”等程度副词根据程度级别乘以对应的权重系数比如“非常”是1.8倍“有点”是0.5倍。如果否定词和程度副词同时出现且程度副词在否定词前面如“不太喜欢”做了反转衰减处理如果程度副词在否定词后面如“不很喜欢”则保留反转。这个方法虽然不能解决所有问题但已经能覆盖弹幕中大部分常见的否定和强调表达。另外弹幕里经常出现的连续感叹号“”和“哈哈哈哈哈”可以视为情感加强信号。我们的规则是如果一条弹幕匹配到正面情感词且以连续3个以上感叹号结尾得分额外1如果是负面情感词且有大量感叹号则额外-1。这条规则虽然有点“暴力”但在弹幕场景中效果很不错。最后一条弹幕的总得分就是所有情感词得分累加的结果。我们设置了一个阈值总分大于0判正面小于0判负面等于0判中性。考虑到中文表达的含蓄性当时还加了一个阈值调节参数只有绝对值大于0.5才判正面或负面否则划为中性。这个参数可以通过实验调优在作业报告中也能体现你对系统的思考。3.3 规则引擎代码实现要点情感打分模块的代码结构我在这里贴一个核心逻辑的简化版本里面带注释大家可以直接参考import jieba import jieba.posseg as pseg class EmotionAnalyzer: def __init__(self, pos_dict, neg_dict, degree_dict, neg_words): self.pos_dict pos_dict self.neg_dict neg_dict self.degree_dict degree_dict self.neg_words neg_words def analyze(self, text): # 分词并过滤停用词这里省略停用词处理 words [w for w in jieba.cut(text) if w.strip()] score 0.0 window_size 2 for i, word in enumerate(words): weight 0 # 匹配正面词 if word in self.pos_dict: weight self.pos_dict[word] # 匹配负面词 elif word in self.neg_dict: weight -self.neg_dict[word] if weight ! 0: # 往前看窗口内的否定词和程度副词 neg_flag False degree_factor 1.0 for j in range(max(0, i - window_size), i): if words[j] in self.neg_words: neg_flag not neg_flag if words[j] in self.degree_dict: degree_factor self.degree_dict[words[j]] if neg_flag: weight -weight score weight * degree_factor return score这个实现虽然简单但已经是一个可以跑通全流程的框架。在此基础上我还加了感叹号加强规则、表情符号规则和网络词规则。3.4 另一种路线TF-IDF加朴素贝叶斯做对照实验为了在作业报告里展示对比分析我们还实现了一个基于TF-IDF加朴素贝叶斯的对照实验。思路是把情感词典法对每一条弹幕的判定结果作为伪标签虽然不完美但可以用来训练分类器或者更严谨一点人工标注一部分数据大概500到1000条用这些标注数据训练一个朴素贝叶斯模型。从结果来看在标注数据量较少的情况下朴素贝叶斯的效果会略逊于词典法因为训练数据不足而且弹幕文本太短会导致TF-IDF特征非常稀疏。但如果把标注数据扩展到2000条以上机器学习法的效果会反过来略优于词典法尤其是在处理“阴阳怪气”这种反讽表达时机器学习能学到一些词典法学不到的上下文模式。在报告中我们画了一张性能对比表分别计算了两种方法在测试集上的准确率、精确率、召回率和F1值。这种对比实验的写法是老师比较喜欢看到的因为它体现了你不只是跑通了一个系统而是对不同的技术方案有比较和思考。4. 项目代码结构与管理4.1 代码目录怎么组织大作业代码的目录结构虽然没有硬性要求但一个清晰的组织方式能让你在写报告和答辩时省很多力气。我们的结构如下danmaku-sentiment/ ├── data/ │ ├── raw/ # 原始弹幕数据 │ ├── cleaned/ # 清洗后的数据 │ └── dicts/ # 情感词典、停用词表、自定义词典 ├── src/ │ ├── crawler.py # 弹幕爬虫 │ ├── preprocess.py # 数据清洗与分词 │ ├── analyzer.py # 情感分析核心逻辑 │ ├── train_nb.py # 朴素贝叶斯对照实验 │ └── visualize.py # 结果可视化 ├── output/ │ ├── figures/ # 图表 │ ├── result.csv # 情感分析结果表 │ └── report.md # 实验报告 ├── requirements.txt └── README.md这个结构的好处是职责分明数据、代码、结果分开放不会像一个文件夹里扔了几十个文件那样混乱。requirements.txt里把jieba、scikit-learn、pandas、matplotlib、opencc这几个核心依赖列清楚可以让别人在复现的时候少踩很多环境坑。4.2 中间结果落盘的意义写大作业代码的时候最容易犯的一个错误就是追求“一条流水线走到底”从原始数据直接出结果。这种做法在调试的时候非常痛苦你根本不知道哪一步出了问题。我们当时的实践是每一步处理都同步保存中间结果。爬虫爬完存一份原始数据清洗完存一份清洗数据分词完存一份带词性的分词结果最后情感分析的每一条结果都输出成CSV。CSV里至少包含这些字段弹幕原始文本、清洗后文本、分词结果、情感得分、情感极性。这样一旦发现某条弹幕的判错了你可以直接查CSV定位到是分词的问题还是词典缺失的问题。这也是我在做完这个大作业之后最大的体会之一写分析类代码中间结果要尽量落到磁盘上别全都放在内存里不然排查问题的成本会高到让你怀疑人生。5. 常见坑位与排查指南5.1 编码问题全局统一UTF-8弹幕数据是中文编码问题会出现在各个角落。爬虫请求回来的响应如果直接用默认编码解析很容易出现乱码。我们的做法是所有读取和保存文件都显式指定encodingutf-8爬虫请求时设置响应的编码避免Windows平台默认GBK编码导致的头疼问题。另外还有个细节在Windows上跑脚本时控制台输出中文可能会遇到UnicodeEncodeError这不是代码逻辑错了而是控制台编码问题解决方案是设置环境变量PYTHONIOENCODINGutf-8或者在代码最前面加一行sys.stdout.reconfigure(encodingutf-8)。5.2 否定词的语义反转并不总是成立前面提到过否定词处理这里再展开说。在中文里否定词的作用非常复杂有双重否定表肯定的情况例如“不会不喜欢”其实是“喜欢”有反讽用法“你真是太好了”在特定语境下是负面的还有口语化的强调用法“好得不要不要的”是正面。这些在简单的规则引擎里很难全部处理。我们的应对策略是在作业报告里主动承认规则引擎的局限并给出具体的失败案例。这比装作自己的系统完美无缺要好得多老师会认为你有批判性思维。同时我们针对“双重否定”这类常见情况在代码里做了一层特殊处理如果同一个情感词前出现偶数个否定词判定为肯定不反转极性。5.3 网络新词和表情符号怎么处理网络新词更新速度快得离谱可能你今天刚把“栓Q”加进词典下周就有新的热词出现了。对于大作业来说不可能追求百分之百的覆盖率更合理的做法是设计一个可维护的词典扩展机制。我们的做法是把自定义网络词单独放在一个文本文件里标注好情感值和词性让analyzer.py启动时动态加载。这样以后看到新词只需要在文本文件里加一行不需要改任何代码。表情符号的处理类似我们把常见的“笑哭”、“流泪”、“生气”等emoji单独映射成对应的情感词比如“”映射为“笑哭”正面或中性“”映射为“愤怒”负面。在弹幕里emoji往往比文字更直接地表达情感这个信息不能浪费。5.4 标注工作量与训练数据的平衡如果你做机器学习对照实验就会面对一个现实问题人工标注弹幕数据真的很累。一条弹幕短语义又复杂标注速度大概一小时几百条标2000条需要好几个小时而且标注的一致性不好保证。我们的做法是两个人各标一半然后交叉验证遇到分歧大的弹幕讨论后统一标准。这个过程本身也可以写进报告里作为“数据标注一致性”讨论的素材。如果实在不想人工标注可以用词典法的结果作为“软标签”但必须说明这存在噪声模型评估指标的可靠性会打折扣。6. 实验评估与报告撰写建议6.1 实验设计、评估指标与结果呈现实验部分我们把数据划分成训练集和测试集比例是82。词典法没有训练过程直接在测试集上评估。朴素贝叶斯则在训练集上训练在测试集上评估。评估指标用了准确率、精确率、召回率和F1四个。由于我们的人工标注量有限1500条整体样本量不算大所以精确率和召回率的波动会比较明显在报告里要说明这一点不要强行得出结论。从我们的结果来看词典法在测试集上的准确率大约在78%左右TF-IDF加朴素贝叶斯大约在74%左右。差距不算太大这个结果其实比较符合预期词典法在短文本情感分析场景下如果没有大量标注数据支撑并不会明显输给传统机器学习方法。在报告里多展示几个典型的情感判定案例正确和错误的都要有比单纯贴数字有说服力得多。6.2 报告文档的结构建议作业报告的写法建议遵循“背景、方法、实验、分析、总结”的主线。背景部分要有佐证引用几篇情感分析和弹幕研究的论文让老师知道你做过文献调研。方法部分要写清楚技术选型的理由比如为什么选词典法作为主体为什么用jieba分词为什么选择这两个基础情感词典。实验部分除了数字还要有可视化图表。总结部分不要空泛地写“本项目实现了什么”而是写“在过程中遇到了什么困难怎么解决的还有哪些不足之处”。6.3 答辩时高频问题的应对答辩环节老师通常不会逐行看代码但会问几个关键问题。我们当时被问到的主要是情感词典和权威词典有什么区别怎么保证词典质量——就从构建过程讲说明基础词典来源权威弹幕词库通过人工审核补充并给出具体的样例。和BERT相比你这个方法有什么优势和不足——优势是计算资源要求低、可解释性强、部署快不足是语义理解深度不够反讽和复杂句法处理不了。你的系统能直接应用到生产环境吗——诚实回答不能直接商用因为通用性不足换一个视频类型可能效果下降但可以作为一个快速原型结合业务数据进一步优化。这些问题都不难关键是你在做项目的时候真的动过脑子而不是对着别人的项目改个名字交上去。7. 从大作业到真实项目的几点体会做完这个NLP大作业我最大的体会是大作业的价值不在于最后得多少分而在于你完整地走了一遍“数据采集—数据清洗—算法设计—代码实现—实验评估—报告写作”的流程。这个过程比任何一门课程都更接近于真实项目中一个NLP功能的落地路径。最后再分享一个小技巧做大作业的时候建议把每一个关键节点的决策理由记在一个单独的笔记里比如“为什么选这个词典”、“为什么窗口大小取2”、“为什么阈值设0.5”。这些理由放在报告里既是答辩的弹药库也是你在这个项目里的真实收获。等到项目结束回头看你会发现最值钱的不是那份源码而是这些决策背后的思考过程。本文还有配套的精品资源点击获取
返回列表