快好知 kuaihz

口碑扑街!Python告诉你《完美关系》为何表...

 CDA数据分析师 出品  

【导语】:今天我们聊聊国产职场剧《完美关系》,Python技术部分可以直接看第三部分。

Show me data,用数据说话

今天我们聊聊 职场剧《完美关系

点击下方视频,先睹为快:

最近一连出了好几部职场剧,有孙俪主演讲述房地产行业的《安家》,李易峰主演讲律师的《我在北京等你》,以及佟丽娅、黄轩主演围绕公关行业展开的《完美关系》。

其中,《安家》是翻拍自高分日剧《卖房子的女人》,《我在北京等你》讲的是一名律师奋斗的故事,《完美关系》则是国产职场剧涉及的又一全新行业——公关。

那么这三部剧的口碑如何呢?

截止到目前为止,《安家》在豆瓣的评分为6.2分,《我在北京等你》豆瓣5.2分,《完美关系》为3.9分。都不是特别好的成绩。

《完美关系》播出后更是有公关行业的小伙伴吐槽:我们不想被这么代言啊!

那么《完美关系》到底是哪里差强人意呢?今天我们就先聊聊这部《完美关系

01:

近年频频扑街的

国产职场剧

近年来,推出的国产职场剧还真不少,涉及的行业从地产、互联网、医疗、到翻译、律师等等,几乎形形色色的行业都有。但这些剧的口碑如何呢?

先看几部比较热门的:

以上这些剧在播出时都频频上热搜,但口碑就差强人意了。分数3.5-5.5不等,连6分及格线都不到。

相关行业的从业者也吐槽,根本没有反应出行业的真实现状,美其名曰职场剧,其实这不是披着行业外衣的偶像剧嘛!

进一步汇总国产职场剧的情况可以发现:

图源:DT财经

从2008年到2020年3月,共出品64部职场剧,近两年职场题材更有井喷之势,2018年和2019年每年都有13部,数量是2014年的13倍!

数量上来了,然后质量就堪忧了。从这些职场剧的豆瓣评分可见,平均分一直在5.5分徘徊。

02:

披着公关外衣的

《完美关系

那这次瞄准公关行业的《完美关系》能为国产职场剧正名吗?

《完美关系》是由安建执导,黄轩、佟丽娅领衔主演,陈数、高露主演的都市职场剧。

故事讲的是公关合伙人卫哲、江达琳等人从单枪匹马到并肩作战,积极迎接在公关实战中遇到的压力与困难,互相影响、共同成长的故事。

图源:《完美关系》官方剧照

从2月18日首播以来,《完美关系》的收视率越来越高,3月11日《完美关系》凭借6.92%的市场占有率,拿下了收视率排行榜的冠军宝座。

但同时收获的吐槽和差评也不少,主要集中在:

剧情太浮夸,对公关行业的刻画不真实;

女主的傻白甜人设实在不讨喜;

演员的演技流于表面,难以产生共鸣等等

03:

《完美关系》豆瓣3.9分

到底冤不冤?

《完美关系》在豆瓣已有60284人进行评分,目前仅为3.9分。那么《完美关系》豆瓣3.9分到底冤不冤呢?

我们对《完美关系》豆瓣的影评数据进行了收集整理。

整个数据分析的过程分为三步:

· 获取数据

· 数据预处理

· 数据可视化

以下是具体的步骤和代码实现:

获取数据

1:

此次我们选择豆瓣短评的数据作为分析对象。由于豆瓣的限制,非登录状态下最多获取200条数据,登录状态下最多获取500条数据

为了解决登录的问题,此次我们使用requests的Session方法来让代码自动保存Cookie信息,维持登录和会话保持状态。然后使用Xapth配合正则语句进行数据的提取。

如图所示,本次我们需要获取的主要内容如下:

用户名

用户主页

评论时间

评论星级

短评内容

短评投票数

用户主页(用于获取城市)

评分分布

代码实现:

# 导入所需包

import pandas as pd

import requests

import parsel

import re

import time

from fake_useragent import UserAgent

def login_douban():

 """

 功能:登录豆瓣,维持会话形式

 """

 global s

 # 初始化session

 s = requests.Session()

 # 登录地址

 login_url = "https://accounts.douban.com/j/mobile/login/basic"

 # 添加headers

 headers = {"user-agent": UserAgent().random}

 # 表单数据

 form_data = {

  "name": "你的账号",

  "password": "你的密码",

  "remember": "false"

 }

 # post登录

 try:

  s.post(login_url, headers=headers, data=form_data)

 except:

  print("登录失败")

def get_one_page(url):

 """

 功能:给定URL地址,获取豆瓣电影一页的短评信息

 :param url: 电影URL地址

 :return: 返回数据

 """

 # 添加headers

 headers = {"user-agent": UserAgent().random}

 # 发起请求

 try:

  r = s.get(url, headers=headers, timeout=5)

 except:

  time.sleep(3)

  r = s.get(url, headers=headers, timeout=5)

 # 解析网页

 data = parsel.Selector(r.text)

 # 获取用户名

 user_name = [re.findall(r".*?class="">(.*?).*", i)

  for i in data.xpath("//span[@class="comment-info"]").extract()]

 # 获取评分

 rating = [re.findall(r".*?.*", i)

  for i in data.xpath("//span[@class="comment-info"]").extract()]

 # 获取评论时间

 comment_time = [re.findall(r".*", i)

  for i in data.xpath("//span[@class="comment-info"]").extract()]

 # 获取短评信息

 comment_info = data.xpath("//span[@class="short"]/text()").extract()

 # 投票次数

 votes_num = data.xpath("//span[@class="comment-vote"]/span/text()").extract()

 # 获取主页URL

 user_url = data.xpath("//div[@class="avatar"]/a/@href").extract()

 # 保存数据

 df_one = pd.DataFrame({

  "user_name": user_name,

  "rating": rating,

  "comment_time": comment_time,

  "comment_info": comment_info,

  "votes_num": votes_num,

  "user_url": user_url

 })

 return df_one

def get_all_page(movie_id, page_num=25):

 """

 功能:获取豆瓣电影25页短评信息

 :param movie_id: 电影ID

 :param page_num: 爬取页面数

 :return: 返回数据

 """

 df_25 = pd.DataFrame()

 for i in range(page_num):

  # 构造URL

  url = "https://movie.douban.com/subject/{}/comments?start={}&limit=20&sort=new_score&status=P".format(movie_id,

  i * 20)

  # 调用函数

  df = get_one_page(url)

  # 循环追加

  df_25 = df_25.append(df, ignore_index=True)

  # 打印进度

  print("我正在获取第{}页的信息".format(i + 1))

  # 休眠一秒

  time.sleep(1)

 return df_25

if __name__ == "__main__":

 # 先登录豆瓣

 login_douban()

 # 获取完美关系

 df_all = get_all_page(movie_id="30221758")

 print(df_all.shape)

获取的数据数据框的形式存储,结果如下:

从用户主页的地址可以进一步获取到用户的城市信息,此次共获取500条数据

数据预处理

2:

对于获取的数据,我们需要进行进一步的处理以满足可视化的需求。

推荐星级:转换为1~5分

评论时间:转换为时间类型,并提取日期数据

城市信息:有未填写数据、海外城市、写错的需要进行处理

短评信息:需要进行分词处理

部分关键代码:

# 处理评分列

df["rating"] = [re.sub(r"[""|""]", "", i) for i in df["rating"]]

# 替换空列表

df["rating"].replace("[]", "还行", inplace=True)

# 定义字典

rating_dict = {

 "很差": "1星",

 "较差": "2星",

 "还行": "3星",

 "推荐": "4星",

 "力荐": "5星"

}

df["rating"] = df["rating"].map(rating_dict)

# 评论信息分词处理

# 合并为一篇

txt = df["comment_info"].str.cat(sep="。")

# 添加关键词

jieba.add_word("黄轩")

jieba.add_word("佟丽娅")

jieba.add_word("男主")

jieba.add_word("女主")

jieba.add_word("跳戏")

jieba.add_word("颜值")

jieba.add_word("吐槽")

jieba.add_word("装逼")

jieba.add_word("国产剧")

# 读入停用词表

stop_words = []

with open("stop_words.txt", "r", encoding="utf-8") as f:

 lines = f.readlines()

 for line in lines:

  stop_words.append(line.strip())

# 添加停用词

stop_words.extend(["一部", "一拳", "一行", "10", "啊啊啊", "一句",

 "get", "哈哈哈哈", "哈哈哈", "越来越", "一步",

 "一种", "样子", "几个", "第一集", "一点",

 "第一", "没见", "一集", "第一次", "两个",

 "二代", "真的", "2020", "令人"])

# 评论字段分词处理

word_num = jieba.analyse.extract_tags(txt,

  topK=100,

  withWeight=True,

  allowPOS=())

# 去停用词

word_num_selected = []

for i in word_num:

 if i[0] not in stop_words:

  word_num_selected.append(i)

key_words = pd.DataFrame(word_num_selected, columns=["words","num"])

数据可视化

3:

我们使用pyecharts进行数据可视化分析,安装命令:pip install pyecharts。分析结果如下:

总体评分分布

有41.6%的人都给了1星,其次28.2%的人给了5星。15.4%的人给了2星。由此可见本剧的两极分化特别严重,有些人特别喜欢给到了5星好评,同时觉得拍的很烂的也有不少。

代码实现:

score_perc = df["rating"].value_counts() / df["rating"].value_counts().sum()

score_perc = np.round(score_perc*100,2)

print(score_perc)

# 绘制饼图

from pyecharts.charts import Pie

from pyecharts import options as opts

pie1 = Pie(init_opts=opts.InitOpts(width="1350px", height="750px"))

pie1.add("",

   [*zip(score_perc.index, score_perc.values)],

   radius=["35%","70%"])

pie1.set_global_opts(title_opts=opts.TitleOpts(title="总体评分分布"),

   legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),

   toolbox_opts=opts.ToolboxOpts())

pie1.set_series_opts(label_opts=opts.LabelOpts(formatter="{c}%"))

pie1.set_colors(["#D7655A", "#FFAF34", "#3B7BA9", "#EF9050", "#6FB27C"])

pie1.render()

评分热度时间走势

评分热度主要集中在2月18日,也就是《完美关系》首播的那天,其次热度不断下降。

代码实现:

df["comment_time"] = pd.to_datetime(df["comment_time"])

df["comment_date"] = df["comment_time"].dt.date

comment_num = df["comment_date"].value_counts().sort_index()

# 折线图

from pyecharts.charts import Line

line1 = Line(init_opts=opts.InitOpts(width="1350px", height="750px"))

line1.add_xaxis(comment_num.index.tolist())

line1.add_yaxis("评论热度", comment_num.values.tolist(),

 areastyle_opts=opts.AreaStyleOpts(opacity=0.5),

 label_opts=opts.LabelOpts(is_show=False))

line1.set_global_opts(title_opts=opts.TitleOpts(title="时间走势图"),

 toolbox_opts=opts.ToolboxOpts(),

 visualmap_opts=opts.VisualMapOpts(max_=200))

line1.render()

评论用户城市分布

观看和评分人群主要集中在北上广三地,其次是江苏、四川等地。

代码实现:

# 国内城市top10

city_top10 = df["city_dealed"].value_counts()[:12]

city_top10.drop("国外", inplace=True)

city_top10.drop("未填写", inplace=True)

# 条形图

from pyecharts.charts import Bar

bar1 = Bar(init_opts=opts.InitOpts(width="1350px", height="750px"))

bar1.add_xaxis(city_top10.index.tolist())

bar1.add_yaxis("城市", city_top10.values.tolist())

bar1.set_global_opts(title_opts=opts.TitleOpts(title="评论者Top10城市分布"),

   visualmap_opts=opts.VisualMapOpts(max_=50),

   toolbox_opts=opts.ToolboxOpts())

bar1.render()

city_num = df["city_dealed"].value_counts()

city_num.drop("国外", inplace=True)

city_num.drop("未填写", inplace=True)

from pyecharts.charts import Map

# 地图

map1 = Map(init_opts=opts.InitOpts(width="1350px", height="750px"))

map1.add("", [list(z) for z in zip(city_num.index.tolist(), city_num.values.tolist())],

   maptype="china")

map1.set_global_opts(title_opts=opts.TitleOpts(title="评论者国内城市分布"),

   visualmap_opts=opts.VisualMapOpts(max_=50),

   toolbox_opts=opts.ToolboxOpts())

map1.render()

评论词云

而在词云方面讨论最多的就是「黄轩」和「佟丽娅」两大主演了。

其次关于女配「陈数」的讨论也很多,无论是陈数这次强大的职场新女性人设,还是惊艳干练的职场穿搭都是很吸睛的。

然后对「演技」和「剧情」上的吐槽也不少。评价中「油腻」、「尴尬」、「狗血」等负面词频频出现。

代码实现: 

# 词云图

from pyecharts.charts import WordCloud

from pyecharts.globals import SymbolType

word1 = WordCloud(init_opts=opts.InitOpts(width="1350px", height="750px"))

word1.add("", [*zip(key_words.words, key_words.num)],

 word_size_range=[20, 200],

 shape=SymbolType.DIAMOND)

word1.set_global_opts(title_opts=opts.TitleOpts("完美关系豆瓣短评词云图"),

 toolbox_opts=opts.ToolboxOpts())

word1.render()

那么《完美关系》你怎么看呢?

作者:Mika

本站资源来自互联网,仅供学习,如有侵权,请通知删除,敬请谅解!
搜索建议:口碑  口碑词条  告诉  告诉词条  为何  为何词条  关系  关系词条  完美  完美词条