舆情分析实战:如何用大连理工情感词典和K-means聚类,给微博评论自动打上情感标签并分组?

张开发
2026/4/17 15:14:23 15 分钟阅读

分享文章

舆情分析实战:如何用大连理工情感词典和K-means聚类,给微博评论自动打上情感标签并分组?
微博评论情感分析与群体划分实战从词典匹配到聚类优化在社交媒体时代海量用户评论中蕴含着丰富的情感倾向和观点差异。传统的人工标注方法难以应对大规模数据处理需求而基于情感词典与机器学习算法的自动化分析方案正成为企业舆情监控和用户洞察的利器。本文将手把手带你实现一套完整的微博评论分析流程从原始数据清洗到情感打分再到K-means聚类分组最后解读不同情感群体的特征。1. 环境准备与数据获取工欲善其事必先利其器。我们需要配置Python环境和安装必要的库。推荐使用Anaconda创建虚拟环境避免依赖冲突conda create -n sentiment_analysis python3.8 conda activate sentiment_analysis pip install jieba pandas numpy scikit-learn matplotlib seaborn微博数据获取通常有两种途径官方API和爬虫采集。对于中小规模分析可以使用微博开放平台的API需申请开发者权限。以下是使用requests获取最近7天气候变化话题评论的示例import requests url https://api.weibo.com/2/comments/show.json params { access_token: YOUR_ACCESS_TOKEN, id: 话题ID, count: 200, page: 1 } response requests.get(url, paramsparams) comments [item[text] for item in response.json()[comments]]注意实际应用中需处理分页和API调用频率限制大规模采集建议使用Scrapy等专业框架2. 数据预处理与情感词典应用原始微博数据通常包含大量噪声需要进行多步清洗去除无关内容过滤广告、特殊符号、URL链接等中文分词使用jieba分词并加载自定义词典提升专有名词识别停用词过滤去除的、了等无意义高频词import jieba import re def clean_text(text): # 去除HTML标签和URL text re.sub(r[^]|http\S, , text) # 保留中文和基本标点 text re.sub(r[^\w\s。、], , text) return text def tokenize(text, stopwords): words jieba.lcut(clean_text(text)) return [w for w in words if w not in stopwords]大连理工情感词典(NAU)包含超过27,000个情感词每个词标注了情感类别和强度。我们需要将其加载为结构化字典def load_emotion_dict(path): emotion_dict {} with open(path, r, encodingutf-8) as f: for line in f: word, emotion, intensity line.strip().split(\t) emotion_dict[word] (emotion, int(intensity)) return emotion_dict情感打分算法需要考虑词语的极性和强度加权。以下是一个简单的实现方案def sentiment_score(text, emotion_dict): positive_emotions {PA, PE} # 快乐、赞美 negative_emotions {NA, NB, NJ, NK, NL} # 愤怒、悲伤等 score 0 for word in text: if word in emotion_dict: emotion, intensity emotion_dict[word] if emotion in positive_emotions: score intensity elif emotion in negative_emotions: score - intensity return score3. 特征工程与K-means聚类单纯的情感得分还不足以区分用户群体我们需要构建更丰富的特征情感维度扩展将七类基础情绪的出现频次作为特征TF-IDF加权提取评论的关键词权重元特征评论长度、感叹号数量等from sklearn.feature_extraction.text import TfidfVectorizer # 情感特征 def build_emotion_features(texts, emotion_dict): features [] emotion_categories [PA, PE, PD, PH, PG, PB, PK] for text in texts: feature [0] * len(emotion_categories) for word in text: if word in emotion_dict: emotion, _ emotion_dict[word] if emotion in emotion_categories: idx emotion_categories.index(emotion) feature[idx] 1 features.append(feature) return np.array(features) # TF-IDF特征 tfidf TfidfVectorizer(max_features500) tfidf_features tfidf.fit_transform([ .join(text) for text in tokenized_texts])K-means聚类需要确定最佳簇数K。轮廓系数是常用评估指标值越接近1表示聚类效果越好from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score def find_optimal_k(features, max_k10): scores [] for k in range(2, max_k1): kmeans KMeans(n_clustersk, random_state42) labels kmeans.fit_predict(features) score silhouette_score(features, labels) scores.append(score) return np.argmax(scores) 2 # 返回最佳K值 optimal_k find_optimal_k(combined_features) kmeans KMeans(n_clustersoptimal_k, random_state42) clusters kmeans.fit_predict(combined_features)4. 结果分析与业务解读聚类完成后我们需要分析每个群体的特征。以下是一个典型的三类划分群体类型情感特征关键词分布占比典型评论愤怒问责派负面情绪主导(NA类)失职、抗议、问责28%景区管理明显存在漏洞必须严查责任人理性分析派中性偏负面原因、调查、制度45%建议从装备、培训和应急预案三方面改进同情支持派正面情绪(PA/PE类)致敬、辛苦、加油27%救援人员冒着危险工作大家多些理解可视化是呈现结果的有力工具。使用t-SNE降维后绘制散点图可以直观展示群体分布from sklearn.manifold import TSNE import matplotlib.pyplot as plt tsne TSNE(n_components2, random_state42) features_2d tsne.fit_transform(combined_features) plt.figure(figsize(10, 8)) for i in range(optimal_k): plt.scatter(features_2d[clustersi, 0], features_2d[clustersi, 1], labelfGroup {i}) plt.legend() plt.title(t-SNE Visualization of Comment Clusters) plt.show()在实际项目中我们发现几个关键改进点能显著提升分析效果领域词典扩充通用情感词典对专业术语识别有限需添加领域特定词汇上下文处理否定词(不)和程度副词(非常)会改变情感倾向需要特殊处理动态权重调整不同时期公众关注点变化需要定期更新特征权重# 上下文处理示例 def adjust_with_context(words, emotion_dict): adjusted_score 0 negation_words {不, 没, 无, 非} intensifiers {非常, 极其, 特别} for i, word in enumerate(words): if word in emotion_dict: emotion, intensity emotion_dict[word] # 检查前一个词是否为否定词 if i 0 and words[i-1] in negation_words: intensity -intensity # 检查前一个词是否为程度副词 elif i 0 and words[i-1] in intensifiers: intensity * 1.5 adjusted_score intensity return adjusted_score5. 进阶优化与生产部署当系统需要处理实时数据流时可以考虑以下架构优化增量学习使用MiniBatchKMeans替代标准K-means支持在线更新分布式计算对大规模数据采用Spark MLlib实现缓存机制缓存情感词典和模型参数减少重复计算from sklearn.cluster import MiniBatchKMeans # 增量聚类示例 mbk MiniBatchKMeans(n_clustersoptimal_k, random_state42) for batch in get_data_batches(): # 自定义批次获取函数 features extract_features(batch) mbk.partial_fit(features)模型效果评估不应仅依赖技术指标还需结合业务场景设计评估方案人工抽样验证随机抽取样本验证自动标注准确性A/B测试对比不同分组策略对后续操作的影响时间稳定性检查模型在不同时间段的表现一致性最后给出一个完整的Pipeline类实现封装主要处理逻辑class SentimentClusterPipeline: def __init__(self, emotion_dict_path): self.emotion_dict load_emotion_dict(emotion_dict_path) self.tfidf TfidfVectorizer(max_features500) self.kmeans None def process(self, texts): # 数据清洗和分词 cleaned [clean_text(t) for t in texts] tokenized [tokenize(t, stopwords) for t in cleaned] # 特征提取 emotion_features build_emotion_features(tokenized, self.emotion_dict) tfidf_features self.tfidf.fit_transform([ .join(t) for t in tokenized]) combined np.hstack([emotion_features, tfidf_features.toarray()]) # 聚类分析 if not self.kmeans: optimal_k find_optimal_k(combined) self.kmeans KMeans(n_clustersoptimal_k, random_state42) clusters self.kmeans.fit_predict(combined) return { texts: texts, tokens: tokenized, sentiments: [sentiment_score(t, self.emotion_dict) for t in tokenized], clusters: clusters }

更多文章