背景
随着Internet的日渐普及,人们对于看电影的需求不单单只是到电影院购买一张电影票这么简单了。手机、电脑上各种观影软件填补了许多人对于电影的渴望,但是如何能够在视频软件中快速、准确地定位到用户喜欢什么电影这种看不见摸不着的想法,成为了开发者一直探讨的问题。电影推荐系统在此种情景下应运而生,2006年Netflix的百万美金大赛将此类技术推向高潮,在那之后的十余年间,各种电影推荐算法层出不穷,对于用户的喜好判断也越来越精准。本次大作业是基于不同类型的电影受不同职业人群的欢迎程度来做的电影推荐,以平均评价为一项指标来推荐用户想要的电影。

技术路线
1.1已有相关技术介绍
已有的实现电影推荐的代码主要使用了以下技术:
一、 基于用户的协同过滤(User Collaborative Filtering,简称 UserCF)通过用户对不同内容(物品)的行为,来评测用户之间的相似性,找到“邻居”基于这种相似性做出推荐。

  1. 找到和目标用户兴趣相似的用户集合(关键在于计算两个用户之间的兴趣相似度)。
  2. 找到这个集合中的用户所喜欢的,并且目标用户没有使用(消费)过物品推荐给目标用户。

二、 基于物品的协同过滤(Item Collaboration Filter,简 称ItemCF)算法给用户推荐那些和他们之前喜欢的物品相似的物品。

  1. 计算物品之间的相似度;
  2. 根据物品的相似度和用户的历史行为给用户生 成推荐列表

1.2团队使用相关技术介绍
一、团队设计新的电影推荐系统时设计思路如下:
1.将电影信息及观影用户相关联
电影的种类和风格以及其他详细参数,会影响到观影人数,以及观影人数的评分,考虑电影本身和电影的受众,有助于提高电影推荐的准确度。
2.分析观影用户的相关信息
对于不同电影的观影人数以及观影人数的评分进行统计。
3.统计电影评分TOP N
电影的评分是用户对未知电影的数据参考,这一数据将从极大程度上影响用户对电影的选择。

二、团队在已有技术基础上设计新的电影推荐系统时使用了以下算法与技术:
1.surprise的使用
● 在推荐系统的建模过程中,我们将用到python库 Surprise(Simple Python Recommendation System Engine),是scikit系列中的一个。
● 简单易用,同时支持多种推荐算法:
✧ 基础算法/baseline algorithms
✧ 基于近邻方法(协同过滤)/neighborhood methods
✧ 矩阵分解方法/matrix factorization-based (SVD, PMF, SVD++, NMF)

2.协同过滤
两种协同过滤算法及其适用场景:
UserCF更适合对新颖性要求高的场景,比如新闻推荐,很少有用户只看某个话题的新闻,主要是因为这个话题不可能保证每天都有新的消息,而这个用户却是每天都要看新闻的。
ItemCF更适合用户兴趣稳定的场景,如购书、音乐和电影推荐。在这些场景中,用户的兴趣是比较固定和持久的,这些网站中个性化推荐的任务是帮助用户发现和其兴趣领域相关的物品。

二、结果展示

2.1 数值结果展示

第一模块:

输入电影类别号显示喜爱该类电影的职业前三位:

IMDB影评数据分析 数据清洗_数据挖掘

`import numpy as np
 import math
 #读取u.data数据
 def load_data():
 data = []
 f = open(‘ml-100k/u.data’)
 for i in range(100000):
 h = f.readline().split(’\t’)
 h = list(map(int, h))
 data.append(h[0:3])
 f.close()
 return data
 #读取item类别数据
 def load_class_data():
 id_and_class = []
 f = open(‘ml-100k/u.item’,encoding=‘ISO-8859-1’)
 for i in range(1682):
 h = f.readline().split(’|’)
 id_and_class.append([int(h[0])])
 h = list(map(int,h[5:]))
 id_and_class[i].append(h)
 f.close()
 return id_and_class
 #读取user工作数据
 def load_job():
 user_job = []
 f = open(‘ml-100k/u.user’)
 for i in range(943):
 h = f.readline().split(’|’)
 user_job.append([int(h[0])])
 user_job[i].append(h[3])
 f.close()
 return user_job
 #处理u.data数据,制成user-item评分表
 def user_cf_data(data):
 rate = []
 for i in range(943):
 rate.append([])
 for j in range(1682):
 rate[i].append(0)
 for h in data:
 rate[h[0] - 1][h[1] - 1] = h[2]
 return rate
 #获取所选种类电影id列表
 def class_id(data,num):
 id_list = []
 for i in range(1682):
 if data[i][1][num] == 1:
 id_list.append(data[i][0])
 return id_list
 #获取各个职业对该种类电影满分评价次数
 def single_favorite_job(data, id_list, user_job):
 n = len(id_list)
 list_favrite = []
 for i in range(21):
 list_favrite.append(0)
 for i in range(n):
 for j in range(943):
 if data[j][id_list[i]-1] == 5:
 if user_job[j][1] == ‘administrator’:
 list_favrite[0] += 1
 elif user_job[j][1] == ‘artist’:
 list_favrite[1] += 1
 elif user_job[j][1] == ‘doctor’:
 list_favrite[2] += 1
 elif user_job[j][1] == ‘educator’:
 list_favrite[3] += 1
 elif user_job[j][1] == ‘engineer’:
 list_favrite[4] += 1
 elif user_job[j][1] == ‘entertainment’:
 list_favrite[5] += 1
 elif user_job[j][1] == ‘executive’:
 list_favrite[6] += 1
 elif user_job[j][1] == ‘healthcare’:
 list_favrite[7] += 1
 elif user_job[j][1] == ‘homemaker’:
 list_favrite[8] += 1
 elif user_job[j][1] == ‘lawyer’:
 list_favrite[9] += 1
 elif user_job[j][1] == ‘librarian’:
 list_favrite[10] += 1
 elif user_job[j][1] == ‘marketing’:
 list_favrite[11] += 1
 elif user_job[j][1] == ‘none’:
 list_favrite[12] += 1
 elif user_job[j][1] == ‘other’:
 list_favrite[13] += 1
 elif user_job[j][1] == ‘programmer’:
 list_favrite[14] += 1
 elif user_job[j][1] == ‘retired’:
 list_favrite[15] += 1
 elif user_job[j][1] == ‘salesman’:
 list_favrite[16] += 1
 elif user_job[j][1] == ‘scientist’:
 list_favrite[17] += 1
 elif user_job[j][1] == ‘student’:
 list_favrite[18] += 1
 elif user_job[j][1] == ‘technician’:
 list_favrite[19] += 1
 elif user_job[j][1] == ‘writer’:
 list_favrite[20] += 1
 return list_favrite
 #获取各个职业对所有电影满分评价次数
 def total_favorite_job(data, user_job):
 list_favrite = []
 for i in range(21):
 list_favrite.append(0)
 for i in range(1682):
 for j in range(943):
 if data[j][i] == 5:
 if user_job[j][1] == ‘administrator’:
 list_favrite[0] += 1
 elif user_job[j][1] == ‘artist’:
 list_favrite[1] += 1
 elif user_job[j][1] == ‘doctor’:
 list_favrite[2] += 1
 elif user_job[j][1] == ‘educator’:
 list_favrite[3] += 1
 elif user_job[j][1] == ‘engineer’:
 list_favrite[4] += 1
 elif user_job[j][1] == ‘entertainment’:
 list_favrite[5] += 1
 elif user_job[j][1] == ‘executive’:
 list_favrite[6] += 1
 elif user_job[j][1] == ‘healthcare’:
 list_favrite[7] += 1
 elif user_job[j][1] == ‘homemaker’:
 list_favrite[8] += 1
 elif user_job[j][1] == ‘lawyer’:
 list_favrite[9] += 1
 elif user_job[j][1] == ‘librarian’:
 list_favrite[10] += 1
 elif user_job[j][1] == ‘marketing’:
 list_favrite[11] += 1
 elif user_job[j][1] == ‘none’:
 list_favrite[12] += 1
 elif user_job[j][1] == ‘other’:
 list_favrite[13] += 1
 elif user_job[j][1] == ‘programmer’:
 list_favrite[14] += 1
 elif user_job[j][1] == ‘retired’:
 list_favrite[15] += 1
 elif user_job[j][1] == ‘salesman’:
 list_favrite[16] += 1
 elif user_job[j][1] == ‘scientist’:
 list_favrite[17] += 1
 elif user_job[j][1] == ‘student’:
 list_favrite[18] += 1
 elif user_job[j][1] == ‘technician’:
 list_favrite[19] += 1
 elif user_job[j][1] == ‘writer’:
 list_favrite[20] += 1
 return list_favrite
 #计算各个职业对该类电影满分评价占对所有电影满分评价百分比
 def cala_percent(single_favorite,total_favorite):
 percent_favorite = []
 for i in range(21):
 percent_favorite.append(float(single_favorite[i])/float(total_favorite[i]))
 return percent_favorite
 #排序并输出结果
 def print_favorite_job(percent_favorite):
 f = open(‘ml-100k/u.occupation’)
 job = []
 for i in range(21):
 h = f.readline().split(’\n’)
 job.append(h[0])
 f.close()
 for i in range(21):
 for j in range(20-i):
 if percent_favorite[j] < percent_favorite[j+1]:
 mid = percent_favorite[j]
 percent_favorite[j] = percent_favorite[j+1]
 percent_favorite[j+1] = mid
 mid = job[j]
 job[j] = job[j+1]
 job[j+1] = mid
 print(‘最喜爱该类电影的职业是:’ + job[0] + ‘\n’ + ‘第二喜爱该类电影的职业是:’ + job[1] + ‘\n’ + ‘第三喜爱该类电影的职业是:’ + job[2] + ‘\n’)
item_class = load_class_data()
 user_job = load_job()
 data = load_data()
 user_rate = user_cf_data(data)
 id_input = int(input(‘enter movie class id :’))
 id_list = class_id(item_class,id_input)total_favorite = total_favorite_job(user_rate, user_job)
 single_favorite = single_favorite_job(user_rate, id_list, user_job)
 percent_favorite = cala_percent(single_favorite,total_favorite)print_favorite_job(percent_favorite)`

第二模块:

输入职业号显示喜爱的电影种类前三位:

IMDB影评数据分析 数据清洗_ci_02

import numpy as np
 import math
def load_data():
 data = []
 f = open(‘ml-100k/u.data’)
 for i in range(100000):
 h = f.readline().split(’\t’)
 h = list(map(int, h))
 data.append(h[0:3])
 f.close()
 return datadef load_class_data():
 id_and_class = []
 f = open(‘ml-100k/u.item’,encoding=‘ISO-8859-1’)
 for i in range(1682):
 h = f.readline().split(’|’)
 id_and_class.append([int(h[0])])
 h = list(map(int,h[5:]))
 id_and_class[i].append(h)
 f.close()
 return id_and_classdef user_cf_data(data):
 rate = []
 for i in range(943):
 rate.append([])
 for j in range(1682):
 rate[i].append(0)
 for h in data:
 rate[h[0] - 1][h[1] - 1] = h[2]
 return ratedef load_job():
 user_job = []
 f = open(‘ml-100k/u.user’)
 for i in range(943):
 h = f.readline().split(’|’)
 user_job.append([int(h[0])])
 user_job[i].append(h[3])
 f.close()
 return user_jobdef user_id(user_job, num):
 id_list = []
 job = []
 f = open(‘ml-100k/u.occupation’)
 for i in range(21):
 h = f.readline().split(’\n’)
 job.append(h[0])
 f.close()
 for i in range(943):
 if user_job[i][1] == job[num]:
 id_list.append(user_job[i][0])
 return id_listdef calafavo(data, id_list, item_class):
 n = len(id_list)
 total_favorite = 0
 list_favorite = []
 percent = []
 for i in range(19):
 list_favorite.append(0)
 for i in range(n):
 for j in range(1682):
 if data[id_list[i]-1][j] == 5:
 total_favorite += 1
 if item_class[id_list[i]-1][1][0] == 1:
 list_favorite[0] += 1
 elif item_class[id_list[i]-1][1][1] == 1:
 list_favorite[1] += 1
 elif item_class[id_list[i]-1][1][2] == 1:
 list_favorite[2] += 1
 elif item_class[id_list[i]-1][1][3] == 1:
 list_favorite[3] += 1
 elif item_class[id_list[i]-1][1][4] == 1:
 list_favorite[4] += 1
 elif item_class[id_list[i]-1][1][5] == 1:
 list_favorite[5] += 1
 elif item_class[id_list[i]-1][1][6] == 1:
 list_favorite[6] += 1
 elif item_class[id_list[i]-1][1][7] == 1:
 list_favorite[7] += 1
 elif item_class[id_list[i]-1][1][8] == 1:
 list_favorite[8] += 1
 elif item_class[id_list[i]-1][1][9] == 1:
 list_favorite[9] += 1
 elif item_class[id_list[i]-1][1][10] == 1:
 list_favorite[10] += 1
 elif item_class[id_list[i]-1][1][11] == 1:
 list_favorite[11] += 1
 elif item_class[id_list[i]-1][1][12] == 1:
 list_favorite[12] += 1
 elif item_class[id_list[i]-1][1][13] == 1:
 list_favorite[13] += 1
 elif item_class[id_list[i]-1][1][14] == 1:
 list_favorite[14] += 1
 elif item_class[id_list[i]-1][1][15] == 1:
 list_favorite[15] += 1
 elif item_class[id_list[i]-1][1][16] == 1:
 list_favorite[16] += 1
 elif item_class[id_list[i]-1][1][17] == 1:
 list_favorite[17] += 1
 elif item_class[id_list[i]-1][1][18] == 1:
 list_favorite[18] += 1
 for i in range(19):
 percent.append(float(list_favorite[i])/float(total_favorite))
 return percentdef print_favorite_class(percent_favorite):
 f = open(‘ml-100k/u.genre’)
 cla = []
 for i in range(21):
 h = f.readline().split(’|’)
 cla.append(h[0])
 f.close()
 for i in range(19):
 for j in range(18-i):
 if percent_favorite[j] < percent_favorite[j+1]:
 mid = percent_favorite[j]
 percent_favorite[j] = percent_favorite[j+1]
 percent_favorite[j+1] = mid
 mid = cla[j]
 cla[j] = cla[j+1]
 cla[j+1] = mid
 print(‘该职业最喜爱的电影种类是:’ + cla[0] + ‘\n’ + ‘该职业第二喜爱的电影种类是:’ + cla[1] + ‘\n’ + ‘该职业第三喜爱的电影种类是:’ + cla[2] + ‘\n’)data = load_data()
 user_rate = user_cf_data(data)
 item_class = load_class_data()
 user_job = load_job()
 job_list=[‘administrator’,‘artist’,‘doctor’,‘educator’,‘engineer’,‘entertainment’,‘executive’,‘healthcare’,‘homemaker’,‘lawyer’,
 ‘librarian’,‘marketing’,‘none’,‘other’,‘programmer’,‘retired’,‘salesman’,‘scientist’,‘student’,‘technician’,‘writer’]
 for i in range(21):
 print(’[’+str(i).rjust(2)+’]’+ job_list[i])
 id_input = int(input(‘enter job id:’))
 id_list = user_id(user_job, id_input)
 percent = calafavo(user_rate, id_list, item_class)print_favorite_class(percent)

第三模块:

结合前两种算法和推荐方法得出电影推荐结果:

1.自动推荐平均评价在前十的电影:

IMDB影评数据分析 数据清洗_IMDB影评数据分析 数据清洗_03

2.输入电影序号查看与其相似的电影以及喜欢该电影的用户还喜欢哪些电影:

IMDB影评数据分析 数据清洗_数据_04

方法流程图

IMDB影评数据分析 数据清洗_python_05

2.2 与参照方法的对比
团队对于计算出与某部电影相近的其他电影所采用的方法是循环获取用户输入,根据用户输入的电影ID,基于itemCF推荐算法,获取十个相似电影,与基于皮尔逊相似计算得到的结果差异如下:

基于用户推荐得到与某部电影相近的十部电影:

IMDB影评数据分析 数据清洗_python_06

团队的方法得到与某部电影相近的十部电影:

IMDB影评数据分析 数据清洗_数据挖掘_07