基于TF-IDF生成大学差异化词云的技术实现咨询
基于TF-IDF的大学评论差异化词云实现方案
问题背景
有存储大学谷歌评论的DataFrame,uni_name列记录大学名称。需要为每所大学单独生成词云,要求词的大小同时反映该校评论中的出现频率和在其他大学评论中的稀有度(即TF-IDF核心逻辑),以此获取不同大学的竞争洞察。
原代码的核心问题:循环内单独对单所大学的评论计算TF-IDF,导致IDF仅基于当前大学的单份文档计算,完全失去了“跨大学稀有度”的意义,等价于单纯用词频生成词云。
解决方案思路
要实现TF-IDF的正确加权,必须:
- 以所有大学的合并评论作为全局语料来拟合TF-IDF向量器,确保IDF值基于所有大学的文档数量计算(每个大学视为一个独立文档)
- 对每所大学的合并评论单独做TF-IDF转换,得到该大学专属的词权重
- 用转换后的TF-IDF权重生成词云
完整实现代码
import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer from wordcloud import WordCloud import matplotlib.pyplot as plt # 示例DataFrame df_unis = pd.DataFrame( {'review': ['this is a good school', 'this school was not worth it', 'aah', 'mediocre school with good profs'], 'uni_name': ['a', 'b', 'b', 'a']} ) # 1. 合并每所大学的所有评论,每个大学对应一份完整文档 corpus = df_unis.groupby('uni_name')['review'].sum() # 2. 基于全局所有大学的文档拟合TF-IDF向量器(关键:这里用整个corpus拟合,计算全局IDF) vectorizer = TfidfVectorizer(stop_words='english', ngram_range=(1, 3)) tfidf_matrix = vectorizer.fit_transform(corpus) feature_names = vectorizer.get_feature_names_out() # 转换为DataFrame,方便按大学提取权重 tfidf_df = pd.DataFrame(tfidf_matrix.todense(), index=corpus.index, columns=feature_names) # 3. 循环每所大学,生成TF-IDF加权的词云 for uni_name in tfidf_df.index: # 提取当前大学的有效词权重(过滤零权重词) word_weights = tfidf_df.loc[uni_name][tfidf_df.loc[uni_name] > 0].to_dict() # 生成词云 wordcloud = WordCloud( width=800, height=600, background_color='white', stopwords=vectorizer.get_stop_words() ).generate_from_frequencies(word_weights) # 显示词云 plt.figure(figsize=(10, 7)) plt.imshow(wordcloud, interpolation='bilinear') plt.title(f"TF-IDF Word Cloud for {uni_name}") plt.axis('off') plt.show()
关键细节说明
- 全局拟合TF-IDF:
vectorizer.fit_transform(corpus)用所有大学的文档拟合,IDF值计算为log(总大学数/包含该词的大学数),真正体现词在不同大学间的稀有度 - 按大学提取权重:
tfidf_df.loc[uni_name]直接获取该大学所有词的TF-IDF权重,无需重复拟合向量器 - 过滤零权重词:避免词云加载无意义的零权重词,提升生成效率和视觉效果
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

