上一篇用python分析豆瓣短评(一)讲了通过编写爬虫代码获取豆瓣电影短评数据。本文则利用pandas、matplotlib库对爬取的数据进行简单分析。
完整代码:
电影短评数据分析
一、从mongoDB中获取数据并清洗
数据清洗主要是清除mongoDB自动生成的_id字段,处理缺失值数据并转换数据类型,代码为:
def getData(self):
'''
从mongoDB中提取数据
:return: 电影评论的DataFrame数据
'''
try:
client = MongoClient()
db = client[self.database]
col = db[self.movie_name]
df = DataFrame(list(col.find()))
print('连接mongoDB成功!')
return df
except Exception:
print('尚未启动mongoDB服务。请提前开启mongoDB服务!')
def getCleanData(self):
'''
对从mongoDB中获取的原始数据进行清洗:剔除多余字段;转换数据类型;添加评分分数值列
:return:
'''
df = self.getData()
del df['_id'] # 删除mongodb自动生成对_id字段
# 处理评分(rating)字段空字符串及缺失值
df.rating = df.rating.str.split(',', expand=True).replace('', np.nan)
grades = self.grades
# 添加分数值列
df['score'] = df['rating'].apply(lambda x: grades[x] if x in grades else 0)
# 转换数据类型
df['pub_time'] = pd.to_datetime(df['pub_time']) # 将pub_time(评论发布日期)转换为日期格式
df['vote'] = pd.to_numeric(df['vote']) # 将vote(有用数)转换为数据格式
print('共获取%d条评论信息.' % len(df))
return df
二、电影评分情况
为了能够正常显示中文,需要提前进行字体设置
from pylon import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
统计不同打分的数量,得到评分的分布情况:
这是豆瓣网页上的评分分布结果:
可以看到,500个样本的打分分布与整体的分布基本一致,而且5星最多,大量4星,分布形状成F型,这是大好片的分布形状。(关于豆瓣评分形状介绍,可以看这里:从豆瓣评分的形状辨别电影质量。
不过比较以上两组评分分布也会发现,在采集的热门短评数据中,评价为3星及以下的比例(32%)高于全网数据(18%),导致按照样本数据计算的电影得分更低。鉴于豆瓣是以评论获得的“有用”数作为衡量热门的指标,说明还是有相当数量的用户不太认可这部电影。稍后我们可以再次对采集的数据进行分组并绘制词云,看看不同评分的用户有着怎样的评语。
三、评分与时间的关系
利用评论发表时间与打分数据,计算出单位时间内的平均分,并得到分数随时间的变化图。
由于《你的名字。》从最早在日本上映到样本数据截止日期已经有超过一年半的时间,因此选择以“月”作为时间单位计算平均分:
new_col = 'month'
data[new_col] = data['pub_time'].apply(lambda x: datetime.strftime(x, '%Y-%m'))
rating_by_time = data['score'].groupby(by=data[new_col]).mean()*2 #原始数据是5分制,这里改成10分制
使用matplotlib库绘制折线图:
fig, ax = plt.subplots()
ax.plot(rating_by_time,linestyle='--',marker='o')
ax.axes.set_xticklabels(rating_by_time.index.values,rotation=45)
ax.set_title(title)
得到分数变化图:
四、评论里都说了什么
之前提到,在样本数据中3星及以下的评论也占有近1/3的比例,因此以3星为界,将评论文本分为两组,分别绘制词云图。
先分组
goodRating=data[data['score']>3] #评分大于3星的为好评
poorRating=data[data['score']<=3] #评分小于等于3星的为差评
goodComments=goodRating['comment_lines']
poorComments=poorRating['comment_lines']
分别统计词频。好评组里前20高频词组为:
差评组的情况:
从统计结果来看,两组的高频词几乎一样,都是很频繁提到导演的名字、电影的画面,以及电影的主题,包括爱情和时空穿越。这些词语都是有实际的指向,表明热门的短评基本上都包含了实质的内容,而非水军灌水。
再看一下词云。
好评的词云里面几乎都是肯定的词汇,偶尔还提到新海诚的另一部《秒速五厘米》用来作比较。《触不到的恋人》也被提及,毕竟很难否认这部电影没有受到全智贤经典作品的启发。
差评的词云里面明显多了一些负面的词汇,比如觉得剧情“尴尬”、“受不了”,或者认为故事“空洞”、逻辑存在bug。即便如此,依然有很多评论提及电影的画面。的确,在电影院看过的人应该都会被壁纸一般的画质震撼到吧。
OK,最后上一张全部评论的词云。