ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

豆瓣电影评论数据分析实战:从爬虫到词云与机器学习全流程

豆瓣电影评论数据分析实战:从爬虫到词云与机器学习全流程 简介这份资源是围绕豆瓣电影数据展开的Python与机器学习实战项目包面向计算机、人工智能、大数据、数学、电子信息等专业的学生以及正在准备课程设计、期末大作业或毕业设计的技术学习者。项目以真实影评数据为对象串联数据清洗、文本预处理、特征提取与机器学习建模等环节帮助读者理解从原始数据到分析结论的完整流程。压缩包共16个文件约28.18MB包含py源码、html作业页面、pdf实验报告、md说明文档以及txt词表与数据文件、jpg可视化图片和rar影评数据包覆盖代码、报告与图表三类成果。目前已有351人学习下载。读者可获得可运行的完整源码与配套实验报告借助停用词表、词云图和评论数据复现分析过程并参考README与作业文档梳理项目结构适合作为机器学习入门练手与课程作业参考。1. 豆瓣电影数据分析源码包从评论到词云的完整链路豆瓣电影评论是个很讨巧的数据分析对象——数据量适中、文本情感丰富、评分体系清晰特别适合拿来做课程设计或期末大作业。但很多人卡在第一步数据从哪来爬虫写完被封了怎么办词云跑出来全是的了吗这种无意义词怎么办这份资源包给了一条完整的链路从原始评论数据2018豆瓣电影评论.rar到停用词表cn_stopwords.txt、词频统计high.txt / low.txt、词云图ciyun.jpg、机器学习建模代码作业代码.py再到实验报告实验报告.pdf基本覆盖了数据采集→清洗→分析→可视化→建模→写报告的全流程。适合正在做课程设计、期末大作业的计算机相关专业学生也适合想拿一个完整案例练手 Python 数据分析的从业者。前提是你得有一定基础至少能看懂 Pandas 和 Sklearn 的基本操作。2. 环境搭建与数据加载把评论数据跑起来2.1 依赖安装与版本选择拿到源码包第一件事不是急着跑代码而是先把环境对齐。这份代码涉及的核心库包括 pandas、numpy、jieba、wordcloud、matplotlib、scikit-learn另外可能用到 re 和 collections 做文本预处理。我一般建议用 Python 3.8 到 3.10 之间的版本太新的版本比如 3.12在某些老库上容易翻车尤其是 wordcloud 对 C 编译环境有依赖。# 创建虚拟环境避免污染全局 python -m venv douban_env source douban_env/bin/activate # Windows 用 douban_env\Scripts\activate # 安装核心依赖 pip install pandas numpy jieba wordcloud matplotlib scikit-learn这里有个血泪经验wordcloud 在 Windows 上安装经常报错提示缺少 Microsoft Visual C 14.0。解决办法是去装一个 Visual Studio Build Tools或者直接用 conda 安装conda install -c conda-forge wordcloud。别在这卡太久环境问题不值得消耗太多精力。2.2 数据加载与初步探查资源包里的2018豆瓣电影评论.rar需要先解压解压后通常是 txt 或 csv 格式。加载之前先确认编码格式豆瓣评论数据常见的是 UTF-8 或 GBK用错编码会直接报 UnicodeDecodeError。import pandas as pd # 尝试 UTF-8 加载失败则切换 GBK try: df pd.read_csv(2018豆瓣电影评论.csv, encodingutf-8) except UnicodeDecodeError: df pd.read_csv(2018豆瓣电影评论.csv, encodinggbk) # 初步探查看数据规模、字段类型、缺失情况 print(df.shape) # 行数和列数 print(df.columns.tolist()) # 字段名 print(df.head(10)) # 前10行 print(df.isnull().sum()) # 每列缺失值数量逻辑说明先试 UTF-8 再降级到 GBK 是处理中文数据的常规操作。df.shape让你知道数据量级如果只有几十条评论那分析结论的统计意义就很有限。isnull().sum()帮你判断是否需要做缺失值处理——如果评论内容列有大量空值后面的分词和词云都会受影响。参数方面pd.read_csv的sep参数默认是逗号如果你的数据是制表符分隔的需要改成sep\t。另外如果数据里有中文列名建议先重命名为英文避免后续代码里混用中英文变量名导致调试困难。3. 文本预处理与词云生成从原始评论到可视化3.1 中文分词与停用词过滤中文文本分析绕不开分词这一步。jieba 是绕不开的选择精度够用、上手快。但分词之后你会发现高频词全是电影好看演员这类词——不是它们不重要而是它们对区分度贡献太低。这时候停用词表就派上用场了。import jieba import re from collections import Counter # 加载停用词表 def load_stopwords(filepath): with open(filepath, r, encodingutf-8) as f: return set(line.strip() for line in f if line.strip()) stopwords load_stopwords(cn_stopwords.txt) # 分词 清洗 def segment_text(text): # 去掉标点、数字、英文 text re.sub(r[^\u4e00-\u9fa5], , str(text)) words jieba.lcut(text) # 过滤停用词和单字 return [w for w in words if w not in stopwords and len(w) 1] # 对所有评论分词 all_words [] for comment in df[comment].dropna(): all_words.extend(segment_text(comment)) # 统计词频 word_freq Counter(all_words) print(word_freq.most_common(30))逻辑说明re.sub(r[^\u4e00-\u9fa5], , text)这行正则只保留中文字符把标点、数字、英文全部剔除。len(w) 1过滤掉单字因为单字在中文里歧义太大。Counter做词频统计比手动循环高效得多。参数调整jieba.lcut可以用cut_allFalse精确模式默认也可以用cut_allTrue全模式。精确模式更适合情感分析全模式适合做词库扩展。停用词表cn_stopwords.txt是通用表如果你发现某些领域词比如豆瓣本身高频出现但无意义可以手动追加进去。3.2 词云图生成与参数调优词云图是这份资源里最直观的输出ciyun.jpg 就是成品。但很多人跑出来的词云要么糊成一团要么字体显示成方块——前者是参数没调好后者是没指定中文字体路径。from wordcloud import WordCloud import matplotlib.pyplot as plt # 中文字体路径Windows 和 Mac 不一样 font_path C:/Windows/Fonts/simhei.ttf # Windows # font_path /System/Library/Fonts/PingFang.ttc # Mac wc WordCloud( font_pathfont_path, width1200, height800, background_colorwhite, max_words150, max_font_size200, colormapviridis, random_state42 ) wc.generate_from_frequencies(word_freq) plt.figure(figsize(12, 8)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.savefig(ciyun_output.png, dpi200, bbox_inchestight) plt.show()逻辑说明generate_from_frequencies直接接收词频字典比传原始文本更可控。max_words150控制显示词数太多会挤在一起。random_state42保证每次生成的布局一致方便调试。参数方面colormap决定配色方案viridis 偏冷色Reds 偏暖色看你的报告风格选。max_font_size200是最大字号如果词云图分辨率高可以适当调大。background_color建议用白色方便插入报告。注意如果你用的是 Mac字体路径要改成/System/Library/Fonts/PingFang.ttc或/Library/Fonts/Arial Unicode.ttf否则中文会显示成方块。4. 机器学习建模与报告撰写从特征到结论4.1 特征工程与模型选择资源包里的作业代码.py和作业代码.html应该包含了机器学习建模部分。豆瓣电影评论的机器学习任务通常是两类一是情感分类好评/差评二是评分预测回归。从资源包的文件结构看更可能是情感分类。from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report, accuracy_score # 假设 df 有 comment 和 label 两列label 为 0/1 X df[comment].fillna() y df[label] # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) # TF-IDF 向量化 tfidf TfidfVectorizer( max_features5000, ngram_range(1, 2), min_df3, max_df0.8 ) X_train_tfidf tfidf.fit_transform(X_train) X_test_tfidf tfidf.transform(X_test) # 逻辑回归建模 clf LogisticRegression(max_iter1000, C1.0) clf.fit(X_train_tfidf, y_train) # 预测与评估 y_pred clf.predict(X_test_tfidf) print(accuracy_score(y_test, y_pred)) print(classification_report(y_test, y_pred))逻辑说明stratifyy保证训练集和测试集的类别比例一致避免某类样本过少导致评估失真。TF-IDF 的ngram_range(1, 2)同时考虑单字和双字词组能捕捉不好看这种否定搭配。min_df3过滤掉出现次数少于 3 次的词降低噪声。参数调整max_features5000控制特征维度太大容易过拟合太小会丢失信息。C1.0是正则化强度的倒数C 越小正则化越强。如果准确率不理想可以试试朴素贝叶斯MultinomialNB或 SVMLinearSVC在小数据集上往往表现更稳。4.2 实验报告的结构与数据呈现实验报告.pdf是这份资源的加分项。很多人代码跑通了但报告写不好白白丢分。一份合格的数据分析实验报告通常包含实验目的、数据来源与描述、方法论述、实验结果、结论与反思。重点在实验结果部分——不要只贴一张词云图就完事要有数据支撑。报告章节建议内容常见扣分点数据描述样本量、字段说明、缺失值处理只写数据来自豆瓣方法论述分词工具、停用词表、模型选择理由堆砌名词无解释实验结果词频Top20表格、词云图、模型评估指标只有图没有数据结论结合业务场景解读空泛套话表格里的常见扣分点是我批改过几十份报告总结出来的。数据描述部分至少要写清楚样本量比如共采集 5000 条评论和字段含义。方法论述要解释为什么选 jieba 而不是 HanLP为什么用 TF-IDF 而不是 Word2Vec。实验结果部分词频统计最好用表格列出 Top20 并标注频次模型评估要有准确率、精确率、召回率、F1 值四个指标。5. 避坑与排查那些让你卡半天的细节5.1 编码报错与路径问题现象运行代码时报UnicodeDecodeError: utf-8 codec cant decode byte...原因原始数据文件不是 UTF-8 编码可能是 GBK 或 GB2312。解决用chardet检测编码或者直接尝试encodinggbk。如果还不行用 Notepad 打开文件查看实际编码格式。现象FileNotFoundError: [Errno 2] No such file or directory: cn_stopwords.txt原因代码里的文件路径是相对路径但你的工作目录和代码文件不在同一层。解决用os.path.dirname(__file__)获取代码文件所在目录再拼接文件路径。或者直接在 IDE 里设置工作目录。5.2 词云中文显示为方块现象词云图生成成功但所有中文都显示成方块或乱码。原因WordCloud 默认字体不支持中文必须手动指定中文字体路径。解决找到系统中的中文字体文件Windows 一般在C:/Windows/Fonts/Mac 在/System/Library/Fonts/把font_path参数指向它。推荐用simhei.ttf黑体或msyh.ttf微软雅黑。5.3 模型准确率异常高或异常低现象逻辑回归准确率 99%或者只有 50% 左右。原因99% 通常是数据泄漏——比如标签信息混入了特征列50% 通常是特征工程没做好或者标签本身不平衡。解决检查X和y是否来自同一列确保特征里不包含标签信息。如果类别不平衡用class_weightbalanced或做重采样。5.4 jieba 分词结果不符合预期现象分词后出现电影很好看被切成电影很好看没问题但豆瓣评分被切成豆瓣评分而不是豆瓣评分。原因jieba 默认词典不包含你的领域专有名词。解决用jieba.add_word(豆瓣评分)手动添加自定义词或者加载自定义词典jieba.load_userdict(user_dict.txt)。5.5 报告里图表模糊不清现象词云图插入 PDF 后模糊或者 matplotlib 生成的图表分辨率太低。原因默认 DPI 只有 100打印或放大后失真。解决保存时指定dpi200或更高bbox_inchestight去掉多余白边。如果是截图插入报告确保截图工具不压缩画质。6. 进阶技巧把这份源码改成你自己的项目这份资源包最大的价值不是代码本身而是它提供了一条可复用的分析链路。你完全可以在它的基础上做二次开发让项目更有个人特色。比如把情感分类从二分类改成三分类好评/中评/差评或者把词云换成 LDA 主题模型看看评论里到底有哪几个讨论维度。from sklearn.decomposition import LatentDirichletAllocation from sklearn.feature_extraction.text import CountVectorizer # 用 CountVectorizer 做词频矩阵LDA 不需要 TF-IDF cv CountVectorizer(max_features3000, max_df0.8, min_df3) X_cv cv.fit_transform(df[comment].fillna()) # LDA 主题模型假设有 5 个主题 lda LatentDirichletAllocation(n_components5, random_state42, max_iter20) lda.fit(X_cv) # 输出每个主题的关键词 feature_names cv.get_feature_names_out() for topic_idx, topic in enumerate(lda.components_): top_words [feature_names[i] for i in topic.argsort()[:-11:-1]] print(f主题 {topic_idx 1}: { .join(top_words)})逻辑说明LDA 是一种无监督主题模型不需要标签就能发现评论中的潜在话题。n_components5表示假设有 5 个主题这个数字需要根据实际数据调整——太少会混淆主题太多会碎片化。max_iter20控制迭代次数一般 10 到 50 之间。参数调整max_features3000控制词表大小太大跑得慢太小主题不清晰。max_df0.8过滤掉出现在 80% 以上文档中的词这些词通常是电影好看这类通用词。min_df3过滤低频词。跑完 LDA 后你可以把每个主题的关键词做成表格放进报告比单纯词云更有分析深度。另一个进阶方向是加爬虫模块。资源包里已经有 2018 年的评论数据但如果你想做更新的数据可以自己写一个采集脚本。不过要注意采集频率别太高加个time.sleep(2)控制节奏否则容易被封 IP。采集到的数据存成 CSV后续流程和这份资源完全兼容。还有一个容易被忽略的点模型评估不能只看准确率。如果好评占 90%你全预测好评也有 90% 准确率但模型其实什么都没学到。这时候要看 F1 值和混淆矩阵。我一般会在报告里同时放准确率和 F1 值如果两者差距大就说明类别不平衡问题严重需要做重采样或调整类别权重。从那以后我每次拿到新的文本数据集都强制先跑一遍df[label].value_counts()看类别分布再决定用什么评估指标。这个习惯帮我省了很多返工时间。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进