2021年数维杯国际大学生数学建模
D题 2021年电影市场票房波动模型分析
原题再现:
1、电影票房预测建模背景
随着人们文化消费需求的增加,电影院和银幕的数量不断增加,我国的电影产业不断呈现出繁荣景象。2019年,全国电影票房642.66亿元。电影票房不仅直接反映了一部电影为投资公司创造的经济价值,也从侧面反映了电影的艺术品质和经营策略。它是衡量一部电影成功与否的重要指标。它自然地反映了电影作品的市场需求和投资吸引力的程度。。如果能够提前预测电影产品在市场上的接受度和盈利能力,将对电影产业链各个环节的决策产生巨大影响。因此,准确预测电影票房无疑对风险控制和决策具有重要的现实意义。
影响电影票房的因素有很多,比如电影本身的质量、放映时间、广告、社会环境、放映电影院的数量,甚至放映期间的天气。根据预测阶段的不同,票房预测分为前期预测和后期预测,即电影发行前后的票房预测。根据预测阶段的不同,票房预测分为前期预测和后期预测。对于电影的预预测,目前的研究成果包括:基于网络文本的电影类型与票房关系研究;基于明星效应、演员性别、导演水平等因素,研究了不同年级对电影票房的影响;基于神经网络算法研究电影上映日期、上映时间、上映季节等因素与票房的关系;训练多层感知器MLP神经网络对电影质量、人气等变量进行预发布数据处理,并根据预期收益对电影进行分类。电影后期票房预测采用反馈神经网络电影票房预测模型;票房预测考虑了导演、演员和时间表等因素;研究受众在社交网络、网络信息传播、网络搜索中的口碑传播对电影票房的积极影响。
2、电影在线舆情评分对票房的影响
随着我国互联网技术的不断发展,互联网已经成为电影营销的核心宣传媒介。目前,豆瓣、猫眼等电影评价平台大多不实行实名制,参与者具有多样性和复杂性。另外,结合互联网本身的特点,电影网络评价行为具有较强的匿名性和隐蔽性。这也使得雇佣“互联网海军”来不恰当地评估电影、购买票房和锁定电影行业的做法变得不常见。首先,网络的隐蔽性往往使被害人难以准确识别“网络海军”。其次,我国现行法律对“网络水军”对电影进行不当评价的认定和规范还存在不完善之处。基于此,如何识别和管理网络海军对电影的收视率已成为我国电影产业发展中亟待解决的问题。
3、突发事件对电影票房的影响
电影是一种公共娱乐,突发事件以道德和法律的形式对电影的票房产生了巨大的影响。2020年新冠病毒的突然爆发几乎摧毁了公众聚集的电影市场;如何运用模型分析各种突发事件对电影票房的影响显然是非常重要的。
建模中需要解决的主要问题有:
1、电影票房早期预测的核心是选择有效的预测特征。影响电影票房的因素是复杂的,衡量方法也各不相同。特征包括:电影时长、演员、导演、电影类型、电影格式(2D、3D、IMAX)、电影是否续集、上映日期、制作公司、发行公司等。根据电影分类的特点,考虑电影分类的特点、电影类型、导演等分类特点,导演评分等分类特征,对提供的数据集中的电影进行聚类和分类,并验证分类的有效性。
2、常用的票房预测模型包括多元回归、神经网络等,一些学者通过研究观众口碑传播、网络信息传播和社会网络中的网络搜索(见参考文献)对票房进行预测,建立了对电影票房有积极影响的电影票房预测模型,为电影市场的票房预测提供参考,根据提供的数据给出分类模型(标题1的结果),并预先给出每个类别的估计票房预测和总体票房预测。
3、收集豆瓣、猫眼等平台的电影在线舆情评价数据,建立识别网络舆情正负分的算法(标准化为[-1,1]);建立模型提取话题词、话题分类等重要指标;建立模型分析网络舆情与票房的相关性及对票房的影响程度;基于问题和现状,设计思路和具体方法来识别海军电影评分网络。该方法需要具有逻辑上的自洽性和可行性。
4、为应对新冠病毒的突然爆发,国家《电影院开业传染病防治指南》
考虑到疫情对模型的影响,分析其对电影票房的现实影响和未来预测,各场馆的上座率不应超过30%、50%、75%等。利用所提供的数据,模型分析了在疫情稳定后,不同出勤率(30%、50%、75%)对电影票房预测的影响。
整体求解过程概述(摘要)
近年来,我国电影产业不断呈现出繁荣的迹象,电影票房是衡量一部电影成功与否的重要指标,它也反映了电影的市场需求和投资吸引力。然而,影响电影票房的因素很多。电影本身的因素(电影的分类特征)、网络海军对电影的评价以及突发事件都会影响电影的票房。
在问题1中,我们只考虑电影本身的因素,主要研究电影的持续时间、黄金时段、首日票房、总票房等9个特征。然后采用TOPSIS法对9个特征进行评分和评价,并进行k均值聚类分析,将其划分为5类,验证了分类的有效性。
在第二个问题中,我们建立了BP神经网络模型,通过官网找到了2018年和2019年41部电影的相关数据,并将其作为训练样本加入到神经网络中。在得到训练好的神经网络后,我们开始预测电影的最终票房,然后进行误差分析,发现误差很小。
在第三个问题中,首先通过python爬虫对人脸襟翼和猫眼的评论数据进行爬网,然后利用网络的正负分识别建立DNN神经网络,建立主题词、主题分类等重要指标提取模型,使用词频统计方法计算某个词作为特征词的重要性,并将前200个特征显示在词云图中。以5000部电影为样本进行线性回归分析,得到的相关度不是很高。最后,基于logistic回归方法,提出了一种可行的网络海军识别算法。
在第四个问题中,由于可用数据相对较少,我们建立了一个更精确的SVM神经网络预测模型。同时,为了使预测结果更加可靠,采用《猫眼专业版》最终票房预测数据为26,对每部电影的最终票房进行求解,并根据实际情况对回归预测结果进行合理解释。
模型假设:
1、假设除影响本问题研究电影票房的电影分类特征外,其他电影分类特征对电影票房没有影响。
2、假设猫眼专业版预测的最终票房与真实的最终票房一致。
3、假设网络海军没有干预选定的电影评论。
4、假设处于高、中风险区域的电影院已关闭,未开放。
问题分析:
数据分析
我们通过豆瓣、猫眼等主要平台随机选取了67部电影。根据电影分类的特点:实时票房、时长、续集、豆瓣评分、电影格式、一线明星和知名导演数量、黄金时段、首日票房、总票房等分类特征,对提取的67部电影数据进行分类。我们将分类结果放入支持材料中。其中,我们对一些数据进行了近似处理,使计算更加容易。
问题一分析
在问题1中,我们根据电影的分类特征:实时票房、持续时间、续集、豆瓣评分、电影格式、一线明星和知名导演数量、黄金时段、首日票房、总票房等9个特征[1]采用多目标决策分析法TOPSIS法对26部电影进行评分,然后对得分进行k-means聚类分析[2],最后成功地验证了我们分类的有效性。
问题二分析
在第二个问题中,我们主要采用了BP神经网络算法[3]。根据历史数据对网络进行训练,输入训练集(即票房的各种信息),得到训练好的神经网络对2021年的电影进行预测。预测结果与实际票房差距仅为3.5%,说明我们的模型建立是成功的。
问题三分析
在第三个问题中,首先利用python爬虫对人脸襟翼和猫眼的评论数据进行爬网,然后利用网络的正负分识别建立DNN神经网络,以5000个电影数据为样本,进行线性回归分析。经过化学处理后发现,票房与预算、票数、人气有较强的正相关关系,但与收视率相关性不太强,相关系数仅为0.19。
问题四分析
在第四个问题中,我们使用更精确的SVM神经网络模型[4]来预测入住率为75%、50%、30%时的票房情况,即当限购率为75%时,对于高票房(如甲级电影)的票房影响最大,但对于相对低票房的电影,票房会增加;但当限制率为50%时,各类电影的票房都有一定程度的下降;当限值率为30%时,即当疫情较为严重时,影视业的经济形势处于低迷状态,票房也出现了严重下滑。最后,对结果进行了合理的分析。
模型的建立与求解整体论文缩略图
全部论文及程序请见下方“ 只会建模 QQ名片” 点击QQ名片即可
程序代码:
clc
clear
x=xlsread('The first question.xlsx','Sheet1','B2:I27');
[n,m]=size(x);
zh=zeros(1,m);
d1=zeros(1,n); %Minimum matrix
d2=zeros(1,n); %Maximum matrix
c=zeros(1,n); %Proximity
%Normalized
for i=1:m
for j=1:n
zh(i)=zh(i)+x(j,i)^2;
end
end
for i=1:m
for j=1:n
x(j,i)=x(j,i)/sqrt( zh(i));
end
end
%Calculate the distance
xx=min(x);
dd=max(x);
for i=1:n
for j=1:m
d1(i)=d1(i)+(x(i,j)-xx(j))^2;
end
d1(i)=sqrt(d1(i));
end
for i=1:n
for j=1:m
d2(i)=d2(i)+(x(i,j)-dd(j))^2;
end
d2(i)=sqrt(d2(i));
end
%Calculate proximity
for i=1:n
c(i)=d1(i)/(d2(i)+d1(i));
end
c_1=c';
%Calculate contour values
numC=10;
for i=1:numC
kidx = kmeans(c_1,i);
silh = silhouette(c_1,kidx); %Calculate the contour value
silh_m(i) = mean(silh); %Mean contour values were calculated
end
figure
plot(1:numC,silh_m,'ko-', 'linewidth',2)
set(gca,'linewidth',2);
xlabel('number of categories');
ylabel('mean contour value');
title(' average contour values corresponding to different categories');
%kMean cluster calculation process
[idx,ctr]=kmeans(c',5); % Clustering using K-means method
%Extract the sample number of the same category
c1=find(idx==1); c2=find(idx==2);
c3=find(idx==3); c4=find(idx==4);
c5=find(idx==5);
figure;
F1 = plot(find(idx==1), c(idx==1),'k:*', ... find(idx==2), c(idx==2),'k:o', ... find(idx==3), c(idx==3),'k:p', ... find(idx==4), c(idx==4),'k:d', ... find(idx==5), c(idx==5),'k:+');
set(gca,'linewidth',2);
set(F1,'linewidth',2, 'MarkerSize',8);
xlabel('serial number','fontsize',12);
ylabel('score','fontsize',12);
title('K-means clustering results');
disp('clustering results:');
disp(['class 1:' ,'center:',num2str(ctr(1)),' ','class sample number:', num2str(c1')]);
disp(['class 2:' ,'center:',num2str(ctr(2)),' ','class sample number:', num2str(c2')]);
disp(['class 3:' ,'center:',num2str(ctr(3)),' ','class sample number:', num2str(c3')]);
disp(['class 4:' ,'center:',num2str(ctr(4)),' ','class sample number:', num2str(c4')]);
disp(['class 5:' ,'center:',num2str(ctr(5)),' ','class sample number:', num2str(c5')]);
clc
clear
shichang=xlsread('First question.xlsx','Sheet2','B2:B42')';
xuji=xlsread('First question.xlsx','Sheet2','C2:C42')';
pingfen=xlsread('First question.xlsx','Sheet2','D2:D42')';
geshi=xlsread('First question.xlsx','Sheet2','E2:E42')';
mingxingshu=xlsread('First question.xlsx','Sheet2','F2:F42')';
huangjindang=xlsread('First question.xlsx','Sheet2','G2:G42')';
shouripiaofang=xlsread('First question.xlsx','Sheet2','H2:H42')';
shouriguanyingrenshu=xlsread('First question.xlsx','Sheet2','I2:I42')';
piaofang=xlsread('First question.xlsx','Sheet2','J2:J42')';
p=[shichang; xuji; pingfen; geshi; mingxingshu; huangjindang; shouripiaofang;
shouriguanyingrenshu;];
t=piaofang;
[pn, inputStr] = mapminmax(p);
[tn, outputStr] = mapminmax(t);
net = newff(pn, tn, [8 7 1], {'purelin', 'logsig', 'purelin'});
net.trainParam.show = 10;
net.trainParam.epochs = 5000;
net.trainParam.lr = 0.05;
net.trainParam.goal = 0.001;
net.divideFcn = '';
net = train(net, pn, tn);
answer = sim(net, pn);
answer1 = mapminmax('reverse', answer, outputStr);
t = 1:41;
a1 = answer1(1,:);
figure(1);
plot(t, a1, 'ro', t, piaofang, 'b+');
legend('predict box office', 'actual box office');
xlabel('movie number'); ylabel('box office (ten thousand yuan)');
title('Box office training value and real value comparison chart');
grid on;
wucha=(a1-piaofang)./piaofang;
figure;
plot(wucha,'r-^');
xlabel('movie number'); ylabel('relative error');
hold on;
newInput = [xlsread('First question.xlsx','Sheet1','B2:B27')';
xlsread('First question.xlsx','Sheet1','C2:C27')';
xlsread('First question.xlsx','Sheet1','D2:D27')';
xlsread('First question.xlsx','Sheet1','E2:E27')';
xlsread('First question.xlsx','Sheet1','F2:F27')';
xlsread('First question.xlsx','Sheet1','G2:G27')';
xlsread('First question.xlsx','Sheet1','H2:H27')';
xlsread('First question.xlsx','Sheet1','I2:I27')';];
%Use the normalization parameters of the original input data (the input data of the
training set) to normalize the new input data
newInput = mapminmax('apply', newInput, inputStr);
%Simulation
newOutput = sim(net, newInput);
%Denormalization
newOutput = mapminmax('reverse',newOutput, outputStr);
disp('Predict the box office for the other five movies: ');
abs(newOutput)
import urllib.request
from bs4 import BeautifulSoup
import random
import time
import csv
def getRequest(url):
header1 = {
"Host":"movie.douban.com", "User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" }
header2 = {
"Host": "movie.douban.com", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; rv:73.0) Gecko/20100101
Firefox/73.0" }
list = [header1,header2]
index = random.randint(0,len(list)-1)
req = urllib.request.Request(url=url,headers=list[index])
return req
def getData(url,commentAll):
req = getRequest(url)
html = urllib.request.urlopen(req)
data = html.read()
soup = BeautifulSoup(data,"html.parser")
comments = soup.select("#comments")[0]
items = comments.select(".comment-item")
for i in items:
info = i.select(".comment-info")[0]
author = info.find("a").string
star = info.select("span")[1]["title"]
short = i.select(".short")[0].string
talk = {"author":author,"star":star,"short":short}
commentAll.append(talk)
return commentAll
def writeInto(commentAll):
with open("douban.csv","a+",encoding="utf-8",newline="") as file:
writer = csv.writer(file)
for i in commentAll:
info = [i["author"],i["star"],i["short"]]
writer.writerow(info)
file.close()
if __name__ == '__main__':
commentAll = []
for i in range(0,3):
url =
"https://movie.douban.com/subject/25931446/comments?start=%d&limit=20&sort=n
ew_score&status=P"%(i*20)
getData(url,commentAll)
time.sleep(10)
writeInto(commentAll)