一、项目背景:为什么要做社交媒体情感分析?
现在每天有上亿条社交媒体评论(比如微博、小红书)产生,这些文本里藏着用户的真实态度——比如“某品牌口红太干”是负面反馈,“演唱会超震撼”是正面情绪。但人工分析这些数据根本不现实,需要用算法自动分类。
传统情感分析有两个痛点:
- 噪音多:社交媒体文本里混着广告、URL、乱码(比如“领券拍t.cn/xxx”),直接分析会… accuracy;
- 分类准度低:单纯用朴素贝叶斯等基础算法,对“又爱又恨”这类复杂情感的分类准确率常低于70%。
我的毕业设计就是解决这两个问题:以微博为数据源,先爬取评论并清理噪音,再用“SVM过滤广告+朴素贝叶斯+AdaBoost优化”的流程,把评论分成“积极、消极、客观”三类,最终准确率提升到85%以上,能帮企业快速抓用户反馈,也能为社会舆情分析提供支持。
二、核心技术栈:从数据处理到算法优化
整个系统围绕“数据爬取→预处理→过滤→情感分类→算法加强”展开,技术栈兼顾实用性和可实现性,本科生用Python就能落地:
| 技术模块 | 具体工具/算法 | 核心作用 |
|---|---|---|
| 数据爬取 | 微博API+Python SDK | 获取微博数据:通过申请微博开放平台API,批量爬取公共 timeline 评论,一次可获取200条,支持存储到MySQL; |
| 文本预处理 | 结巴分词+停用词表 | 清理噪音:分词(“萌萌哒”拆成“萌萌”)、删URL/用户名(@xxx)、去停用词(“的”“了”); |
| 广告过滤 | SVM(LinearSVC) | 初步筛选:把“领券”“包邮”这类广告评论过滤掉,减少无关数据干扰; |
| 基础情感分类 | 多项式朴素贝叶斯 | 三类分类:将过滤后的评论分成积极(1)、消极(2)、客观(3),基于词频做特征; |
| 算法优化 | AdaBoost(SAMME.R) | 提升准度:把朴素贝叶斯当“弱分类器”,用AdaBoost迭代优化,解决复杂情感分类不准问题; |
| 可视化与评估 | Matplotlib+ROC曲线 | 结果验证:画准确率曲线、ROC曲线,直观对比优化前后的效果; |
| 数据库 | MySQL | 存储数据:爬取的原始评论、预处理后的文本、分类结果,方便后续调用; |
三、项目全流程:5步实现微博情感分析系统
3.1 第一步:数据爬取——获取微博评论数据
要做情感分析,首先得有高质量的数据源,这里用微博官方API爬取,避免反爬风险:
3.1.1 爬取准备(3个关键步骤)
- 申请微博API权限:
- 登录微博开放平台,创建“应用”,获取App Key和App Secret;
- 配置回调页(比如http://localhost:8080),获取访问令牌(Token),这是调用API的“钥匙”;
- 安装Python SDK:
pip install weibo-sdk - 设计存储结构:
在MySQL建表weibo_comments,字段包括comment_id(评论ID)、content(评论内容)、create_time(发布时间),方便后续处理。
3.1.2 核心爬取代码
用SDK调用statuses/public_timeline接口,批量获取并存储微博:
from weibo import APIClient
import pymysql
# 1. 初始化API客户端
APP_KEY = '你的App Key'
APP_SECRET = '你的App Secret'
CALLBACK_URL = '你的回调页'
client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL)
# 设置Token(提前获取)
client.set_access_token('你的Token', expires_in=3600)
# 2. 连接MySQL
db = pymysql.connect(host='localhost', user='root', password='123456', db='weibo_db')
cursor = db.cursor()
# 3. 爬取并存储微博(一次200条)
try:
# 调用API获取公共timeline
result = client.statuses.public_timeline.get(count=200, separators=(',', ':'))
comments = result['statuses']
# 遍历存储
for comment in comments:
content = comment['text'] # 评论内容
create_time = comment['created_at'] # 发布时间
# 插入数据库
sql = "INSERT INTO weibo_comments (content, create_time) VALUES (%s, %s)"
cursor.execute(sql, (content, create_time))
db.commit()
print("爬取成功,共200条微博")
except Exception as e:
print(f"爬取失败:{e}")
db.rollback()
finally:
db.close()
- 注意:微博API有调用频率限制(每小时150次),避免频繁请求导致封号。
3.2 第二步:文本预处理——清理“脏数据”
爬取的微博里有大量噪音(URL、用户名、表情符号),必须先处理,否则会干扰后续分类:
3.2.1 预处理4步走
- 删除URL:
微博里的短链接(如t.cn/xxx)毫无情感意义,…import re def delete_url(text): return re.sub(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', '', text) - 删除用户名:
@开头的用户名(如@real__pcyyyyy)对情感分析无用,同样用正则删除:def delete_username(text): return re.sub(r'@[a-zA-Z0-9_]+', '', text) - 中文分词:
用结巴分词的“精确模式”,把句子拆成词语(比如“今天很开心”→['今天', '很', '开心']):import jieba def cut_words(text): return jieba.lcut(text, cut_all=False) # 精确模式 - 去除停用词:
加载停用词表(含“的”“了”“啊”等无意义词),过滤掉分词结果中的停用词:# 加载停用词表 stop_words = set() with open('stop_words.txt', 'r', encoding='utf-8') as f: for line in f: stop_words.add(line.strip()) def delete_stop_words(words): return [word for word in words if word not in stop_words and len(word) > 1] # 还过滤掉单字
3.2.2 预处理效果对比
原始评论:
"【领10元券】帆布鞋26.8元,领券拍:http://t.cn/R6lLnsV @申马官方"
处理后:
['帆布鞋', '26.8元', '领券拍', '官方']
(广告关键词“领券拍”会在后续SVM过滤中被识别并删除)
3.3 第三步:SVM过滤——剔除广告等无关评论
预处理后仍有广告(如“领券拍”“包邮”),用LinearSVC做二分类,把评论分成“相关(情感评论)”和“无关(广告/乱码)”:
3.3.1 核心步骤
- 标注训练数据:
手动标注1000条预处理后的评论,“0”代表无关(广告),“1”代表相关(情感评论); - 特征提取:
用“词频”做特征,把文本转成向量(比如“开心”出现2次,对应向量维度值为2):from sklearn.feature_extraction.text import CountVectorizer # 把分词结果拼成字符串(CountVectorizer需要输入字符串) train_texts = [' '.join(words) for words in train_words_list] # train_words_list是标注数据的分词结果 # 初始化向量器 vectorizer = CountVectorizer() # 转成词频向量 X_train = vectorizer.fit_transform(train_texts) y_train = train_labels # 标注的标签(0/1) - 训练SVM模型:
用LinearSVC训练,适合文本分类,速度快:from sklearn.svm import LinearSVC # 初始化模型 svm_model = LinearSVC(random_state=42) # 训练 svm_model.fit(X_train, y_train) - 过滤无关评论:
对新爬取的评论,先用预处理,再转成向量,用SVM预测,只保留“相关(1)”的评论:def filter_irrelevant(comment_words): # 转成向量 text = ' '.join(comment_words) X = vectorizer.transform([text]) # 预测 pred = svm_model.predict(X)[0] return pred == 1 # True表示相关,保留;False表示无关,过滤
3.3.1 过滤效果
测试1000条评论,SVM过滤广告的准确率达92%,把“领券”“包邮”这类无关评论剔除后,后续情感分类的噪音减少40%。
3.4 第四步:朴素贝叶斯——基础情感分类
把SVM过滤后的评论分成“积极、消极、客观”三类,用多项式朴素贝叶斯(适合文本分类,对词频特征友好):
3.4.1 核心步骤
- 标注情感数据:
手动标注800条相关评论,“1”=积极(如“生日快乐[噢耶]”),“2”=消极(如“好难啊[失望]”),“3”=客观(如“今天吃了饭”); - 特征提取:
复用SVM的CountVectorizer(避免重新拟合,保证特征一致),把标注数据转成词频向量; - 训练朴素贝叶斯模型:
用MultinomialNB,加拉普拉斯平滑(避免概率为0的情况):from sklearn.naive_bayes import MultinomialNB # 初始化模型(alpha=1是拉普拉斯平滑) nb_model = MultinomialNB(alpha=1) # 训练(X_train_nb是情感标注数据的词频向量,y_train_nb是情感标签1/2/3) nb_model.fit(X_train_nb, y_train_nb) - 情感预测:
对新的相关评论,预处理后转向量,用模型预测情感类别:def predict_sentiment(comment_words): text = ' '.join(comment_words) X = vectorizer.transform([text]) pred = nb_model.predict(X)[0] # 映射成情感标签 sentiment_map = {1: '积极', 2: '消极', 3: '客观'} return sentiment_map[pred]
3.4.2 基础分类效果
测试200条评论,朴素贝叶斯的准确率约78%——对“开心”“失望”这类明显情感词分类准,但对“又甜又虐”这类复杂情感容易错。
3.5 第五步:AdaBoost优化——提升分类准度
针对朴素贝叶斯的不足,用AdaBoost(SAMME.R算法)把它当“弱分类器”,迭代优化,提升复杂情感的分类准度:
3.5.1 核心原理
AdaBoost的思路:每次迭代给“分类错的样本”加权重,让下一轮弱分类器更关注这些样本,最后把多轮弱分类器的结果加权融合,得到强分类器。
3.5.2 优化步骤
- 初始化AdaBoost模型:
用sklearn的AdaBoostClassifier,base_estimator设为朴素贝叶斯,算法选SAMME.R(适合多分类):from sklearn.ensemble import AdaBoostClassifier # 初始化AdaBoost(n_estimators=50是迭代50轮) ada_model = AdaBoostClassifier( base_estimator=nb_model, # 弱分类器是朴素贝叶斯 n_estimators=50, algorithm='SAMME.R', # 多分类用SAMME.R random_state=42 ) - 训练优化模型:
用情感标注数据训练AdaBoost:ada_model.fit(X_train_nb, y_train_nb) - 优化后预测:
用AdaBoost模型替代原始朴素贝叶斯,预测情感:def predict_sentiment_ada(comment_words): text = ' '.join(comment_words) X = vectorizer.transform([text]) pred = ada_model.predict(X)[0] sentiment_map = {1: '积极', 2: '消极', 3: '客观'} return sentiment_map[pred]
3.5.3 优化效果对比
| 指标 | 朴素贝叶斯 | AdaBoost优化后 | 提升幅度 |
|---|---|---|---|
| 准确率(%) | 78 | 86 | +8% |
| 复杂情感准度(%) | 65 | 82 | +17% |
| ROC曲线AUC | 0.81 | 0.92 | +0.11 |
- 关键原因:AdaBoost对“又甜又虐”这类分类错的样本重点优化,多轮迭代后能捕捉到更细的情感特征。
四、毕业设计复盘:踩过的坑与经验
4.1 那些踩过的坑
- API调用失败:一开始没注意Token过期时间,爬取时突然报错——解决:在代码里加Token过期检测,到期前重新获取;
- 分词不准:结巴分词对网络流行词(如“yyds”)分错——解决:自定义词典,把“yyds”“绝绝子”加入词典,提高分词准确率;
- AdaBoost过拟合:迭代轮次设为100时,训练集准确率98%,测试集只有75%——解决:把n_estimators降到50,加正则化(如限制弱分类器复杂度)。
4.2 给学弟学妹的建议
- 数据标注要认真:情感分析的效果依赖标注质量,一开始随便标导致模型不准,后来重新标了500条才好转;
- 先跑通基础流程:不要一开始就上复杂算法,先实现“爬取→预处理→朴素贝叶斯”的基础流程,再逐步优化;
- 答辩突出对比效果:评委喜欢看“优化前后的差异”,比如展示SVM过滤前后的评论数量、AdaBoost准确率提升的曲线,比单纯讲公式更有说服力。
五、项目资源与后续扩展
5.1 项目核心资源
本项目包含完整的代码(爬取、预处理、模型训练)、标注数据集(1800条微博情感标签)、停用词表,可支持直接复现实验结果。若需获取这些资源,可私信沟通,还能提供模型调参和代码调试的指导。
5.2 未来扩展方向
- 细粒度情感分析:目前是三类分类,后续可细分“惊喜、愤怒、悲伤”等更细情感;
- 结合BERT预训练模型:用BERT做词嵌入,替代传统词频特征,进一步提升复杂情感的分类准度;
- 实时舆情监控:对接微博实时API,实时分析热点事件的情感趋势(如某演唱会的观众反馈)。
如果本文对你的自然语言处理、文本情感分析相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多算法落地的实战案例!