文章目录

  • 一、数据整理
    • 1、合并+处理缺失值
    • 2、对于json格式的数据进行分割提取
  • 二、 电影类型随时间变化怎么样?
  • 三、 电影类型与利润的关系
  • 四、 Universal和Paramount两家影视公司的对比情况如何?
  • 五、 改编电影和原创电影以及评分情况如何
  • 六、 电影时长与电影票房以及评分的关系
  • 七、 分析电影关键字
    • 1、根据jieba生成词频计算
    • 2、根据pkuseg生成词频计算
  • 八、分析演员的关联度(社会网络计算)

一、数据整理

1、合并+处理缺失值

# tmdb_5000_movies.csv
budget  :电影成本
genres:风格列表,按|分隔,最多5种风格
homepage:电影首页URL
id :电影ID
keywords:电影关键词,按|分隔,最多5种关键词
original_language:原始语言
original_title  :电影名称
overview:剧情摘要
popularity:热度
production_companies:制作商
production_countries:制作地区
release_date:首次上映日期
revenue :收入
runtime :电影时长
spoken_languages:语言
status:是否发布
tagline:一句话说明一部电影(往往是海报上面的)
title   :电影名称
vote_average:平均分
vote_count:投票人数
# tmdb_5000_credits.csv
movie_id:电影ID
title:电影名称
cast:演员表
crew:制作团队(分析那些人经常出现在高票房的电影里面)
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
import json
import warnings
warnings.filterwarnings('ignore')#忽略警告credits_file='D:/S072003Python/05DataMineML/tmdb_5000_credits.csv'
movies_file='D:/S072003Python/05DataMineML/tmdb_5000_movies.csv'
credits=pd.read_csv(credits_file)
movies=pd.read_csv(movies_file)


# 合并文档
fulldf=pd.concat([credits,movies],axis=1)
# 选择子集
moviesnames=['movie_id','original_title','cast','crew','release_date','genres','keywords','production_companies','production_countries','revenue','budget','runtime','vote_average']
moviesdf=fulldf[moviesnames]
moviesdf.head()
# 增加电影利润
moviesdf['profit']=moviesdf['revenue']-moviesdf['budget']# 处理不理想数据
release_date_null=movies['release_date'].isnull()
moviesdf.loc[release_date_null]
moviesdf['release_date']=movies['release_date'].fillna('2014-06-01')
moviesdf['release_date']=pd.to_datetime(moviesdf['release_date'],format='%Y-%m-%d')
moviesdf.to_excel('moviesdf.xlsx',index=False)
moviesdf.head()#3 找出runtime的缺失值
runtime_date_null=moviesdf['runtime'].isnull()
moviesdf[runtime_date_null]
values={'runtime:':98.0}
values={'runtime:':81.0}moviesdf.fillna(value=values,limit=1,inplace=True)
moviesdf.fillna(value=values,limit=2,inplace=True)

2、对于json格式的数据进行分割提取

# 如何从json的数据格式提取需要的数据
# 提取电影风格数据genres
moviesdf['genreslist']=moviesdf['genres'].apply(json.loads)
moviesdf.head(1)
moviesdf['castlist']=moviesdf['cast'].apply(json.loads)
moviesdf['countries']=moviesdf['production_countries'].apply(json.loads) # json.loads()将str类型的数据转换为dict类型
moviesdf['companies']=moviesdf['production_companies'].apply(json.loads)
moviesdf['crewslist']=moviesdf['crew'].apply(json.loads)
moviesdf.head(1)

定义函数处理genres:

# 每一个genres
[{"id": 28, "name": "Action"}, {"id": 12, "name": "Adventure"}, {"id": 14, "name": "Fantasy"}, {"id": 878, "name": "Science Fiction"}]
#等于json格式的数据进行分割提取,通过自定义函数
def decode(column):z=[]for i in column:z.append(i['name'])return ' '.join(z) # 获取dict中第一个元素的name值
def decode1(column):z=[]for i in column:z.append(i['name'])return ''.join(z[0:1])  #切片,只输出第一个分隔
moviesdf['genresls']=moviesdf['genreslist'].apply(decode1)

二、 电影类型随时间变化怎么样?

# 电影类型与时间的关系
genres_list=set() # 获取所有的电影风格
for i in moviesdf['genresls'].str.split(' '):genres_list=set().union(i,genres_list) # 集合(set)是一个无序的不重复元素序列。可以使用大括号 { } 或者 set() 函数创建集合。genres_list=list(genres_list)genres_listgenres_list.remove('') # 去除空的元素
print(genres_list)moviesdf['releaseyear']=pd.to_datetime(moviesdf['release_date']).dt.year
moviesdf.head(3)
moviesdf.to_excel('moviesdfv3.xlsx',index=False)

得到的所有电影的风格genres_list

['Movie', 'Documentary', 'Comedy', 'Crime', 'Fantasy', 'History', 'Drama', 'Horror', 'Action', 'War', 'Foreign', 'Thriller', 'Fiction', 'Animation', 'Science', 'Music', 'Western', 'Romance', 'Family', 'TV', 'Mystery', 'Adventure']

目的:由于每部电影不只一种风格,则为每种风格添加一个字段,如果该电影包含这种风格则填1,否则填0。

for genre in genres_list:moviesdf[genre]=moviesdf['genresls'].str.contains(genre).apply(lambda x:1 if x else 0)moviesdf[genre].tail()
moviesdf.head(2)

genre_year=moviesdf.loc[:,genres_list]
genre_year.index=moviesdf['releaseyear']
genresdf=genre_year.groupby('releaseyear').sum()
genresdf
genresdf.plot(figsize=(16,10))


genresdfsum=genresdf.sum(axis=0).sort_values(ascending=False)
genresdfsum

genresdfsum:拿到从1916到2017年所有风格电影数据的总和

Drama          2297
Comedy         1722
Thriller       1274
Action         1154
Romance         894
Adventure       790
Crime           696
Fiction         535
Science         535
Horror          519
Family          513
Fantasy         424
Mystery         348
Animation       234
History         197
Music           185
War             144
Documentary     110
Western          82
Foreign          34
TV                8
Movie             8
dtype: int64
genresdfsum.sort_values().plot(kind='barh',label='genres') # 如果是kind='bar'则横纵坐标交换
plt.rcParams['font.sans-serif']=['Microsoft YaHei'] # 使用微软雅黑的字体
plt.title('电影类型数量排名统计图')
plt.xlabel('电影数量')
plt.ylabel('电影类型')
plt.show()

# 计算电影类型的饼图
genres_pie=genresdfsum/genresdfsum.sum()
others=0.01
genres_pie_otr=genres_pie[genres_pie>=others]
genres_pie_otr['other']=genres_pie[genres_pie<others].sum()explode=(genres_pie_otr<=0.02)/10+0.04
genres_pie_otr.plot(kind='pie',label='',startangle=50,shadow=False,figsize=(10,10),autopct='%1.1f%%',explode=explode)

# 电影类型和时间关系的分析
plt.figure(figsize=(16,10))
plt.plot(genresdf,label=genresdf.columns)
plt.xticks(range(1905,2021,5))
plt.legend(genresdf)
plt.title('电影类型与时间',fontsize=15)
plt.xlabel('年份',fontsize=15)
plt.ylabel('%ddir影数量',fontsize=15)
plt.show()

三、 电影类型与利润的关系

# 电影类型与利润的关系
mean_genre_profit=pd.DataFrame(index=genres_list)
mean_genre_profit.head()
newarray=[]
for genre in genres_list:
#   moviesdf.groupby('War',as_index=True)['profit'].mean() # 使得War得到两组数据,第一组为0,即不是War类型的平均值,无意义,因此下面只取第二组1newarray.append(moviesdf.groupby(genre,as_index=True)['profit'].mean())newarray2=[]
for i in range(len(genres_list)):newarray2.append(newarray[i][1]) # 这里取的是第二个数据,
mean_genre_profit['mean_profit']=newarray2
mean_genre_profit.head(17)

得到的mean_profit

mean_profit
Movie   -1.150000e+06
Documentary 7.185600e+06
Comedy  4.597608e+07
Crime   3.830085e+07
Fantasy 1.297936e+08
History 2.762010e+07
Drama   3.143791e+07
Horror  2.897105e+07
Action  8.970235e+07
War 4.887342e+07
Foreign -2.934369e+05
Thriller    4.907608e+07
Fiction 1.005910e+08
Animation   1.592271e+08
Science 1.005910e+08
Music   3.254800e+07
Western 1.916726e+07
Romance 3.969103e+07
Family  1.116260e+08
TV  -1.150000e+06
Mystery 4.755644e+07
Adventure   1.423333e+08
# 绘制电影类型与平均利润的关系
mean_genre_profit.sort_values(by='mean_profit').plot(kind='barh')
plt.xlabel('平均利润')
plt.ylabel('电影类型')
plt.title('电影类型与平均利润的关系')

四、 Universal和Paramount两家影视公司的对比情况如何?

# 对比两家电影公司的电影发行情况
# 对电影公司的数据进行整理
moviesdf['prodcompanies']=moviesdf['production_companies'].apply(json.loads)
moviesdf['prodcompany']=moviesdf['prodcompanies'].apply(decode) # 用到上面定义的函数
moviesdf.head()
moviesdf['Universal']=moviesdf['prodcompany'].str.contains('Universal Pictures').apply(lambda x:i if x else 0)
moviesdf['Paramount']=moviesdf['prodcompany'].str.contains('Paramount Pictures').apply(lambda x:i if x else 0)
moviesdf.tail()
a=moviesdf['Universal'].sum()
b=moviesdf['Paramount'].sum()
dict_companies={'Universal':a,'Paramount':b}
dict_companies
companies_number=pd.Series(dict_companies)
companies_number.plot(kind='pie',label='',autopct='%11.1f%%')

company=moviesdf[['Universal','Paramount']]
company.index=moviesdf['releaseyear']
companydf=company.groupby('releaseyear').sum()
companydf.head()plt.figure(figsize=(10,7))
plt.plot(companydf,label=companydf.columns)

五、 改编电影和原创电影以及评分情况如何

# 通过keywords字段,分割改编电影与原创电影的对比
# 分析:在keywords字段中,如果存在based on novel 则说明电影改编自小说
moviesdf['keywds']=moviesdf['keywords'].apply(json.loads)
moviesdf['keywds2']=moviesdf['keywds'].apply(decode)# 标注是否为基于小说改编的电影
a='based on novel'
moviesdf['if_original']=moviesdf['keywds2'].str.contains(a).apply(lambda x:'no original' if x else 'original')
moviesdf['if_original'].value_counts()
# moviesdf.head(2)original_profit=moviesdf[['if_original','budget','revenue','profit']]
original_profit_mean=original_profit.groupby(by='if_original').mean()
original_profit_mean.head()
plt.figure(figsize=(12,9))
original_profit_mean.plot(kind='bar')
plt.title('原创电影与改编电影的预算,收入,利润比较')
plt.xlabel('原创与改编')
plt.ylabel('现金流')
plt.xticks(rotation=0)

六、 电影时长与电影票房以及评分的关系

# 电影的runtime与票房,评分之间的关系
moviesdf.plot(kind='scatter',x='runtime',y='revenue',figsize=(10,7))
plt.title('电影时长与票房的关系',fontsize=15)
plt.xlabel('时长(分钟)',fontsize=15)
plt.ylabel('票房收入',fontsize=15)

# 电影的时长与评分之间的关系
moviesdf.plot(kind='scatter',x='runtime',y='vote_average',figsize=(10,7))
plt.title('电影时长与评分之间的关系',fontsize=15)
plt.xlabel('时长(分钟)',fontsize=15)
plt.ylabel('评分',fontsize=15)

七、 分析电影关键字

1、根据jieba生成词频计算

# 电影关键字词频计算和词云生成
keywords_list=[]
for i in moviesdf['keywds2']:keywords_list.append(i)
#     keywords_list=list(keywords_list)
lis=''.join(keywords_list)
lis.replace('\'s','')
lis
# 根据电影关键词生成词频计算
import jieba
words=jieba.lcut(lis)
counts={}
mytext_list=[]
for word in words:if len(word)==1: # 单个分词不需要continue else:counts[word]=counts.get(word,0)+1mytext_list.append(word.replace(" ",""))
cloud_text=','.join(mytext_list)
# print(cloud_text)
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(100):word,countsnt=items[i]print("{0:<10}{1:>5}".format(word,count))


from PIL import Image  #需要下载安装PIL包
import numpy as np
from wordcloud import WordCloud, ImageColorGenerator
from matplotlib import pyplot as plt
import pandas as pd
# 简单生成词云
wc=WordCloud(background_color='black',max_words=2000,max_font_size=100,min_font_size=10,random_state=12
)
wc.generate(lis)
plt.figure(figsize=(12,9))
plt.imshow(wc)
plt.axis('off')
plt.show()

2、根据pkuseg生成词频计算

# 安装pkuseg
!pip install pkuseg
#调用北大算法和jieba算法得到的结果对于英文来说基本相同,但对于中文来说pkuseg会更加准确
#根据电影关键词生成词频计算 北大算法pkuseg
# 根据电影关键词生成词频计算
import pkuseg
seg=pkuseg.pkuseg()words=seg.cut(lis) # 与jieba的区别主要是调用的算法不同counts={}
mytext_list=[]
for word in words:if len(word)==1: # 单个分词不需要continue else:counts[word]=counts.get(word,0)+1mytext_list.append(word.replace(" ",""))
cloud_text=','.join(mytext_list)
# print(cloud_text)
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(100):word,count=items[i]print("{0:<20}{1:>5}".format(word,count))

八、分析演员的关联度(社会网络计算)

# 分析演员的关联度(社会网络计算)
moviesdf['actorsls']
actors_list=[]
actorsforcut=[]# 将每部电影的演员放在列表当中
for i in moviesdf['actorsls']:actors_list.append(i.split(','))# 将演员列表中的对象放置到为分割而设置的另一个列表
for k in range(0,len(actors_list)):for j in range(len(actors_list[k])):actorsforcut.append(actors_list[k][j])actors_list=''.join(actorsforcut)
actors_list

此时生成的actors_list[0:100]

wc=WordCloud(background_color='black',max_words=2000,max_font_size=100,min_font_size=10,random_state=12
)
wc.generate(actors_list)
plt.figure(figsize=(12,9))
plt.imshow(wc)
plt.axis('off')
plt.show()

此时生成的词云是不完整的

改进方法:变换词云的结构:

# 改进方案:
# 分析演员的关联度(社会网络计算)
moviesdf['actorsls']
actors_list=[]
actorsforcut=[]# 将每部电影的演员放在列表当中
for i in moviesdf['actorsls']:actors_list.append(i.split(','))# 将演员列表中的对象放置到为分割而设置的另一个列表
for k in range(0,len(actors_list)):for j in range(len(actors_list[k])):actorsforcut.append("'"+actors_list[k][j]+"'") # 在这里对每个人的姓名前后都加上单引号actors_list=','.join(actorsforcut)
actors_list[0:100]

此时生成的actors_list[0:100]


将演员中间的空格去除,并合并为一个整体

# 如何将演员中间的空格去除,并合并为一个整体
movieactorsdfv2=moviesdf['actorsls'].apply(lambda x:''.join(x.split())).replace()
movieactorsdfv2.head(2)
movieactorsdfv2.to_csv('actors.txt',index=False,header=False)
# 读取数据并加载字典
with open('actors.txt',encoding='utf-8-sig') as f:actorstxt=f.readlines()# 此处的actors_forcut是手工查找替换单引号等完成的,在进行DF转换中可以直接处理
jieba.load_userdict("actors_forcut")
actorsforcut
actorsdf=pd.DataFrame(actorsforcut).drop_duplicates()
actorsdf[0]=actorsdf[0].apply(lambda x:''.join(x.split())).replace() # 将中间的空格删除
# 此时拿到了完整的人物列表
actorsdf[0]=actorsdf[0].apply(lambda x:''.join(x.split('\''))).replace() # 将姓名两边的单引号去除
actorsdf['']='nr'
actorsdf.to_excel('actorsdf.xlsx',index=False)
actorsdf.head()
movieactorsdfv2=pd.DataFrame(moviesdf['actorsls'])
movieactorsdfv2.head(5)


思路:如果我们按照actorsdf去寻找movieactorsdfv2,只要在电影里面找到了演员的名字,则在对应的actorsdf上面加一,就能知道哪些演员演过的电影最多。并且还可以将不同演员之间建立关系,最后使用pyechart进行可视化。

机器学习系列(2)_数据分析之Kaggle电影TMDB5000相关推荐

  1. 机器学习系列(1)_数据分析之Kaggle泰坦尼克之灾

    本篇博客通过分析泰坦尼克号事故中乘客的信息,从而得出一些相关关系的判断,并且使用Python可视化的手段更加具体的展现. 注:本篇博客参考资料: 1.kaggle入门–泰坦尼克号之灾(某书) 2.机器 ...

  2. 机器学习系列(4)_机器学习算法一览,应用建议与解决思路

    作者:寒小阳 时间:2016年1月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50469334 声明:版权所有,转载请联系作者并注明出 ...

  3. 机器学习系列(10)_决策树与随机森林回归

    注:本篇文章接上一篇文章>>机器学习系列(9)_决策树详解01 文章目录 一.决策树优缺点 二.泰坦尼克号幸存者案例 三.随机森林介绍 1.随机森林的分类 2.重要参数 [1]n_esti ...

  4. 机器学习系列(8)_读《Nature》论文,看AlphaGo养成

    机器学习系列(8)_读<Nature>论文,看AlphaGo养成  标签: 机器学习算法深度学习神经网络蒙特卡罗树搜索 2016-03-16 11:23 17843人阅读 评论(8) 收藏 ...

  5. 机器学习系列(2)_从初等数学视角解读逻辑回归

    作者:龙心尘 && 寒小阳  时间:2015年10月.  出处:http://blog.csdn.net/longxinchen_ml/article/details/49284391 ...

  6. 机器学习系列(1)_逻辑回归初步

    转载自: 机器学习系列(1)_逻辑回归初步 - 寒小阳 - 博客频道 - CSDN.NET http://blog.csdn.net/han_xiaoyang/article/details/4912 ...

  7. 机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾

    作者: 寒小阳 时间:2015年11月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/49797143 声明:版权所有,转载请注明出处,谢 ...

  8. 机器学习系列(7)_机器学习路线图(附资料)

    作者:寒小阳&&龙心尘 时间:2016年2月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50759472 http:/ ...

  9. (转)机器学习系列(7)_机器学习路线图(附资料)

    作者:寒小阳&&龙心尘 时间:2016年2月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50759472 http:/ ...

  10. 机器学习系列(9)_机器学习算法一览(附Python和R代码)

    转载自:http://blog.csdn.net/longxinchen_ml/article/details/51192086 – 谷歌的无人车和机器人得到了很多关注,但我们真正的未来却在于能够使电 ...

最新文章

  1. 记住:用户不是傻*,她是你的老婆大人
  2. linux常规检查命令,linux学习-常规命令使用5
  3. UI学习笔记---第十四天数据持久化
  4. 《大型门户网站是这样炼成的!(Struts 2+Spring 2+Hibernate 3) 》
  5. 嵊州D5T2 折纸 folding
  6. 基于Ant Design UI框架的React项目
  7. 大数据城市规划 杨东_空头转多!前期大比例减仓的私募,目前开始加仓
  8. python窗口消息处理_在Python中将鼠标光标悬停在某些内容上时显示消息
  9. android base64 字符串,Android 文件转base64字符串
  10. vb.net怎么和mysql连接_解析VB.NET如何连接数据库
  11. VBA—Doevents说明
  12. 车辆颜色识别opencv
  13. 法国警告Nobelium网络间谍攻击法国组织
  14. Google谷歌地图基础
  15. 2021年芯片产业发展的五大关键词
  16. 华为云服务器使用教程
  17. ChineseGLUE:为中文NLP模型定制的自然语言理解基准
  18. iOS超级签名流程及代码(php版本)
  19. 快讯:今日一颗小行星2014 RC掠过地球轨道
  20. 一文了解互联网技术岗

热门文章

  1. 域名解析信息易语言代码
  2. vb.net程序可以在触摸屏上运行么_简单PLC编程台达PLC模拟量程序
  3. Scala(1) -- Scala下载安装及idea环境配置
  4. icem网格数和节点数_icem如何查看网格数量
  5. mysql8.0重置密码
  6. 什么是JavaWeb,主要框架有哪些
  7. 高等数学 下册 第九章 多元函数的概念 笔记
  8. ELK-使用nxlog+filebeat采集不同类型的日志输出到logstash
  9. SVN server安装步骤
  10. 基于stm32的指纹打卡系统/指纹锁