# douban_analysis **Repository Path**: shanluo852369/douban_analysis ## Basic Information - **Project Name**: douban_analysis - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-27 - **Last Updated**: 2026-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基于多源影视数据的评分预测、热度分类与聚类分析 > Python数据分析课程大作业 | 数据来源:豆瓣电影 --- ## 一、项目概述 本项目严格按照 **数据采集 → 数据清洗与预处理 → 数据挖掘 → 数据可视化** 四阶段流程完成。从豆瓣采集600部电影和约3万条评论数据,训练16个分析模型,生成19种可视化图表,并搭建11页Streamlit交互式Web展示页面。 **项目规模:** - 600部电影 + 30,275条评论 - 16个模型(4回归 + 6分类×2模式 + 2聚类 + 3情感 + 1异常检测) - 19种可视化图表 - 11页Streamlit Web展示页面 --- ## 二、运行方式 ```bash # 安装依赖 (Python 3.10, conda) pip install -r requirements.txt # Pipeline 1 — 数据采集 → data/raw/crawl_output/ python run_data.py # Pipeline 2 — 数据分析全流程(清洗→统计→可视化→模型训练) python run_pipeline.py # Web展示页面 streamlit run app.py ``` --- ## 三、项目架构 ``` code/ ├── app.py # Streamlit 11页Web展示 ├── run_data.py # Pipeline 1:数据采集入口 ├── run_pipeline.py # Pipeline 2:分析全流程入口 ├── src/ │ ├── config.py # 路径、MySQL、特征列配置 │ ├── crawlers/ # 爬虫模块 │ │ ├── douban_movie_crawler.py # 列表(JSON API) + 详情页(HTML) │ │ ├── douban_comment_crawler.py # 评论页(HTML) + 情感标注 │ │ └── real_movie_data_builder.py # 标准化输出 │ ├── data_processing/ │ │ ├── preprocess.py # 数据清洗与特征工程 │ │ └── statistics.py # 统计分析(分组/透视/相关性/时序) │ ├── models/ │ │ ├── regression.py # 4个回归模型 │ │ ├── classification.py # 6个分类模型 × 2种标签方案 │ │ ├── clustering.py # KMeans + 层次聚类 │ │ ├── sentiment_analysis.py # TF-IDF + 3个情感分类模型 │ │ └── anomaly_detection.py # Isolation Forest 异常检测 │ ├── visualization/ │ │ └── charts.py # 19种可视化图表 │ └── utils/ │ ├── io_utils.py # CSV/XLSX/JSON/SQLite/MySQL读写 │ ├── text_utils.py # 文本清洗、jieba分词 │ └── request_client.py # HTTP session、Cookie、限速 └── requirements.txt ``` --- ## 四、数据集说明 ### 数据概述 - **数据来源**:豆瓣电影 (douban.com) - **采集时间**:2025年(数据中最晚上映日期为2025年8月) - **采集方法**:Python爬虫,通过豆瓣JSON API和HTML页面解析获取 - **数据范围**:8个电影标签(剧情/喜剧/动作/爱情/科幻/悬疑/动画/纪录片),按热度排序取前20页×20条/页 - **数据量**:600部电影 + 30,275条评论 - **电影年份跨度**:1936年 - 2025年 - **评分范围**:3.2 - 9.7分(豆瓣10分制) - **制片地区**:涵盖中国大陆、美国、日本、韩国、英国、法国等15+个国家和地区 ### 数据存储 5种持久化存储方式:CSV、JSON、Excel、SQLite、MySQL。 ### movies.csv 字段说明(19个字段) | 字段名 | 含义 | 数据类型 | 非空率 | 示例 | |--------|------|----------|--------|------| | movie_id | 豆瓣电影唯一标识ID | str | 100% | 26752088 | | title | 电影标题 | str | 100% | 我不是药神 | | year | 上映年份 | float | 99.5% | 2018.0 | | region | 制片国家/地区 | str | 100% | 中国大陆 | | language | 对白语言 | str | 100% | 汉语普通话 | | genres | 电影类型(多值,"/"分隔) | str | 100% | 剧情/喜剧 | | duration | 电影时长(分钟) | float | 93.0% | 117.0 | | release_date | 上映日期 | str | 99.5% | 2018-07-05 | | douban_score | 豆瓣评分 | float | 100% | 9.0 | | vote_count | 评分人数 | float | 99.5% | 2348849.0 | | director | 导演 | str | 99.5% | 文牧野 | | actors | 主演 | str | 99.5% | 徐峥/王传君 | | summary | 电影简介 | str | 99.5% | 普通中年男子... | | tag_list | 所属标签 | str | 100% | 剧情/喜剧 | | cover | 封面图URL | str | 100% | https://img1.doubanio.com/... | | source_url | 详情页URL | str | 100% | https://movie.douban.com/subject/26752088/ | | playable | 是否可播放 | str | 0%(全空,已删除) | — | | is_new | 是否新片 | str | 0%(全空,已删除) | — | | source_site | 数据来源站点 | str | 99.5% | douban | ### comments.csv 字段说明(10个字段) | 字段名 | 含义 | 数据类型 | 非空率 | 示例 | |--------|------|----------|--------|------| | comment_id | 评论唯一ID | float | 99.99% | 32514679.0 | | movie_id | 所属电影ID | str | 100% | 1292052 | | user_name | 评论者昵称 | str | 99.94% | 影迷A | | comment_time | 已删除(数据无效) | — | — | — | | content | 评论正文 | str | 99.98% | 经典之作... | | likes | 点赞数 | int | 100% | 25713 | | rating_text | 评分文字 | str | 97.72% | 力荐 | | rating_value | 评分数值 | float | 97.65% | 5.0 | | sentiment_label | 情感标签 | str | 100% | positive | | source | 数据来源 | str | 100% | douban | > `comment_time` 列在清洗阶段删除,因为HTML中该位置存储的是地区信息而非时间(列错位)。 ### 情感标签映射 | rating_value | sentiment_label | 数量 | |--------------|-----------------|------| | 5(力荐)/ 4(推荐) | positive | 21,089 | | 3(还行) | neutral | 4,707 | | 2(较差)/ 1(很差) | negative | 3,769 | | 无评分 | unknown | 710 | --- ## 五、数据清洗(8分,全部完成) ### 5.1 缺失值处理 - 检测:对全部字段计算缺失率,用热力图可视化(绿<10%、黄10-30%、红>30%) - 填充策略:评分/时长用中位数(偏态分布更鲁棒),投票数填0,分类字段填"未知" - playable/is_new两列100%缺失,直接删除 ### 5.2 重复值处理 - 电影按movie_id去重:1072 → 600(同一部电影被多个标签页重复采集) - 评论按comment_id去重 - 均输出去重前后数量对比日志 ### 5.3 异常值检测与处理 - **三种检测方法**:业务规则(评分0-10、时长IQR范围)、Z-score(阈值3)、IQR箱线图 - **时长异常值处理**:用IQR上下限替换(q1-1.5×IQR ~ q3+1.5×IQR),而非简单clip(1,600) - 箱线图标注各字段IQR异常值数量 ### 5.4 数据标准化 - 日期格式统一(去除括号后缀如"2018-07-05(中国大陆)") - 数值类型修正(`pd.to_numeric`) - 评分范围裁剪(0-10)、字符串清洗、多值字段拆分 ### 5.5 特征工程 - **多表合并**:电影表与评论统计通过movie_id做left join - **独热编码**:region_group(9列)+ primary_genre(9列)= 18列 - **派生特征**:director_count、actor_count、summary_length、is_weekend_release --- ## 六、统计分析(全部完成) ### 6.1 描述性统计 - 对10个核心数值字段计算:均值、中位数、方差、标准差、分位数、偏度、峰度、极差 - 分类字段频数/频率统计(地区、类型、评分等级、语言) - 异常统计值自动标注:偏态明显(|偏度|>1)、尖峰分布(峰度>3)、方差异常(变异系数>1) **异常统计值原因分析:** | 字段 | 异常标注 | 原因 | |------|----------|------| | douban_score | 偏态明显(-1.12) | 豆瓣用户倾向给中高分评价,评分集中在6-9分,形成左偏分布 | | vote_count | 偏态(2.12)、尖峰(6.25)、方差异常 | 少数热门电影投票数极高(如肖申克的救赎328万票),方差远大于均值 | | duration | 偏态(13.99)、尖峰(225.02) | 少量超长电影(>1000分钟),绝大部分集中在90-130分钟 | | comment_count | 偏态(2.25)、尖峰(3.09)、方差异常 | 热门电影评论达400条上限,大量电影评论为0 | | year | 偏态(-2.41)、尖峰(10.50) | 数据以近年电影为主,早期老电影较少 | ### 6.2 分组/透视与交叉分析 - 分组统计5个维度:年份、类型、地区、语言、情感 - 透视表3张:年份×类型平均评分、地区×评分等级电影数、类型×热度交叉分析 ### 6.3 相关性分析 - Pearson + Spearman 两种相关系数矩阵 - 交互式热力图(支持切换) - 关键发现:投票数与评分正相关(0.47)、年份与评分负相关(-0.44)、投票数与评论数强正相关(0.75) - 散点图采用LOWESS非参数回归拟合(非OLS线性) ### 6.4 时间序列分析 - 3年移动平均平滑短期波动 - 环比增长率分析 - 线性趋势拟合(`np.polyfit`一阶多项式) - 未来3年外推预测(2026-2028) ### 6.5 分布分析 - 评分分布直方图 + KDE核密度曲线 - 正态拟合曲线对比 + QQ图验证 - 偏度/峰度计算与业务影响解读 ### 6.6 业务洞察(6个核心发现) 1. **评分呈左偏态** — 豆瓣收录门槛+用户正向选择偏差 2. **评论活跃度与评分非线性** — 争议性作品更容易引发讨论 3. **类型显著影响评分** — 纪录片最高,动作片相对较低 4. **国产与进口评分差异** — 受用户群体偏好和类型分布影响 5. **年度产量增长但质量趋稳** — 头部与尾部差距拉大 6. **异常数据归因** — 投票数异常=马太效应,时长异常=类型多样性 --- ## 七、模型分析 ### 7.1 回归预测(4个模型) 预测目标:豆瓣评分(douban_score) | 模型 | MAE | RMSE | R² | |------|-----|------|-----| | 线性回归 | 0.580 | 0.841 | 0.249 | | 岭回归(Ridge) | 0.610 | 0.819 | 0.288 | | **随机森林** | **0.444** | **0.595** | **0.624** | | 梯度提升 | 0.464 | 0.618 | 0.594 | **最优模型**:随机森林(R²=0.62)。特征重要性Top3:投票数(40%)、年份(21%)、地区(15.5%)。R²偏低说明仅靠客观特征预测评分有局限。 ### 7.2 分类预测(6个模型 × 2种标签方案) #### 模式1:热度分类(移除vote_count防数据泄露) | 模型 | Accuracy | F1 | AUC | |------|----------|-----|------| | **随机森林** | **0.850** | **0.903** | **0.914** | | 决策树 | 0.800 | 0.864 | 0.745 | | 逻辑回归 | 0.775 | 0.862 | 0.789 | | KNN | 0.767 | 0.850 | 0.661 | | SVM | 0.717 | 0.835 | 0.737 | | 朴素贝叶斯 | 0.592 | 0.648 | 0.761 | #### 模式2:评分等级分类(score_level ≥ 7.5为高分) | 模型 | Accuracy | F1 | AUC | |------|----------|-----|------| | **逻辑回归** | **0.733** | **0.733** | **0.754** | | 随机森林 | 0.650 | 0.638 | 0.788 | | 决策树 | 0.642 | 0.583 | 0.679 | | 朴素贝叶斯 | 0.617 | 0.378 | 0.774 | | SVM | 0.608 | 0.356 | 0.609 | | KNN | 0.517 | 0.453 | 0.561 | **关键发现**:模式1效果明显更好,说明热度可从其他特征预测;模式2更难,因为评分等级与特征的非线性关系更强。 ### 7.3 聚类分析(2个模型) - **KMeans + 层次聚类**,K=3(综合肘部法则+轮廓系数+业务可解释性) - Winsorize预处理(1%-99%分位数截断)防止极端值主导 - 三个群体:经典老片(311部)、超热门经典(76部)、近年热门(213部) - 可视化:PCA散点图、聚类特征热力图、层次聚类树状图(dendrogram)、肘部法则图 ### 7.4 情感分析(3个模型) - jieba中文分词 + TF-IDF特征提取(max_features=5000) - 三分类:positive / neutral / negative | 模型 | 准确率 | F1 | |------|--------|-----| | 朴素贝叶斯 | 71.9% | 0.615 | | 逻辑回归 | 71.9% | 0.617 | | LinearSVC | 70.9% | 0.635 | - 支持实时情感预测(输入文本 → jieba分词 → TF-IDF → 预测) ### 7.5 异常检测(Isolation Forest) - contamination=0.05, n_estimators=200 - 检测出约30部异常电影(评分或投票数远超平均水平) - 每部异常电影输出偏离最大的3个特征 --- ## 八、可视化图表(19种) ### 基础图表(4种) 1. 折线图 — 历年电影数量趋势 2. 柱状图 — 各类型电影数量 3. 饼图 — 影视类型占比 4. 散点图 — 评分人数与豆瓣评分 ### 分析型可视化(12种) 5. 缺失值分布热力图 6. 异常值检测箱线图 7. 相关系数热力图(Pearson/Spearman) 8. 地区与类型平均评分热力图 9. 地区评分箱线图 10. 评分分布直方图 + KDE 11. 评分分布分析 + QQ图 12. 电影类型多维度雷达图 13. 评论文本词云图 14. 时间序列趋势分析图 15. 聚类群体特征热力图 16. 层次聚类树状图 ### 模型图表(3种) 17. ROC曲线对比图(6模型) 18. 混淆矩阵(6模型) 19. 肘部法则图(SSE + 轮廓系数) ### 技术栈 - **交互式图表**:Plotly Express / Graph Objects(条形图、饼图、散点图、热力图、折线图) - **静态图表**:Matplotlib + Seaborn(直方图、箱线图、雷达图、词云、ROC等) - **前端框架**:Streamlit(11页Web展示) - **数据处理**:Pandas + NumPy - **统计分析**:SciPy(正态拟合、QQ图) - **机器学习**:Scikit-learn(回归/分类/聚类/异常检测/PCA) - **文本处理**:jieba + wordcloud --- ## 九、综合结论 ### 5个核心发现 1. **评分预测能力有限** — 最优R²仅0.62,评分受主观因素影响大 2. **热度与评分是两个独立维度** — 两种分类模式对比揭示了数据泄露问题 3. **电影市场呈长尾分布** — 13%超热门经典占据绝大部分用户关注度 4. **评论情感可有效自动识别** — 准确率70%+,可用于实时监控 5. **经典老片评分普遍高于新片** — 年份与评分负相关(-0.44) ### 4条实践建议 1. **电影制作方**:关注口碑质量,评分与正面评论比例强相关 2. **平台方**:利用聚类+情感分析做差异化推荐 3. **观众**:高评分不一定适合所有人,结合类型偏好选片 4. **分析师**:评分预测需引入更多特征(导演历史评分、演员号召力等) --- ## 十、演示指南 运行 `streamlit run code/app.py` 后,11个页面依次展示: | 页面 | 内容 | 对应评分点 | |------|------|-----------| | 数据概览 | 数据量指标、表格预览 | 数据采集A | | 数据清洗 | 5个标签页:缺失值/重复值/异常值/标准化/特征工程 | 数据清洗B | | 统计分析 | 5个标签页:分组统计/描述统计/分布分析/透视表/业务洞察 | 统计分析C + 分组A + 分布E + 洞察D | | 相关性分析 | 热力图 + 散点图 | 相关性B | | 时间序列 | 趋势+预测+环比 | 时序分析C | | 回归预测 | 4模型对比 + 特征重要性 | 回归F | | 分类预测 | 6模型×2模式 + ROC + 混淆矩阵 | 分类G | | 聚类分析 | PCA散点图 + 热力图 + 树状图 + 肘部法则 | 聚类H | | 可视化图表 | 19种图表画廊 | 可视化D | | 情感分析/异常检测 | 模型对比 + 实时预测 + 异常电影 | 创新B | | 综合结论 | 5发现 + 4建议 + 图表支撑 | 创新C | **互动演示亮点**:情感分析实时预测 — 输入任意评论文本,自动分词→向量化→预测情感倾向和概率分布。 --- ## 十一、评分点完成情况 | 评分项 | 满分 | 状态 | |--------|------|------| | 1.1.A 爬虫(2个以上) | 2 | ✅ | | 1.1.B 数据持久化存储 | 2 | ✅ CSV/JSON/XLSX/SQLite/MySQL | | 1.1.C 数据说明文档 | 1 | ✅ | | 1.2.B.a 缺失值处理 | 2 | ✅ 热力图+多种填充策略 | | 1.2.B.b 重复值处理 | 1 | ✅ 去重前后对比 | | 1.2.B.c 异常值处理 | 2 | ✅ IQR/Z-score/箱线图 | | 1.2.B.d 数据标准化 | 1 | ✅ | | 1.2.B.e 特征处理 | 2 | ✅ 18列one-hot+4个派生特征 | | 1.2.C 统计分析 | 3 | ✅ 描述统计+异常标注 | | 1.2.D 数据可视化 | 4 | ✅ 4基础+12分析型 | | 1.3.A 分组/透视/交叉 | 2 | ✅ 5维度+3张透视表 | | 1.3.B 相关性分析 | 2 | ✅ Pearson/Spearman+热力图 | | 1.3.C 时间序列 | 2 | ✅ 移动平均+趋势+预测 | | 1.3.D 业务洞察 | 2 | ✅ 6个洞察+归因 | | 1.3.E 分布分析 | 2 | ✅ 直方图+QQ图+偏度峰度 | | 1.3.F 回归模型 | 3 | ✅ 4个模型+评估对比 | | 1.3.G 分类模型 | 4 | ✅ 6模型×2模式+ROC+混淆矩阵 | | 1.3.H 聚类模型 | 3 | ✅ KMeans+层次聚类+可视化 | | 创新A Web展示 | 2 | ✅ Streamlit 11页 | | 创新B 更多分析方法 | 4 | ✅ 情感分析+异常检测+时序预测 | | 创新C 整合结论 | 4 | ✅ 5发现+4建议 |