文章目录

  • 一、运行环境
  • 二、实战介绍
  • 三、获取数据
  • 四、PyMongo 实战
    • 4.1 连接MongoDB、创建集合
    • 4.2 向 MongoDB 插入文档
    • 4.3 查询MongoDB的数据
    • 4.4 同样的操作插入影评
    • 4.5 插入影评信息到MongoDB
  • 五、基于 PyMongo的数据分析
    • 5.1 计算豆瓣 Top 10 影视的平均评分
    • 5.2 统计Top10电影影评的[赞同 / 不赞同]的平均比率
    • 5.3 统计Top10电影从2021年到今日的评论情况

Gitee 仓库地址: https://gitee.com/ccuni/pymongo-douban-comment-analysis

一、运行环境


  • Windows10
  • python 3.9
  • Anaconda3 + jupyter
  • mongodb 5.0.6
  • PyMongo 3.5.1
  • wordcloud-1.8.1

anaconda 安装 wordcloud的命令

conda install -c conda-forge wordcloud

二、实战介绍


数据来源基于Python的第三方库,即requests库bs4库re库爬取豆瓣网TOP10的电影信息,以及它们的部分影评信息(100个左右)。

将爬取的信息进行预处理,封装成dict字典,借助 pymongo库 连接本机的 MongoDB,向数据库插入之前爬取的真实数据,然后分别使用MongoDB提供的map_reduce机制以及agreegate机制来聚合、分组、汇总计算数据,以MongoDB为基础,存储影视信息和评论信息,同时分析电影的综合价值。

三、获取数据


这一部分可参考Gitee仓库:https://gitee.com/ccuni/pymongo-douban-comment-analysis

四、PyMongo 实战


4.1 连接MongoDB、创建集合

from pymongo import MongoClient
from random import randint
client = MongoClient('localhost', 27017)db = client.mv
# 创建电影信息集合
ct_mv_info = db.dc_mv_info
# 创建影评集合
ct_mv_review = db.dc_mv_review# 查看创建结果
ct_mv_review

4.2 向 MongoDB 插入文档

这里先将DataFrame的影视信息转化为dict字典格式

dc_mv = []
index = 0
for x in mv_data.values.tolist():dict_info = {}# 指定文档的_id为电影IDdict_info['_id'] = mv_data['mv_id'][index]index += 1# i 用于循环遍历取DF列表数据i = 0for key, v in mv_data.items():dict_info[key] = x[i]i += 1# 指定文档的dc_mv.append(dict_info)
dc_mv

# 插入前 先清空
ct_mv_info.delete_many({})
# 插入文档
ct_mv_info.insert_many(dc_mv)

4.3 查询MongoDB的数据

ct_mv_info.find_one()

4.4 同样的操作插入影评

先处理信息,将原先的DataFrame的影评信息转化为可插入到MongoDB的dict字典

# list_mv[1] 输出结果 dict_keys(['reviews', 'star'])
# 查询保存的列表数据
# for x in list_mv[1].values.to_list():
#     print(x)
'''根据之前的存储信息获取所有电影的影评, 封装成可插入MongoDB的 dict
'''
def getAllReviews() -> list[list]:index = 0reviews = []for i in range(len(list_mv)):# 获取每一列rv_cols = list_mv[0]['reviews'].columns# 表示当前的评论标号i = 0# 记录当前电影的所有影评信息dc_reviews = []for k, rows in list_mv[index]['reviews'].iterrows():# 根据电影ID和当前的评论序号定义_iddict_info = {'_id' : mv_data['mv_id'][index] + str(i)}i += 1for col in rv_cols:dict_info[col] = rows[col]dc_reviews.append(dict_info)index += 1reviews.append(dc_reviews)return reviews# 获取Top10电影的爬取到的所有影评
dc_reviews = getAllReviews()
count = 0
for i in range(len(dc_reviews)):count += len(dc_reviews[i])
print(f'[INFO] >> 共获取到 {len(dc_reviews)} 个电影 {count} 个的影评')print(f'[INFO] >> 查看其中的一个影评: {dc_reviews[0][:1]}')

处理结果:

4.5 插入影评信息到MongoDB

ct_mv_review.delete_many({})
for rv in dc_reviews:ct_mv_review.insert_many(rv)
# 查看插入结果
ct_mv_review.find_one()

五、基于 PyMongo的数据分析


5.1 计算豆瓣 Top 10 影视的平均评分

ct_mv_info.find_one()

from bson.code import Codemapper = Code("""function(){emit('', {count:1, mv_star: eval(this.mv_star)});}
""")
reducer = Code("""function(k, v) {reducedVal = {count: 0, mv_star: 0};for (var idx = 0; idx < v.length; idx++) {reducedVal.count += v[idx].count;reducedVal.mv_star += v[idx].mv_star;}return reducedVal;};
""")finalizer = Code("""reducedVal.mv_star_avg = reducedVal.mv_star/reducedVal.count;return reducedVal;
""")
res = ct_mv_info.map_reduce(map = mapper,reduce=reducer,out='mv_star_avg', finalize = finalizer)
res

ct_mv_star_avg = db.mv_star_avg
for x in ct_mv_star_avg.find():print(x)


根据结果得出,10部电影里的平均评分为9.5分,还是处于相当高的水平,当然这个案例并没有实际意义,主要是为了熟悉MongoDB的MapReduce的基本使用

5.2 统计Top10电影影评的[赞同 / 不赞同]的平均比率

ct_mv_review.find_one()

from bson.code import Codemapper = Code("""function(){var a = eval(this.rv_action_agree);var b = eval(this.rv_action_disagree);var rate = 0;if(a > 0 && b > 0){rate = b / (a + b);emit(this.rv_mv_id, {count: 1, rate: rate});} }
""")
reducer = Code("""function(k, v) {reducedVal = {count: 0, rate: 0};for (var i = 0; i < v.length; i++) {reducedVal.count += v[i].count;reducedVal.rate += v[i].rate;}return reducedVal;};
""")finalizer = Code("""reducedVal.rate = reducedVal.rate/reducedVal.count;return reducedVal;
""")
res = ct_mv_review.map_reduce(map = mapper,reduce=reducer,out='mv_agree_divide_disagree_rate', finalize = finalizer)
res

ct_mv_agree_divide_disagree_rate = db.mv_agree_divide_disagree_rate# 查询mongodb文档数据并持久化
temp1 = []
for x in ct_mv_agree_divide_disagree_rate.find():print(x)temp1.append(x)
len(temp1)

# 准备电影ID到电影名的映射字典
dict_rv_name = {}
for mv in ct_mv_info.find():dict_rv_name[mv['mv_id']] = mv['mv_name']
# 条件查询, 根据电影 ID 获取到对应的电影名
for i in range(len(temp1)):id = temp1[i]['_id']name = ''for x in ct_mv_info.find({'_id': id}):name = x['mv_name']temp1[i]['mv_name'] = name
temp1


可视化

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'# 柱形的宽度
bar_width = 0.6
plt.xticks(rotation=35)
x1 = [x['mv_name'] for x in temp1]y1 = [x['value']['rate'] for x in temp1]
# 绘制柱形图
plt.bar(x=x1, height=y1, width=bar_width, color=['skyblue', 'pink'],linewidth=1.5,)# 26 # 为每个条形图添加数值标签
for x,y in enumerate(y1):plt.text(x,y+0.003,'%.3f' % y,ha='center')
plt.xlabel('电影名称',fontsize=14, color='blue')
plt.ylabel('评论分歧(反对)平均占比',fontsize=14, color='red')
plt.title('豆瓣Top10影视评论分歧占比统计图',fontsize=15, color='green')
plt.show()


分析过程:

通过PyMongoDB的MapReduce过程,最终得出的豆瓣Top10部分影评分歧占比统计图如上图所示。

  1. 从整体来看,Top10影视的评论分歧都相对较低,处于[6.1%, 11.1%] 范围。

  2. 其中占比最多电影的为《盗梦空间》,分歧率为 11.1% ,这意味着有100人评论,那么就有将近11人的观点不被赞同,这跟电影的题材、类型、剧情、演员等多个因素都有关。

  3. 占比最少的为《千与千寻》,仅为 6.1%,这说明观众们的观点大多是一致的,100人里面只有6人左右的观点不一致。

综上,对于Top10的电影,除了评分、观看数等指标,评论分歧率直观体现了影视的影响力,这意味着观众可以选择这个分歧率较小的电影作为参考,达到更好的观看体验,同时对于同行,能更放心地借鉴其中的一些高深的拍摄手法、剧情演绎方法等。

5.3 统计Top10电影从2021年到今日的评论情况

ct_mv_review.find_one()

for x in ct_mv_review.aggregate([{'$group': {'_id':'$rv_mv_id', 'counter':{'$sum':1}}}]):print(x)

from datetime import datetimelist_rv= []
year, month, day = 2021,1,1
for x in ct_mv_review.aggregate([{# 转化类型'$project':{'rv_time': '$rv_time','rv_info': '$rv_info','rv_name': '$rv_name','rv_time_stand': {'$convert':{'input':'$rv_time','to': 'date','onNull': 'missing rv_time'}},},},{'$match': {'rv_time_stand':{'$gte': datetime(year,month,day)},}}, ]):list_rv.append(x)dict_rv_info = {}
'''处理 MongoDB 聚合后的结果 汇总评论
'''
for rv in list_rv:# 前 7 位是电影的IDmv_id = rv['_id'][:7]dict_rv_info[dict_rv_name[mv_id]] = {}dict_rv_info[dict_rv_name[mv_id]][rv['rv_name']] = {'rv_time': rv['rv_time'],'rv_info': rv['rv_info']}
print(f'[INFO] >> 已统计完 [{len(dict_rv_info)}] 个电影在{year}年{month}月{day}后的影评')'''词频统计
'''
import jieba
from wordcloud import WordCloud
# 不需要统计的词汇
nope = ['电影', '没有', '一个', '之后', '这部']
for k, v in dict_rv_info.items():dict_word_count = {}# 遍历每个用户的评论for review in v.values():# 遍历每个词for x in jieba.cut(review['rv_info']):if(len(x) >= 2) and x not in nope:dict_word_count.setdefault(x, 0)dict_word_count[x] = dict_word_count[x] + 1#生成词云 保存到本地t = WordCloud(width=600, height=480,  # 图片大小background_color='white',  # 背景颜色scale=10,font_path=r'c:\windows\fonts\simfang.ttf' ).generate_from_frequencies(dict_word_count)save_path = './count_images/' + k + '.jpg't.to_file(save_path)print(f'[INFO] >> 电影[{k}] 评论的词频统计词云生成完毕, 保存位置在[{save_path}]')
# print(dict_word_count)


评论词云的结果如下图所示:

美丽人生:

辛德勒的名单

这里展示了两部电影的评论词云,而且是在21年1月份以后的评论,在MongoDB的强大支持下,检索某个日期里的文档数据十分遍历,通过这样的方式,我们能感受到电影从去年到现在的影响力。

MongoDB 实战(一)基于PyMongo的电影影评分析 | 对数据结果进行可视化展示以及分析 | 评论词云 | 分时间段分析相关推荐

  1. Spark商业案例与性能调优实战100课》第20课:大数据性能调优的本质和Spark性能调优要点分析

    Spark商业案例与性能调优实战100课>第20课:大数据性能调优的本质和Spark性能调优要点分析 基于本元想办法,大智若愚,大巧若拙!深入彻底的学习spark技术内核!

  2. 《大数据存储:MongoDB实战指南》一1.1 什么是大数据

    本节书摘来异步社区<大数据存储:MongoDB实战指南>一书中的第1章,第1.1节,作者: 郭远威 , 彭文波 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区" ...

  3. 基于微信小程序的电影交流论坛系统 基于SSM的电影影评小程序(源码调试+讲解+文档)

  4. R语言实战应用精讲50篇(十八)-R语言实现分词、词频与词云案例解析

    前言 我真的超爱R语言,原因之一就是R有许多已经写好."开箱即用"的程序包可以直接拿来用:要知道,程序包减少了多少工作量.当然,其他语言也有类似的包,但是貌似没那么多.没那么细.这 ...

  5. 【微博爬虫教程实例】基于requests、mysql爬取大数据量博主关键字下博文及评论

    [关键词:手把手教程.反爬.数据库.python爬虫.微博关键词爬虫.较大数据量.数据简单过滤] 本教程适合微博相关爬虫需求者阅读,完整实例源码将放置在文末github链接中. 该实例针对微博的反爬措 ...

  6. 基于Scrapy框架爬取豆瓣《复联4》影评,并生成词云

    基于Scrapy框架爬取豆瓣<复联4>影评,并生成词云 1. 介绍及开发环境 2. 爬虫实现 2.1 新建项目 2.2 构造请求 2.3 提取信息 2.4 数据存储 2.4 运行结果 3. ...

  7. 基于Python的海量豆瓣电影、数据获取、数据预处理、数据分析、可视化、大屏设计项目(含数据库)

    目录 项目介绍 研究背景 国内外研究现状分析 研究目的 研究意义 研究总体设计 网络爬虫介绍 豆瓣电影数据的采集 数据预处理 大数据分析及可视化 豆瓣影评结构化分析 大屏可视化 文本可视化 总结 每文 ...

  8. 【项目实战】基于python的 p2p 贷后指标全自动日报制作

    需要数据分析.风控评分卡等相关数据.代码,请添加qq群:102755159,或留言联系笔者邮件发送!!! 如果对金融风控.机器学习.数据科学.大数据分析等感兴趣的小伙伴,可加微信交流(邮件中备注,我会 ...

  9. 电影《战狼2》的可视化分析

    <战狼2>真心堪称中国的好莱坞大片,不管是打斗场景的展现,还是在特效的细节处理.吴京的那句"我只会花钱在武器上,花在取景上,永远不会花在小鲜肉上!",也是近年来,观众对 ...

最新文章

  1. 设计模式学习2 工厂模式
  2. 用 Python 实现答题卡识别!
  3. mysql ldap_OpenLDAP 使用MySQL作为数据库
  4. [HDU 1427]速度计算24点(DFS暴力搜索)
  5. 云信迎来五周年里程碑:日活破3亿,消息量破10000亿
  6. boost::hana::flatten用法的测试程序
  7. when is this.oModel in sap-ui-core.js initialized for navigation working
  8. php ioc容器,PHP 在Swoole中使用双IoC容器实现无污染的依赖注入
  9. 基于java教学管理系统设计(含源文件)
  10. ansys怎么使用anand模型_详细剖析ANSYS有限元分析这个软件
  11. 如何得到DataTable的列名
  12. Pycharm下载包慢的问题
  13. python判断是否为英文_Python判断字符串是否纯英文(纯ASCII码字符)
  14. 推荐10个超级实用的电脑软件 (可以快速提高工作效率)
  15. c语言stdin输入字符,scanf如何从stdin中读取数据的
  16. python处理金融数据_Python金融大数据分析-数据获取与简单处理
  17. NOI / 2.1基本算法之枚举 1809:两倍
  18. 《IBM SPSS Modeler数据与文本挖掘实战》之文本挖掘算法
  19. BLE-1の蓝牙4.0协议栈概览
  20. Vue源码实现之watcher拾遗

热门文章

  1. 网站安全公司生存发展趋势分析
  2. 关于lightroom 安装出现乱码问题
  3. python抓取小红书_小红书很难爬?最新爬取方法教给你啦~
  4. java输出华氏摄氏温度转换表_C语言入门教程-示例:编写能够打印华氏-摄氏温度转换表的程序...
  5. IMS:开发者选项Touch点显示
  6. oracle查询为姓 张,Oracle经典查询案例
  7. c语言圆周率小数点后500万位,圆周率500位
  8. 在c语言如何对拨码开关编程,拨码开关控制实验
  9. 关于 618的前世今生,我帮东哥告诉你
  10. inurl_inurl,intitle指令的含义、作用及用法