豆瓣电影数据分析实战实验(训)报告

实训项目:豆瓣电影数据分析实战

系统需求分析:

数据采集:使用lxml,BeautifulSoup4框架或Scrapy框架爬取豆瓣电影Top250的数据。

(分析系统的功能模块需求,详细描述各个功能模块的作用) 

数据清洗:对爬取到的电影数据进行缺失值处理、异常值处理、数据类型转换和数据去重等数据清洗操作。

数据分析:多维度分析:导演、主演、类型、制片国家等,对比分析:电影评分变化趋势、电影数据的变化趋势,文本分析:热词统计、文本情感分析

数据可视化:通过折线图、柱状图、柱状图和词云等多种方式完成可视化

系统设计

(系统整体设计,各个功能模块的设计,可以通过系统架构图、流程图和活动图等多种方式进行描述)

系统实现

各个功能模块的实现过程以及实现的结果)

调试及结果分析

所有功能演示,根据输入的不同数据得到不同的测试结果)

# 一、导入常用库

import numpy as np

import pandas as pd

from collections import Counter

import matplotlib.pyplot as plt

from bs4 import BeautifulSoup

import seaborn as sns

import collections

import requests

import pyecharts as pe

import json

import statsmodels.formula.api as smf

from array import array

from statsmodels.formula.api import ols

# 导入数据

df=pd.read_excel("movice.xlsx")

df.head(5)

#转换日期格式

df['上映时间'] = pd.to_datetime(df['上映时间']).apply(lambda x: x.date())

df.columns

df_columns = ['名字','类型','导演','编剧','主演','时长','国家','语言','上映时间','简介','评分','评分人数','排名']

# 检查重复值、缺失值

df.info()

print(df.describe())

# 判断哪些列有空值

df.isnull().any()

# 筛选出主演为空值的数据

df[df['编剧'].isnull()]

df[df['主演'].isnull()]

# 填充相应的值

df['编剧'].fillna('郭柯',inplace=True)

df['主演'].fillna('韦绍兰',inplace=True)

df.isnull().any()

# 二、数据可视化

# 定义函数,将用"/" 分割的数据转化为列表

def conver_list(df, *columns):

    for column in columns:

        data[column] = data[column].str.split('/')

    return data

data

# #获取上映时间中的年份

type(data['上映时间'] )

type(data['类型'] )

data['上映时间']=pd.to_datetime(data['上映时间'], errors='coerce')

data['上映年份'] = df['上映时间'].dt.strftime('%Y')

data

# 1、获取每一年上映的电影数量

list_date = data['上映年份'].tolist()

date_count = collections.Counter(list_date)

print(date_count)

len(date_count)

# 2、按照电影上映年份进行排序

sort_date_count = sorted(date_count.items(), key=lambda x: x[0])

# 将排序后的字典转化为新的列表,作为图表横坐标轴、纵坐标轴

x1 = [x[0] for x in sort_date_count]

y1 = [x[1] for x in sort_date_count]

#3、绘制电影年份数量情况分布图

plt.figure(dpi=300,figsize=(24,8))

yearshu=data.groupby('上映年份')['上映年份'].count().plot(kind='bar')

p1 = plt.bar(x1, y1, width= 0.8, label='value')  # width表示柱子的宽度

# plt.xticks(rotation=360)

plt.xticks(rotation = 90,fontsize=20)#使x轴标签竖着显示

plt.title('电影上映年份分布情况',fontname='SimHei',fontsize=15)

plt.xlabel('上映年份',fontname='SimHei',fontsize=15)

plt.ylabel('不同年份上映的电影数量',fontname='SimHei',fontsize=15)

plt.bar_label(p1, label_type='edge')# label_type=‘edge’表示将数据值标签放在柱子顶端,label_type=‘center’表示将数据值标签放在柱子中间。

plt.show()

import pandas as pd

yearshu1=data.groupby('上映年份')['上映年份'].count()

# 4、豆瓣评分&年份的情况分布的散点图

yearshu2=data.groupby('上映年份')['评分'].sum()

# yearshu2

list=[yearshu1,yearshu2]

data3=pd.DataFrame(list).T

data3.columns = ['每年的电影数量', '总评分',]

junfen=data3['总评分'] /data3['每年的电影数量']

data3['评分的平均值'] = data3['总评分'] /data3['每年的电影数量']

aa = data3.sort_values(by=['评分的平均值'],ascending=False)

aa

data3

5、豆瓣评分&年份的情况分布的散点图

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

import random

# 正确显示中文和负号

plt.rcParams["font.sans-serif"] = ["SimHei"]

plt.rcParams["axes.unicode_minus"] = False

plt.xticks(rotation = 90,fontsize=10)#使x轴标签竖着显示

sns.set(font='SimHei')

sns.scatterplot(aa,x='上映年份', y='评分的平均值')  #sns.scatterplot()画散点图

plt.title('年份 &豆瓣评分情况分布散点图',fontname='SimHei',fontsize=15)

plt.xlabel('年份',fontname='SimHei',fontsize=15)

plt.ylabel('豆瓣评分每年的均值',fontname='SimHei',fontsize=15)

# plt.bar_label(p1, label_type='edge')# label_type=‘edge’表示将数据值标签放在柱子顶端,label_type=‘center’表示将数据值标签放在柱子中间。

plt.show()

plt.xticks(rotation = 90,fontsize=10)#使x轴标签竖着显示

sns.set(font='SimHei')

sns.scatterplot(data3,x='上映年份', y='评分的平均值')  #sns.scatterplot()画散点图

plt.title('年份 &豆瓣评分情况分布散点图',fontname='SimHei',fontsize=15)

plt.xlabel('年份',fontname='SimHei',fontsize=15)

plt.ylabel('豆瓣评分每年的均值',fontname='SimHei',fontsize=15)

# plt.bar_label(p1, label_type='edge')# label_type=‘edge’表示将数据值标签放在柱子顶端,label_type=‘center’表示将数据值标签放在柱子中间。

plt.show()

# 6、各个国家电影数量的分布情况

# 将排序后的字典转化为新的列表,作为横坐标轴、纵坐标轴

x2 = [x[0] for x in sort_area_count]

y2 = [x[1] for x in sort_area_count]

# yearshu=data.groupby('上映年份')['上映年份'].count().plot(kind='bar')

# plt.figure(dpi=300,figsize=(24,8))

p1 = plt.bar(x2, y2,width=1,label='value')  # width表示柱子的宽度

# plt.xticks(rotation=360)

plt.xticks(rotation = 90,fontsize=9)#使x轴标签竖着显示

plt.title('各个国家电影数量的分布情况',fontname='SimHei',fontsize=15)

plt.xlabel('各个国家',fontname='SimHei',fontsize=15)

plt.ylabel('不同国家的电影数量',fontname='SimHei',fontsize=15)

plt.bar_label(p1, label_type='edge')# label_type=‘edge’表示将数据值标签放在柱子顶端,label_type=‘center’表示将数据值标签放在柱子中间。

plt.show()

# 7、电影类型分布情况

plt.figure(dpi=300,figsize=(24,64))

type_list = []

for i in data['类型']:

    type_list.extend(i)

type_count = collections.Counter(type_list)

sort_type_count = sorted(type_count.items(), key=lambda x: x[1], reverse=True)

print(sort_type_count)

x3 = [x[0] for x in sort_type_count]

y3 = [x[1] for x in sort_type_count]

pie,l_text,p_text=plt.pie(x=y3, labels=x3, autopct='%3.1f%%',labeldistance=1.2)

for t in l_text:

    t.set_size(22)

for t in p_text:

    t.set_size(17)

plt.title('各类型数量情况比较',fontsize=40)

plt.legend(loc='upper right', bbox_to_anchor=(1.8,1),fontsize=25)

plt.show()

p1 = plt.bar(x3, y3, width= 0.8, label='value')  # width表示柱子的宽度

plt.xticks(rotation = 90,fontsize=10)#使x轴标签竖着显示

plt.title('电影类型的分布情况',fontname='SimHei',fontsize=15)

plt.xlabel('电影的类型',fontname='SimHei',fontsize=15)

plt.ylabel('不同类型的电影数量',fontname='SimHei',fontsize=15)

plt.bar_label(p1, label_type='edge')# label_type=‘edge’表示将数据值标签放在柱子顶端,label_type=‘center’表示将数据值标签放在柱子中间。

plt.show()

# 8、导演数量分布前20

director_list = []

for x in df['导演']:

    director_list.extend(x)

director_count = collections.Counter(director_list)

sort_director_count = sorted(

    director_count.items(), key=lambda x: x[1], reverse=True)

x4 = [x[0] for x in sort_director_count]

y4 = [x[1] for x in sort_director_count]

# fig = plt.figure(figsize=(100, 200))

plt.figure(dpi=300,figsize=(24,8))

p1 = plt.bar(x4[:20], y4[:20], width= 0.8)  # width表示柱子的宽度

plt.xticks(rotation = 90,fontsize=20)#使x轴标签竖着显示

plt.title('Top250电影导演数量分布情况(前20位导演)',fontname='SimHei',fontsize=15)

plt.xlabel('导演名称',fontname='SimHei',fontsize=15)

plt.ylabel('电影数量',fontname='SimHei',fontsize=15)

plt.bar_label(p1, label_type='edge',fontsize=20)# label_type=‘edge’表示将数据值标签放在柱子顶端,label_type=‘center’表示将数据值标签放在柱子中间。

plt.show()

# 9、主演前20分布柱形图

actor_list = []

for x in df['主演']:

    actor_list.extend(x)

actor_count = collections.Counter(actor_list)

sort_actor_count = sorted(

    actor_count.items(), key=lambda x: x[1], reverse=True)

x5 = [x[0] for x in sort_actor_count]

y5 = [x[1] for x in sort_actor_count]

plt.figure(dpi=300,figsize=(24,8))

p1 = plt.bar(x5[:20], y5[:20], width= 0.8, label='value')  # width表示柱子的宽度

plt.xticks(rotation = 90,fontsize=20)#使x轴标签竖着显示

plt.title('Top250电影主演分布情况(前20位导演)',fontname='SimHei',fontsize=15)

plt.xlabel('主演名称',fontname='SimHei',fontsize=15)

plt.ylabel('电影数量',fontname='SimHei',fontsize=15)

plt.bar_label(p1, label_type='edge')

plt.show()

# 10、查看电影时长柱形图

import matplotlib.pyplot as plt

bins=[0,80,100,120,140,160,180,240]

pd.cut(data.时长,bins)

pd.cut(data.时长,bins).value_counts()

pd.cut(data.时长,bins).value_counts().plot.bar(rot=20)

# 11、绘制评分人数与排名的散点图

plt.figure(figsize=(20,5))

plt.subplot(1,2,1)

# 绘制散点图

plt.scatter(data['评分人数'],data['排名'])

plt.xlabel('评分人数')

plt.ylabel('排名')

plt.gca().invert_yaxis()

# 绘制直方图

plt.subplot(1,2,2)

plt.hist(data['评分人数'])

# 12、豆瓣电影Top250评分-排名的散点分布

plt.figure(figsize=(9, 6), dpi=100)

# 设置字体

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 绘制散点图  设置点的颜色

plt.scatter(rating_score, rating, c='r')

# 添加描述信息  设置字体大小

plt.xlabel("评分", fontsize=12)

plt.ylabel("排名", fontsize=12)

plt.title("豆瓣电影Top250评分-排名的散点分布", fontsize=15)

# 添加网格  网格的透明度  线条样式

plt.grid(alpha=0.5, linestyle=":")

plt.savefig('test2.PNG')

plt.show()

# 13、豆瓣top250电影排名&评分&评分人数情况

x5 = data['评分人数'].tolist()

y5 = data['评分'].tolist()

z = data['排名'].tolist()

plt.figure(figsize=(12, 8))

plt.scatter(x=x5,

            y=z,

            cmap='Blues',

            marker='o',

            c=y5,   # 数字越大,颜色越深,评分越高

            alpha=0.8,

            linewidths=0.3,

            edgecolors='Black')

plt.title('豆瓣top250电影排名&评分&评分人数情况', fontsize=18)

plt.xlabel('评分人数', fontsize=14)

plt.ylabel('豆瓣排名', fontsize=14)

plt.xlim(0, 2500000)

plt.colorbar()

14、评论热词次统计及词云可视化

# 导入扩展库

import re # 正则表达式库

import numpy as np # numpy数据处理库

import jieba # 结巴分词

import wordcloud # 词云展示库

from PIL import Image # 图像处理库

import matplotlib.pyplot as plt # 图像展示库

# 读取文件

fn = open('pinglun1.csv','r',encoding='utf-8') # 打开文件

string_data = fn.read() # 读出整个文件

fn.close() # 关闭文件

# 文本预处理

pattern = re.compile(u'\t|\n|\.|-|:|;|\)|\(|\?|"') # 定义正则表达式匹配模式

a = re.sub(pattern, '', string_data) # 将符合模式的字符去除

# print(type(string_data))

words =jieba.lcut(a)

counts = {}

for word in words:

    if len(word) == 1:

        continue

    else:

        counts[word] = counts.get(word,0)+1

print(len(counts))

# 词频展示

mask = np.array(Image.open('771.jpg')) # 定义词频背景

wc = wordcloud.WordCloud(

    font_path='C:/Windows/Fonts/simhei.ttf', # 设置字体格式

mask=mask, # 设置背景图

    # max_words=200, # 最多显示词数

    max_font_size=100,

    background_color="white" #字体最大值

)

wc.generate_from_frequencies(counts) # 从字典生成词云

plt.imshow(wc) # 显示词云

plt.axis('off') # 关闭坐标轴

plt.show() # 显示图像

15、简介情感分析词云图

df=pd.read_excel("movice.xlsx")

s = []

for i in df['简介']:

    s.append(i)

# print(s)

a = str(s)

words =jieba.lcut(a)

counts = {}

for word in words:

    if len(word) == 1:

        continue

    else:

        counts[word] = counts.get(word,0)+1

# items = list(counts.items())

# items.sort(key=lambda x:x[1],reverse=True)

# items

Counts

import numpy as np # numpy数据处理库

import wordcloud # 词云展示库

from PIL import Image # 图像处理库

import matplotlib.pyplot as plt # 图像展示库

text={"喜欢":16,"神秘":13,"梦想":9,'兴趣':9,"怀疑":8,"爱情":8,"案件":7,"社会":7,"愤怒":6,"美好":6,"疯狂":5,"热爱":5,"犯罪":5,

        "威胁":5,"失去":5,"真实":5,"事实":5,"保护":5,"杀害":19,"奇怪":4,"放弃":4,"失败":4,"理想":4,"幸福":4,"烦恼":4

        ,"肮脏":4,"追杀":4,"期待":4,"可爱":4,"温暖":4,"绝望":3,"救赎":3,"鼓励":3,"孤独":3,"不满":3,"垃圾":3,"哭泣":3,

        "好奇":3,"无力":3,"残忍":3,"刺激":3,"活泼":3,"快乐":3,"厌倦":3}

# 词频展示

mask = np.array(Image.open('771.jpg')) # 定义词频背景

wc = wordcloud.WordCloud(

    font_path='C:/Windows/Fonts/simhei.ttf', # 设置字体格式

    mask=mask, # 设置背景图

    max_font_size=100,

 background_color="white" #字体最大值

)

wc.generate_from_frequencies(text) # 从字典生成词云

# image_colors = wordcloud.ImageColorGenerator(mask) # 从背景图建立颜色方案

# wc.recolor(color_func=image_colors) # 将词云颜色设置为背景图方案

plt.imshow(wc) # 显示词云

plt.axis('off') # 关闭坐标轴

plt.show() # 显示图像

二、Flask可视化

from flask import Flask,render_template

import pymysql

app = Flask(__name__)

#路由

@app.route('/')

def hello_world():

    return render_template("index.html")

@app.route('/index')

def index():

    return render_template("index.html")

@app.route('/movie')

def movie():

    # 打开数据库连接

    db = pymysql.connect(host="81.68.122.101", user="root", password="123456", database="test")

    # 使用 cursor() 方法创建一个游标对象 cursor

    cursor = db.cursor()

    # 使用 execute()  方法执行 SQL 查询

    cursor.execute("select * from douban250")

    # 获取所有记录列表

    results = cursor.fetchall()

    data_list = []

    for item in results:

        data_list.append(item)

    # print(data_list)

    return render_template("movie.html",movies = data_list)

@app.route('/score')

def score():

    score = [] #评分

    num = [] #每个评分所统计出的电影数量

    # 打开数据库连接

 db = pymysql.connect(host="81.68.122.101", user="root", password="123456", database="test")

    # 使用 cursor() 方法创建一个游标对象 cursor

    cursor = db.cursor()

    # 使用 execute()  方法执行 SQL 查询

    cursor.execute("SELECT grade,COUNT(grade) FROM douban250 GROUP BY grade")

    results = cursor.fetchall()

    for item in results:

        score.append(item[0])

        num.append(item[1])

return render_template("score.html",score = score,num = num)

@app.route('/word')

def word():

    return render_template("word.html")

@app.route('/team')

def temp():

    return render_template("team.html"

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=8888)

结果:

导入数据:

处理完数据结果:

二、可视化结果

#  '导演', '主演', '类型', '制片国家/地区',这几列下面的值转化为列表

# 1、获取每一年上映的电影数量

# 2、按照电影上映年份进行排序

#3、绘制电影年份数量情况分布图

# 4、豆瓣评分&年份的情况分布的散点图

# 6、各个国家电影数量的分布情况

# 7、电影类型分布情况

# 8、导演数量分布前20

# 9、主演前20分布柱形图

# 10、查看电影时长柱形图

# 11、绘制评分人数与排名的散点图

# 12、豆瓣电影Top250评分-排名的散点分布

# 13、豆瓣top250电影排名&评分&评分人数情况

14、评论热词次统计及词云可视化

15、简介情感分析词云图

16、Flask可视化代码图

17、Flask可视化结果图

学习心得

    

此次,我们采用request,lxml,等库对豆瓣 TOP250 电影数据进行爬取,并用numpy,pandas,matplotlib 以及 wordcloud 等库对豆瓣 TOP250 电影数据进行数据分析处理,数据清洗pd.read_excel导入数据,df.isnull().any()检查数据缺失值,df.duplicated().sum()检查数据是否有重复。编剧、主演这一列有空值,数据有249条,说明各存在1个空值,详细看一下是哪一部电影 评分列格式是浮点型,评分人数是整型,都没有空值,接着对导演、主演、类型进行分割取值以便于后面的数据可视化。

从数据可视化分析我们可以得出,豆瓣电影 TOP250 看到很多演员主演的电影质量是很高的,中国演员张国荣、梁朝伟主演的电影,分别有8部,7部入围豆瓣top250,周星驰有6部入围;张国荣、梁朝伟一起主演的电影有3部入围,分别是《春光乍泄》、《射雕英雄传之东成西就》、《东邪西毒》。上榜次数最多的导演是宫崎骏,史蒂文·斯皮尔伯格以及克里斯托弗·诺兰等。上榜最多的是美国电影。剧情、爱情的电影居多。

我们从中也遇到许多的问题:如在爬取数据时老是遇到被封号,因此导入from selenium import webdriver 来模仿浏览器访问,以及运用sleep(5)来防止被封号。还有库的安装失败,网络爬虫的数据出现空值或爬取的数据不对, scrapy框架文件路径有问题无法运行;在拿取需要的数据时,对数据进行分组统计,使用了不再是传统的groupby,而是创新的方法from collections import Counter计数器。对字符串\列表\元祖\字典进行计数,返回一个字典类型的数据,键是元素,值是元素出现的次数;在可视化时,pyecharts库导入不了所以我们采用了matplotlib.pyplot ;jieba库分成把外国导演的名字分割错误,去掉了中间的一个点等等。结巴库分成把外国导演的名字分割错误是通过把名字读取进一个列表,再转换成字符串,并对其根据逗号进行分割然后统计绘制出词云图,在此过程中就没有用到结巴库了。

我们遇到的这些问题,经过我们的讨论和上网百度请问老师等得到了解决。经过这个实验我们也积累类关于网络爬虫,数据分析处理等经验,方便我们以后更好的操作和学习。我们会不停的学习,争取以后实验可以做到最好,提升自己的实力。

  • 35
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 豆瓣电影数据分析实战需要对豆瓣电影网站上的电影数据进行收集、整理、分析和可视化,以了解电影市场的趋势,评估电影的受欢迎程度和质量等方面。具体的需求如下: 1. 数据收集:从豆瓣电影网站上收集电影的基本信息、评分、评论等数据。 2. 数据整理:对收集到的数据进行清洗、去重、补全等处理,使其符合分析需求。 3. 数据分析:使用统计学方法和机器学习算法对电影数据进行分析,例如:分析电影类型、地区、时间趋势,分析电影评分分布、受众群体等。 4. 可视化展示:将数据分析结果以图表、地图等形式进行可视化展示,让用户更直观地了解电影市场的情况。 5. 用户画像分析:根据用户评论数据进行用户画像分析,了解不同类型电影的受众群体特征,为电影推广和营销提供参考。 6. 推荐算法:运用协同过滤、基于内容的推荐等算法,为用户推荐更符合其兴趣和口味的电影。 ### 回答2: 豆瓣电影数据分析实战的需求分析主要包括以下几个方面。 首先,需要对豆瓣电影的数据进行采集和清洗。采集可以使用网络爬虫技术获取豆瓣电影的相关信息,如电影名称、导演、演员、评分、评论等。在进行数据清洗的过程中,需要处理缺失值、重复值、错误值等问题,以保证后续分析的准确性和可靠性。 其次,需要进行对电影数据的统计分析。可以对电影评分进行平均值、中位数等统计指标的计算,以了解豆瓣电影的评分分布情况。还可以通过对不同类型电影的评分进行对比,探究不同类型电影的受欢迎程度。此外,还可以对导演和演员进行统计分析,比如哪些导演/演员的电影评分更高,哪些导演/演员的电影更受欢迎等。 第三,需要进行电影数据的可视化展示。可以利用柱状图、折线图、饼图等可视化手段展示电影评分分布、不同类型电影的评分对比、导演/演员的电影数量等信息,使分析结果更加直观和易于理解。 最后,可以进行电影推荐系统的开发。通过分析用户对电影的评分和评论,可以利用机器学习和推荐算法为用户推荐个性化的电影。例如,可以根据用户的历史评分记录,利用协同过滤算法预测用户对未评分电影的评分,并推荐评分较高的电影给用户。 综上所述,豆瓣电影数据分析实战的需求分析主要包括数据采集和清洗、统计分析、可视化展示以及电影推荐系统的开发等方面,通过这些分析和应用手段,可以更好地了解豆瓣电影的评分情况、导演演员的影响力,同时为用户提供个性化的电影推荐服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值