毕业设计实战:基于社交媒体评论的文本情感分析系统(从数据爬取到AdaBoost优化全流程)

88 阅读10分钟

一、项目背景:为什么要做社交媒体情感分析?

现在每天有上亿条社交媒体评论(比如微博、小红书)产生,这些文本里藏着用户的真实态度——比如“某品牌口红太干”是负面反馈,“演唱会超震撼”是正面情绪。但人工分析这些数据根本不现实,需要用算法自动分类。

传统情感分析有两个痛点:

  • 噪音多:社交媒体文本里混着广告、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个关键步骤)

  1. 申请微博API权限
  2. 安装Python SDK
    pip install weibo-sdk
    
  3. 设计存储结构
    在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步走

  1. 删除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)
    
  2. 删除用户名
    @开头的用户名(如@real__pcyyyyy)对情感分析无用,同样用正则删除:
    def delete_username(text):
        return re.sub(r'@[a-zA-Z0-9_]+', '', text)
    
  3. 中文分词
    用结巴分词的“精确模式”,把句子拆成词语(比如“今天很开心”→['今天', '很', '开心']):
    import jieba
    def cut_words(text):
        return jieba.lcut(text, cut_all=False)  # 精确模式
    
  4. 去除停用词
    加载停用词表(含“的”“了”“啊”等无意义词),过滤掉分词结果中的停用词:
    # 加载停用词表
    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 核心步骤

  1. 标注训练数据
    手动标注1000条预处理后的评论,“0”代表无关(广告),“1”代表相关(情感评论);
  2. 特征提取
    用“词频”做特征,把文本转成向量(比如“开心”出现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)
    
  3. 训练SVM模型
    用LinearSVC训练,适合文本分类,速度快:
    from sklearn.svm import LinearSVC
    # 初始化模型
    svm_model = LinearSVC(random_state=42)
    # 训练
    svm_model.fit(X_train, y_train)
    
  4. 过滤无关评论
    对新爬取的评论,先用预处理,再转成向量,用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 核心步骤

  1. 标注情感数据
    手动标注800条相关评论,“1”=积极(如“生日快乐[噢耶]”),“2”=消极(如“好难啊[失望]”),“3”=客观(如“今天吃了饭”);
  2. 特征提取
    复用SVM的CountVectorizer(避免重新拟合,保证特征一致),把标注数据转成词频向量;
  3. 训练朴素贝叶斯模型
    用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)
    
  4. 情感预测
    对新的相关评论,预处理后转向量,用模型预测情感类别:
    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 优化步骤

  1. 初始化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
    )
    
  2. 训练优化模型
    用情感标注数据训练AdaBoost:
    ada_model.fit(X_train_nb, y_train_nb)
    
  3. 优化后预测
    用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优化后提升幅度
准确率(%)7886+8%
复杂情感准度(%)6582+17%
ROC曲线AUC0.810.92+0.11
  • 关键原因:AdaBoost对“又甜又虐”这类分类错的样本重点优化,多轮迭代后能捕捉到更细的情感特征。 在这里插入图片描述 在这里插入图片描述

四、毕业设计复盘:踩过的坑与经验

4.1 那些踩过的坑

  1. API调用失败:一开始没注意Token过期时间,爬取时突然报错——解决:在代码里加Token过期检测,到期前重新获取;
  2. 分词不准:结巴分词对网络流行词(如“yyds”)分错——解决:自定义词典,把“yyds”“绝绝子”加入词典,提高分词准确率;
  3. AdaBoost过拟合:迭代轮次设为100时,训练集准确率98%,测试集只有75%——解决:把n_estimators降到50,加正则化(如限制弱分类器复杂度)。

4.2 给学弟学妹的建议

  1. 数据标注要认真:情感分析的效果依赖标注质量,一开始随便标导致模型不准,后来重新标了500条才好转;
  2. 先跑通基础流程:不要一开始就上复杂算法,先实现“爬取→预处理→朴素贝叶斯”的基础流程,再逐步优化;
  3. 答辩突出对比效果:评委喜欢看“优化前后的差异”,比如展示SVM过滤前后的评论数量、AdaBoost准确率提升的曲线,比单纯讲公式更有说服力。

五、项目资源与后续扩展

5.1 项目核心资源

本项目包含完整的代码(爬取、预处理、模型训练)、标注数据集(1800条微博情感标签)、停用词表,可支持直接复现实验结果。若需获取这些资源,可私信沟通,还能提供模型调参和代码调试的指导。

5.2 未来扩展方向

  1. 细粒度情感分析:目前是三类分类,后续可细分“惊喜、愤怒、悲伤”等更细情感;
  2. 结合BERT预训练模型:用BERT做词嵌入,替代传统词频特征,进一步提升复杂情感的分类准度;
  3. 实时舆情监控:对接微博实时API,实时分析热点事件的情感趋势(如某演唱会的观众反馈)。

如果本文对你的自然语言处理、文本情感分析相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多算法落地的实战案例!