基于神经网络的个性化电影推荐

一、小组成员及分工

  • 1 巩卫参:3220180798 数据预处理、文档撰写
  • 2 戴云鹏:5720182061 构建模型、训练模型
  • 3 赵仁豪:3220180773 模型优化、文档撰写
  • 4 肖恩:3220180881 数据可视化、文档撰写

二、问题描述

由于个人喜好不同,喜欢的电影风格也就不尽相同,如果能够根据用户喜欢的电影类型,进行个性化的内容推荐,可以给用户带来很好的体验。为了解决这个问题,推荐系统应运而生,其中协同过滤是推荐系统中使用广泛的技术,该方法根据用户的历史记录、个人喜好等信息,计算与其他用户的相似度,利用相似用户的评价来预测目标用户对特定项目的喜欢程度。优点是会给用户推荐未浏览的项目,缺点是对于新用户来说,由于没有任何与商品的交互记录和个人喜好等信息,导致模型无法找到相似的用户或商品。本项目使用文本卷积神经网络,并使用MovieLens数据集完成电影推荐的任务。

三、数据集描述

使用MovieLens 1M 数据集, 数据集分为三个文件:用户数据users.dat,电影数据movies.da和评分数据ratings.dat。
用户数据有用户ID、性别、年龄、职业ID和邮编等,字段如下图所示:

电影数据有电影ID、电影名和电影风格等,如下图所示:

评分数据有用户ID、电影ID、评分和时间戳等,如下图所示:

四、阶段性结果展示

  • 数据预处理
    UserID、Occupation和MovieID不用变。
    Gender字段:需要将‘F’和‘M’转换成0和1。
    Age字段:要转成7个连续数字0~6。
    Genres字段:是分类字段,要转成数字。首先将Genres中的类别转成字符串到数字的字典,然后再将每个电影的Genres字段转成数字列表,因为有些电影是多个Genres的组合。
    Title字段:处理方式跟Genres字段一样,首先创建文本到数字的字典,然后将Title中的描述转成数字的列表。另外Title中的年份也需要去掉。
    Genres和Title字段需要将长度统一,这样在神经网络中方便处理。空白部分用‘< PAD >’对应的数字填充。
    预处理结果如下图所示:
    用户数据

    电影数据

  • 模型设计

通过研究数据集中的字段类型,我们发现有一些是类别字段,通常的处理是将这些字段转成one hot编码,但是像UserID、MovieID这样的字段就会变成非常的稀疏,输入的维度急剧膨胀,这是我们不愿意见到的,毕竟我这小笔记本不像大厂动辄能处理数以亿计维度的输入。
所以在预处理数据时将这些字段转成了数字,我们用这个数字当做嵌入矩阵的索引,在网络的第一层使用了嵌入层,维度是(N,32)和(N,16)。
电影类型的处理要多一步,有时一个电影有多个电影类型,这样从嵌入矩阵索引出来是一个(n,32)的矩阵,因为有多个类型嘛,我们要将这个矩阵求和,变成(1,32)的向量。电影名的处理比较特殊,没有使用循环神经网络,而是用了文本卷积网络,下文会进行说明。
从嵌入层索引出特征以后,将各特征传入全连接层,将输出再次传入全连接层,最终分别得到(1,200)的用户特征和电影特征两个特征向量。
我们的目的就是要训练出用户特征和电影特征,在实现推荐功能时使用。得到这两个特征以后,就可以选择任意的方式来拟合评分了。我使用了两种方式,一个是上图中画出的将两个特征做向量乘法,将结果与真实评分做回归,采用MSE优化损失。因为本质上这是一个回归问题,另一种方式是,将两个特征作为输入,再次传入全连接层,输出一个值,将输出值回归到真实评分,采用MSE优化损失。
实际上第二个方式的MSE loss在0.8附近,第一个方式在1附近,5次迭代的结果。

  • 文本卷积网络 网络看起来像下面这样

    网络的第一层是词嵌入层,由每一个单词的嵌入向量组成的嵌入矩阵。下一层使用多个不同尺寸(窗口大小)的卷积核在嵌入矩阵上做卷积,窗口大小指的是每次卷积覆盖几个单词。这里跟对图像做卷积不太一样,图像的卷积通常用2x2、3x3、5x5之类的尺寸,而文本卷积要覆盖整个单词的嵌入向量,所以尺寸是(单词数,向量维度),比如每次滑动3个,4个或者5个单词。第三层网络是max pooling得到一个长向量,最后使用dropout做正则化,最终得到了电影Title的特征。

五、仍需解决的问题

编码实现所设计的模型,构建神经网络,构建计算图,训练网络,调整参数,得到适当的用户特征矩阵、电影特征矩阵。测试模型,并将挖掘结果可视化。