我用 Python 搭了一套文本情感分析系统:从用户评论中自动提取正面负面情绪

发布时间:2026/6/21 7:53:10
我用 Python 搭了一套文本情感分析系统:从用户评论中自动提取正面负面情绪 我用 Python 搭了一套文本情感分析系统从用户评论中自动提取正面负面情绪适合需要分析用户评论、产品评价、社交媒体情感倾向的运营和开发者。本文用 Python 搭了一套完整的情感分析系统从数据采集到情感打分到可视化报告。背景为什么需要情感分析每天有大量用户评论、产品评价、社交媒体帖子。手动看 100 条还行10000 条就看不过来了。情感分析能自动判断每条评论是正面还是负面快速发现产品哪里被吐槽最多用户对新功能的反馈是好是坏竞品的口碑怎么样方案对比方案准确率成本适合调 LLM API最高高按 token 收费少量高质量分析预训练模型高低本地推理中等规模规则匹配中极低简单场景SnowNLP中极低快速原型我的组合预训练模型做主力 LLM 做精细分析。模块 1基础情感分析SnowNLP最简单的方案5 行代码搞定fromsnownlpimportSnowNLPdefsimple_sentiment(text):简单情感分析返回 0-1越大越正面sSnowNLP(text)returns.sentiments# 示例texts[这个产品太好用了强烈推荐,质量很差用了一天就坏了,还行吧一般般,客服态度非常好问题解决很快,垃圾浪费钱]fortextintexts:scoresimple_sentiment(text)label正面ifscore0.5else负面print(f[{label}{score:.2f}]{text})输出[正面 0.95] 这个产品太好用了强烈推荐 [负面 0.08] 质量很差用了一天就坏了 [负面 0.42] 还行吧一般般 [正面 0.88] 客服态度非常好问题解决很快 [负面 0.05] 垃圾浪费钱模块 2预训练模型更准确用 HuggingFace 的预训练情感分析模型fromtransformersimportpipeline# 加载中文情感分析模型classifierpipeline(sentiment-analysis,modeluer/roberta-base-finetuned-chinanews-chinese)defpretrained_sentiment(text):预训练模型情感分析resultclassifier(text)[0]return{label:result[label],score:result[score]}# 示例texts[这个产品太好用了,质量很差不推荐,服务态度不错但发货太慢]fortextintexts:resultpretrained_sentiment(text)print(f[{result[label]}{result[score]:.2f}]{text})模块 3LLM 精细分析对于需要更细粒度分析的场景如提取具体的情感维度用 LLMfromopenaiimportOpenAI clientOpenAI()defllm_sentiment(text):LLM 精细情感分析promptf分析以下用户评论的情感返回 JSON 格式 评论{text}返回格式 {{ overall: 正面/负面/中性, score: 1-10, aspects: [ {{aspect: 产品功能, sentiment: 正面/负面, detail: 具体点}}, {{aspect: 服务态度, sentiment: 正面/负面, detail: 具体点}} ], keywords: [关键词1, 关键词2] }}responseclient.chat.completions.create(modelgpt-4,messages[{role:user,content:prompt}],temperature0.1)importjsonreturnjson.loads(response.choices[0].message.content)# 示例review产品功能很强大但界面设计太丑了客服回复也慢resultllm_sentiment(review)print(json.dumps(result,ensure_asciiFalse,indent2))输出{overall:中性,score:5,aspects:[{aspect:产品功能,sentiment:正面,detail:功能强大},{aspect:界面设计,sentiment:负面,detail:界面太丑},{aspect:客服响应,sentiment:负面,detail:回复慢}],keywords:[功能强大,界面丑,客服慢]}模块 4批量分析importpandasaspddefbatch_analyze(texts,methodsnownlp):批量情感分析results[]fortextintexts:ifmethodsnownlp:scoresimple_sentiment(text)label正面ifscore0.5else负面elifmethodpretrained:rpretrained_sentiment(text)label,scorer[label],r[score]elifmethodllm:rllm_sentiment(text)label,scorer[overall],r[score]/10results.append({text:text,label:label,score:score})dfpd.DataFrame(results)returndf# 使用comments[这个产品太好用了,质量很差不推荐,服务态度不错,发货太慢了,性价比很高,包装破损差评,功能齐全值得购买,客服态度恶劣]dfbatch_analyze(comments,methodsnownlp)# 统计print(f总数:{len(df)})print(f正面:{len(df[df[label]正面])}({len(df[df[label]正面])/len(df)*100:.1f}%))print(f负面:{len(df[df[label]负面])}({len(df[df[label]负面])/len(df)*100:.1f}%))print(f平均分:{df[score].mean():.2f})模块 5可视化报告importstreamlitasstimportplotly.expressaspx st.title(情感分析报告)# 上传文件uploaded_filest.file_uploader(上传评论数据CSV,type[csv])ifuploaded_file:dfpd.read_csv(uploaded_file)text_colst.selectbox(选择评论列,df.columns)# 批量分析withst.spinner(分析中...):resultsbatch_analyze(df[text_col].tolist())df[sentiment]results[label]df[score]results[score]# 图表col1,col2st.columns(2)withcol1:# 情感分布饼图fig1px.pie(df,namessentiment,title情感分布,color_discrete_map{正面:#4CAF50,负面:#F44336})st.plotly_chart(fig1,use_container_widthTrue)withcol2:# 情感分数分布fig2px.histogram(df,xscore,title情感分数分布,nbins20,color_discrete_sequence[#2196F3])st.plotly_chart(fig2,use_container_widthTrue)# 负面评论 TOP 10st.subheader(负面评论 TOP 10)negativedf[df[sentiment]负面].sort_values(score).head(10)st.dataframe(negative[[text_col,score]])# 导出st.download_button(下载分析结果,df.to_csv(indexFalse).encode(utf-8-sig),sentiment_results.csv,text/csv)模块 6定时监控importscheduledefdaily_sentiment_report():每日情感分析报告# 1. 采集新评论从数据库/APInew_commentsfetch_new_comments()# 2. 情感分析dfbatch_analyze(new_comments)# 3. 统计positive_ratelen(df[df[label]正面])/len(df)*100negative_ratelen(df[df[label]负面])/len(df)*100# 4. 告警ifnegative_rate30:send_alert(f⚠️ 负面评论占比{negative_rate:.1f}%超过阈值 30%)# 5. 生成报告reportf 每日情感分析报告 - 总评论数:{len(df)}- 正面:{positive_rate:.1f}% - 负面:{negative_rate:.1f}% - 平均分:{df[score].mean():.2f}save_report(report)# 每天早上 9 点运行schedule.every().day.at(09:00).do(daily_sentiment_report)踩坑记录坑 1SnowNLP 对反讽不准确症状真是好极了反讽被判断为正面。原因SnowNLP 基于词典不理解反讽语义。解决反讽场景用 LLM 分析它能理解上下文。坑 2预训练模型不支持 GPU症状10000 条评论分析要 1 小时。原因默认用 CPU 推理。解决安装torch的 GPU 版本模型会自动用 CUDA 加速。坑 3LLM 分析成本太高症状10000 条评论用 GPT-4 分析API 费用 500 元。解决先用 SnowNLP 粗筛只对不确定的评论用 LLM 精分析。或者用 GPT-3.5-turbo便宜 50 倍。坑 4中文分词问题症状“不太好用被分成不”“太”“好”“用”不好这个语义被拆散了。原因分词器对否定词处理不好。解决用预训练模型它内部有更好的分词或者在预处理时把不好很差等否定词组作为整体。坑 5情感分数阈值不好定症状0.5 作为阈值很多中性评论被分到负面。解决用三分类正面/中性/负面中性区间设为 0.4-0.6。总结3 条核心经验按数据量选方案。100 条以内用 LLM1000 条用预训练模型10000 条以上用 SnowNLP LLM 混合。反讽和否定是最难的。“好极了反讽”不太好这类表达简单模型处理不好需要 LLM 或预训练模型。情感分析的价值在于趋势。单条评论的分析意义不大关键是看趋势变化——负面率突然升高说明出了问题。你有做过情感分析吗用什么方案评论区交流。