人工智能学习与实训笔记(六):神经网络之智能推荐系统

慈云数据 2024-03-12 技术支持 111 0

人工智能专栏文章汇总:人工智能学习专栏文章汇总-CSDN博客

本篇目录

七、智能推荐系统处理

7.1 常用的推荐系统算法

7.2 如何实现推荐

7.3 基于飞桨实现的电影推荐模型

7.3.1 电影数据类型

7.3.2 数据处理

7.3.4 数据读取器

7.3.4 网络构建

7.3.4.1用户特征提取

7.3.4.2 电影特征提取

7.3.4.3 相似度计算

7.3.4.4 网络模型完整代码

7.3 根据推荐案例的思考


七、智能推荐系统处理

7.1 常用的推荐系统算法

常用的推荐系统算法实现方案有三种:

  1. 协同过滤推荐(Collaborative Filtering Recommendation):该算法的核心是分析用户的兴趣和行为,利用共同行为习惯的群体有相似喜好的原则,推荐用户感兴趣的信息。兴趣有高有低,算法会根据用户对信息的反馈(如评分)进行排序,这种方式在学术上称为协同过滤。协同过滤算法是经典的推荐算法,经典意味着简单、好用。协同过滤算法又可以简单分为两种:

    a)基于用户的协同过滤:根据用户的历史喜好分析出相似兴趣的人,然后给用户推荐其他人喜欢的物品。假如小李,小张对物品A、B都给了十分好评,那么可以认为小李、小张具有相似的兴趣爱好,如果小李给物品C十分好评,那么可以把C推荐给小张,可简单理解为“人以类聚”。

    基于用户初始选择后续选择系统推荐
    小李ABC 
    小张AB C

    b)基于物品的协同过滤:根据用户的历史喜好分析出相似物品,然后给用户推荐同类物品。比如小李对物品A、B、C给了十分好评,小王对物品A、C给了十分好评,从这些用户的喜好中分析出喜欢A的人都喜欢C,物品A、C是相似的,如果小张给了A好评,那么可以把C也推荐给小张,可简单理解为“物以群分”。

    基于物品初始选择后续选择系统推荐
    小李ABC  
    小王AC  
    小张A C
  2. 基于内容过滤推荐(Content-based Filtering Recommendation):基于内容的过滤是信息检索领域的重要研究内容,是更为简单直接的算法,该算法的核心是衡量出两个物品的相似度。首先对物品或内容的特征作出描述,发现其相关性,然后基于用户以往的喜好记录,推荐给用户相似的物品。比如,小张对物品A感兴趣,而物品A和物品C是同类物品(从物品的内容描述上判断),可以把物品C也推荐给小张。

  3. 组合推荐(Hybrid Recommendation):以上算法各有优缺点,比如基于内容的过滤推荐是基于物品建模,在系统启动初期往往有较好的推荐效果,但是没有考虑用户群体的关联属性;协同过滤推荐考虑了用户群体喜好信息,可以推荐内容上不相似的新物品,发现用户潜在的兴趣偏好,但是这依赖于足够多且准确的用户历史信息。所以,实际应用中往往不只采用某一种推荐方法,而是通过一定的组合方法将多个算法混合在一起,以实现更好的推荐效果,比如加权混合、分层混合等。具体选择哪种方式和应用场景有很大关系。

7.2 如何实现推荐

以电影推荐为例:

如果能将用户A的原始特征转变成一种代表用户A喜好的特征向量,将电影1的原始特征转变成一种代表电影1特性的特征向量。那么,我们计算两个向量的相似度,就可以代表用户A对电影1的喜欢程度。据此,推荐系统可以如此构建:

假如给用户A推荐,计算电影库中“每一个电影的特征向量”与“用户A的特征向量”的余弦相似度,根据相似度排序电影库,取 Top k的电影推荐给A。

这样设计的核心是两个特征向量的有效性,它们会决定推荐的效果。

基于以上思路,可以将电影推荐网络模型设计如下:

  • 将用户信息和电影信息的各类数据提取为向量(通过embedding,分别得到ID,性别,职业等等的特征向量)
  • 再将各个类别的特征向量进行整合计算(全连接),综合得到每个用户的特征向量(200维)和每个电影的特征向量(200维),
  • 将两个特征向量进行比较(余弦相似度),得到预测评分
  • 将预测评分和实际评分进行比较并使得分差收敛,从而完成网络训练

    最终在完成模型训练时,将获得所有用户和电影的特征向量,正是基于这些向量,我们可以比较用户和电影的特征相似度,从而进行推荐。所以我们并不是直接使用网络来进行电影推荐。

    7.3 基于飞桨实现的电影推荐模型

    7.3.1 电影数据类型

    本次实践我们采用ml-1m电影推荐数据集,它是GroupLens Research从MovieLens网站上收集并提供的电影评分数据集。包含了6000多位用户对近3900个电影的共100万条评分数据,评分均为1~5的整数,其中每个电影的评分数据至少有20条。该数据集包含三个数据文件,分别是:

    • users.dat:存储用户属性信息的文本格式文件。
    • movies.dat:存储电影属性信息的文本格式文件。
    • ratings.dat:存储电影评分信息的文本格式文件。
    • posters:包含部分电影海报图像。
    • new_rating.txt:存储包含海报图像的新评分数据文件。

      用户信息、电影信息和评分信息包含的内容如下表所示。

      用户信息UserIDGenderAgeOccupation
      样例1F【M/F】110
      电影信息MovieIDTitleGenresPosterID
      样例1Toy StoryAnimation| Children's|Comedy1
      评分信息UserIDMovieIDRating
      样例111935【1~5】

      其中部分数据并不具有真实的含义,而是编号。年龄编号和部分职业编号的含义如下表所示。

      年龄编号职业编号
      • 1: "Under 18"
      • 18: "18-24"
      • 25: "25-34"
      • 35: "35-44"
      • 45: "45-49"
      • 50: "50-55"
      • 56: "56+"
      • 0: "other" or not specified
      • 1: "academic/educator"
      • 2: "artist"
      • 3: "clerical/admin"
      • 4: "college/grad student"
      • 5: "customer service"
      • 6: "doctor/health care"
      • 7: "executive/managerial"

      海报对应着尺寸大约为180*270的图片,每张图片尺寸稍有差别。

      从样例的特征数据中,我们可以分析出特征一共有四类:

      1. ID类特征:UserID、MovieID、Gender、Age、Occupation,内容为ID值,前两个ID映射到具体用户和电影,后三个ID会映射到具体分档。
      2. 列表类特征:Genres,每个电影有多个类别标签。如果将电影类别编号,使用数字ID替换原始类别,特征内容是对应几个ID值的列表。
      3. 图像类特征:Poster,内容是一张180×270的图片。
      4. 文本类特征:Title,内容是一段英文文本。

      因为特征数据有四种不同类型,所以构建模型网络的输入层预计也会有四种子结构。

      7.3.2 数据处理

      用户数据处理:

      import numpy as np
      def get_usr_info(path):
          # 性别转换函数,M-0, F-1
          def gender2num(gender):
              return 1 if gender == 'F' else 0
          
          # 打开文件,读取所有行到data中
          with open(path, 'r') as f:
              data = f.readlines()
          # 建立用户信息的字典
          use_info = {}
          
          max_usr_id = 0
          #按行索引数据
          for item in data:
              # 去除每一行中和数据无关的部分
              item = item.strip().split("::")
              usr_id = item[0]
              # 将字符数据转成数字并保存在字典中
              use_info[usr_id] = {'usr_id': int(usr_id),
                                  'gender': gender2num(item[1]),
                                  'age': int(item[2]),
                                  'job': int(item[3])}
              max_usr_id = max(max_usr_id, int(usr_id))
          
          return use_info, max_usr_id
      usr_file = "./work/ml-1m/users.dat"
      usr_info, max_usr_id = get_usr_info(usr_file)
      print("用户数量:", len(usr_info))
      print("最大用户ID:", max_usr_id)
      print("第1个用户的信息是:", usr_info['1'])
      ------------------------------------------------------------------------------
      用户数量: 6040
      最大用户ID: 6040
      第1个用户的信息是: {'usr_id': 1, 'gender': 1, 'age': 1, 'job': 10}
      

      电影数据处理:

      def get_movie_info(path):
          # 打开文件,编码方式选择ISO-8859-1,读取所有数据到data中 
          with open(path, 'r', encoding="ISO-8859-1") as f:
              data = f.readlines()
          # 建立三个字典,分别用户存放电影所有信息,电影的名字信息、类别信息
          movie_info, movie_titles, movie_cat = {}, {}, {}
          # 对电影名字、类别中不同的单词计数
          t_count, c_count = 1, 1
          # 初始化电影名字和种类的列表
          titles = []
          cats = []
          count_tit = {}
          # 按行读取数据并处理
          for item in data:
              item = item.strip().split("::")
              v_id = item[0]
              v_title = item[1][:-7]
              cats = item[2].split('|')
              v_year = item[1][-5:-1]
              titles = v_title.split()
              # 统计电影名字的单词,并给每个单词一个序号,放在movie_titles中
              for t in titles:
                  if t not in movie_titles:
                      movie_titles[t] = t_count
                      t_count += 1
              # 统计电影类别单词,并给每个单词一个序号,放在movie_cat中
              for cat in cats:
                  if cat not in movie_cat:
                      movie_cat[cat] = c_count
                      c_count += 1
              # 补0使电影名称对应的列表长度为15
              v_tit = [movie_titles[k] for k in titles]
              while len(v_tit)
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon