第3章 社交媒体情绪挖掘:文本情感分析基础

好,咱们进入正题。社交媒体情绪挖掘,说白了就是从海量文本里把人的情绪「捞」出来。我刚开始做这个方向时,以为就是简单的「正面」「负面」二分类,后来发现——嗯,水很深。

你想想看,一条推文说「这股票涨得我心脏病要犯了」,到底是正面还是负面?情绪这东西,本身就带着语境和反讽。所以这一章,咱们把基础打牢。

3.1 文本情感分析的核心逻辑

情感分析本质上是个映射问题:把非结构化的文本,映射到情绪标签或情绪分数上。我个人习惯把它拆成三个层次:

  • 文档级:整篇文章是正面还是负面?适合新闻、研报。
  • 句子级:逐句判断情绪。适合短评、推文。
  • 方面级:针对某个实体(比如某只股票)的情绪。这是最难也最有用的。

我在项目中遇到过一个问题:某只股票明明财报很好,但社交媒体情绪却持续走低。后来发现,是用户都在吐槽它的客服。你看,方面级分析才能抓到这种细节。

核心观点:情绪挖掘不是为了判断「好」或「坏」,而是为了捕捉「变化」和「异常」。市场波动往往发生在情绪拐点,而不是情绪极值。

3.2 基于词典的方法:简单但有效

词典方法,就是预先准备一个情绪词库,然后数文本里正面词和负面词的数量。听起来很土?但我在实盘回测中发现,某些场景下它比深度学习还稳。

3.2.1 常用情绪词典

词典名称 语言 词条数 特点
LIWC 英文 ~6400 心理语言学分类,含情绪、认知、社会等维度
Harvard IV-4 英文 ~4200 通用情感词典,偏学术
知网Hownet 中文 ~9000 中文情感词+程度词,适合金融文本
NTUSD 中文 ~11000 台湾大学构建,正面/负面词各半

我建议你手头至少备两套词典:一套通用型,一套金融专用型。通用型抓大情绪,专用型抓行业黑话。比如「割肉」「踏空」这种词,通用词典根本认不出来。

3.2.2 词典方法的计算流程

流程其实很简单,但细节决定成败。我踩过的坑,都写在注释里了。

def sentiment_score(text, pos_dict, neg_dict, intensifier_dict):
    """
    基于词典的情感得分计算
    text: 输入文本
    pos_dict: 正面词集合
    neg_dict: 负面词集合
    intensifier_dict: 程度副词词典,如"非常"=1.5,"有点"=0.5
    """
    # 分词(中文用jieba,英文用nltk)
    words = segment(text)
    
    score = 0.0
    intensifier = 1.0  # 默认程度
    
    for i, word in enumerate(words):
        # 先检查程度词
        if word in intensifier_dict:
            intensifier = intensifier_dict[word]
            continue
        
        # 再检查情感词
        if word in pos_dict:
            score += 1.0 * intensifier
            intensifier = 1.0  # 重置
        elif word in neg_dict:
            score -= 1.0 * intensifier
            intensifier = 1.0
        else:
            # 检查否定词(比如"不"+"好")
            if i > 0 and words[i-1] in negation_words:
                score -= 1.0 * intensifier  # 反转极性
                intensifier = 1.0
    
    return score

我曾经踩过的坑:忘记处理否定词。一条「不看好」的文本,词典方法直接判成正面,因为「看好」是正面词。后来我加了个滑动窗口否定检测,准确率从62%直接跳到78%。

3.3 机器学习情感分类:从规则到统计

词典方法有个硬伤:它不认识新词。比如「yyds」「芭比Q了」这种网络梗,词典里根本没有。这时候就需要机器学习出马了。

3.3.1 特征工程:文本怎么变成数字

机器学习不吃文本,只吃数字。所以第一步是把文本向量化。我常用的方法有三种:

  • Bag of Words (BoW):统计每个词出现的次数。简单,但丢失了词序信息。
  • TF-IDF:不仅看词频,还看这个词在整个语料中的稀有度。能过滤掉「的」「了」这种无意义词。
  • Word2Vec / GloVe:词嵌入,把每个词映射到高维空间。能捕捉语义相似性。

我个人习惯在金融情感分析中用TF-IDF。为什么?因为金融文本里,稀有词往往携带更强的情绪信号。比如「暴雷」「熔断」这种词,出现一次就够你紧张半天了。

3.3.2 分类模型选型

别一上来就上BERT。我见过太多人拿大炮打蚊子。先试试这些:

模型 优点 缺点 适用场景
逻辑回归 可解释性强,训练快 无法处理非线性关系 基线模型,快速验证
朴素贝叶斯 对小样本友好 特征独立性假设太强 短文本(推文、标题)
XGBoost 精度高,能处理缺失值 容易过拟合 中等规模数据(万级)
LSTM 能捕捉上下文 训练慢,需要大量数据 长文本(研报、新闻)

我的经验:先用逻辑回归跑一遍,看特征权重。如果某个词权重异常高(比如「利好」权重0.8),说明数据有偏。这时候别急着调模型,先回去看数据标注质量。

3.3.3 完整训练流程

下面是一个完整的训练pipeline。注意,我刻意省略了超参数调优,因为那部分咱们后面章节会细讲。

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split

# 假设你已经有了标注好的数据
# X: 文本列表, y: 标签 (0=负面, 1=中性, 2=正面)

# 构建pipeline
pipeline = Pipeline([
    ('tfidf', TfidfVectorizer(
        max_features=5000,      # 限制特征数,防止过拟合
        ngram_range=(1, 2),     # 考虑单个词和双词组合
        stop_words='english'    # 去掉停用词
    )),
    ('clf', LogisticRegression(
        C=1.0,                  # 正则化强度
        class_weight='balanced' # 处理类别不平衡
    ))
])

# 训练
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
pipeline.fit(X_train, y_train)

# 评估
accuracy = pipeline.score(X_test, y_test)
print(f"测试集准确率: {accuracy:.3f}")

3.4 知识体系总览

说了这么多,咱们用一张图把整个逻辑串起来。这是我做课程时画的,你一看就明白。

社交媒体情绪挖掘知识体系 社交媒体文本 基于词典的方法 机器学习分类 情绪词典匹配 程度词/否定词 特征工程 模型训练 情绪得分 / 情绪标签 / 情绪时间序列 市场波动预测 / 交易信号生成

3.5 避坑指南与实战建议

最后,分享几个我这些年攒下来的经验。不一定全对,但至少能让你少走弯路。

关于数据标注:别迷信众包平台。我试过让五个人标注同一批金融文本,一致性只有60%。后来改成「金融背景+情绪标注」双人复核,一致性才提到85%。

关于词典更新:社交媒体词汇迭代极快。我建议每个月跑一次词频统计,把新出现的高频词手动加入词典。比如2023年的「遥遥领先」,2024年的「硬控」,你不加进去就漏信号。

关于过拟合:机器学习模型在训练集上准确率99%,一到实盘就崩。为什么?因为训练数据里的情绪表达方式,和实盘数据不一样。解决办法:用时间序列交叉验证,而不是随机划分。

好了,这一章的内容就到这。文本情感分析是情绪挖掘的「眼睛」,眼睛不好使,后面所有预测都是空中楼阁。下一章咱们会聊如何把情绪信号转化成交易策略——那才是真正见真章的地方。


公众号:蓝海资料掘金营,微信deep3321