当前位置: 首页 > 编程笔记 >

python实现协同过滤推荐算法完整代码示例

益锦程
2023-03-14
本文向大家介绍python实现协同过滤推荐算法完整代码示例,包括了python实现协同过滤推荐算法完整代码示例的使用技巧和注意事项,需要的朋友参考一下

测试数据

http://grouplens.org/datasets/movielens/

协同过滤推荐算法主要分为:

1、基于用户。根据相邻用户,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表进行推荐

2、基于物品。如喜欢物品A的用户都喜欢物品C,那么可以知道物品A与物品C的相似度很高,而用户C喜欢物品A,那么可以推断出用户C也可能喜欢物品C。

不同的数据、不同的程序猿写出的协同过滤推荐算法不同,但其核心是一致的:

1、收集用户的偏好

1)不同行为分组

2)不同分组进行加权计算用户的总喜好

3)数据去噪和归一化

2、找到相似用户(基于用户)或者物品(基于物品)

3、计算相似度并进行排序。根据相似度为用户进行推荐

本次实例过程:

1、初始化数据

获取movies和ratings

转换成数据userDict表示某个用户的所有电影的评分集合,并对评分除以5进行归一化

转换成数据ItemUser表示某部电影参与评分的所有用户集合

2、计算所有用户与userId的相似度

找出所有观看电影与userId有交集的用户

对这些用户循环计算与userId的相似度

获取A用户与userId的并集。格式为:{'电影ID',[A用户的评分,userId的评分]},没有评分记为0

计算A用户与userId的余弦距离,越大越相似

3、根据相似度生成推荐电影列表

4、输出推荐列表和准确率

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from numpy import *
import time
from texttable import Texttable
class CF:
  def __init__(self, movies, ratings, k=5, n=10):
    self.movies = movies
    self.ratings = ratings
    # 邻居个数
    self.k = k
    # 推荐个数
    self.n = n
    # 用户对电影的评分
    # 数据格式{'UserID:用户ID':[(MovieID:电影ID,Rating:用户对电影的评星)]}
    self.userDict = {}
    # 对某电影评分的用户
    # 数据格式:{'MovieID:电影ID',[UserID:用户ID]}
    # {'1',[1,2,3..],...}
    self.ItemUser = {}
    # 邻居的信息
    self.neighbors = []
    # 推荐列表
    self.recommandList = []
    self.cost = 0.0

  # 基于用户的推荐
  # 根据对电影的评分计算用户之间的相似度
  def recommendByUser(self, userId):
    self.formatRate()
    # 推荐个数 等于 本身评分电影个数,用户计算准确率
    self.n = len(self.userDict[userId])
    self.getNearestNeighbor(userId)
    self.getrecommandList(userId)
    self.getPrecision(userId)

  # 获取推荐列表
  def getrecommandList(self, userId):
    self.recommandList = []
    # 建立推荐字典
    recommandDict = {}
    for neighbor in self.neighbors:
      movies = self.userDict[neighbor[1]]
      for movie in movies:
        if(movie[0] in recommandDict):
          recommandDict[movie[0]] += neighbor[0]
        else:
          recommandDict[movie[0]] = neighbor[0]

    # 建立推荐列表
    for key in recommandDict:
      self.recommandList.append([recommandDict[key], key])
    self.recommandList.sort(reverse=True)
    self.recommandList = self.recommandList[:self.n]

  # 将ratings转换为userDict和ItemUser
  def formatRate(self):
    self.userDict = {}
    self.ItemUser = {}
    for i in self.ratings:
      # 评分最高为5 除以5 进行数据归一化
      temp = (i[1], float(i[2]) / 5)
      # 计算userDict {'1':[(1,5),(2,5)...],'2':[...]...}
      if(i[0] in self.userDict):
        self.userDict[i[0]].append(temp)
      else:
        self.userDict[i[0]] = [temp]
      # 计算ItemUser {'1',[1,2,3..],...}
      if(i[1] in self.ItemUser):
        self.ItemUser[i[1]].append(i[0])
      else:
        self.ItemUser[i[1]] = [i[0]]

  # 找到某用户的相邻用户
  def getNearestNeighbor(self, userId):
    neighbors = []
    self.neighbors = []
    # 获取userId评分的电影都有那些用户也评过分
    for i in self.userDict[userId]:
      for j in self.ItemUser[i[0]]:
        if(j != userId and j not in neighbors):
          neighbors.append(j)
    # 计算这些用户与userId的相似度并排序
    for i in neighbors:
      dist = self.getCost(userId, i)
      self.neighbors.append([dist, i])
    # 排序默认是升序,reverse=True表示降序
    self.neighbors.sort(reverse=True)
    self.neighbors = self.neighbors[:self.k]

  # 格式化userDict数据
  def formatuserDict(self, userId, l):
    user = {}
    for i in self.userDict[userId]:
      user[i[0]] = [i[1], 0]
    for j in self.userDict[l]:
      if(j[0] not in user):
        user[j[0]] = [0, j[1]]
      else:
        user[j[0]][1] = j[1]
    return user

  # 计算余弦距离
  def getCost(self, userId, l):
    # 获取用户userId和l评分电影的并集
    # {'电影ID':[userId的评分,l的评分]} 没有评分为0
    user = self.formatuserDict(userId, l)
    x = 0.0
    y = 0.0
    z = 0.0
    for k, v in user.items():
      x += float(v[0]) * float(v[0])
      y += float(v[1]) * float(v[1])
      z += float(v[0]) * float(v[1])
    if(z == 0.0):
      return 0
    return z / sqrt(x * y)

  # 推荐的准确率
  def getPrecision(self, userId):
    user = [i[0] for i in self.userDict[userId]]
    recommand = [i[1] for i in self.recommandList]
    count = 0.0
    if(len(user) >= len(recommand)):
      for i in recommand:
        if(i in user):
          count += 1.0
      self.cost = count / len(recommand)
    else:
      for i in user:
        if(i in recommand):
          count += 1.0
      self.cost = count / len(user)

  # 显示推荐列表
  def showTable(self):
    neighbors_id = [i[1] for i in self.neighbors]
    table = Texttable()
    table.set_deco(Texttable.HEADER)
    table.set_cols_dtype(["t", "t", "t", "t"])
    table.set_cols_align(["l", "l", "l", "l"])
    rows = []
    rows.append([u"movie ID", u"Name", u"release", u"from userID"])
    for item in self.recommandList:
      fromID = []
      for i in self.movies:
        if i[0] == item[1]:
          movie = i
          break
      for i in self.ItemUser[item[1]]:
        if i in neighbors_id:
          fromID.append(i)
      movie.append(fromID)
      rows.append(movie)
    table.add_rows(rows)
    print(table.draw())
# 获取数据
def readFile(filename):
  files = open(filename, "r", encoding="utf-8")
  # 如果读取不成功试一下
  # files = open(filename, "r", encoding="iso-8859-15")
  data = []
  for line in files.readlines():
    item = line.strip().split("::")
    data.append(item)
  return data

# -------------------------开始-------------------------------
start = time.clock()
movies = readFile("/home/hadoop/Python/CF/movies.dat")
ratings = readFile("/home/hadoop/Python/CF/ratings.dat")
demo = CF(movies, ratings, k=20)
demo.recommendByUser("100")
print("推荐列表为:")
demo.showTable()
print("处理的数据为%d条" % (len(demo.ratings)))
print("准确率: %.2f %%" % (demo.cost * 100))
end = time.clock()
print("耗费时间: %f s" % (end - start))

总结

以上就是本文关于python实现协同过滤推荐算法完整代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

python实现机械分词之逆向最大匹配算法代码示例

K-近邻算法的python实现代码分享

详解K-means算法在Python中的实现

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

 类似资料:
  • SimRank是基于图论的,如果用于推荐算法,则它假设用户和物品在空间中形成了一张图。而这张图是一个二部图。所谓二部图就是图中的节点可以分成两个子集,而图中任意一条边的两个端点分别来源于这两个子集。一个二部图的例子如下图。从图中也可以看出,二部图的子集内部没有边连接。对于我们的推荐算法中的SimRank,则二部图中的两个子集可以是用户子集和物品子集。而用户和物品之间的一些评分数据则构成了我们的二部

  • 本文向大家介绍Java编程实现基于用户的协同过滤推荐算法代码示例,包括了Java编程实现基于用户的协同过滤推荐算法代码示例的使用技巧和注意事项,需要的朋友参考一下 协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相

  • 1.矩阵分解用于推荐算法要解决的问题     在推荐系统中,我们常常遇到的问题是这样的,我们有很多用户和物品,也有少部分用户对少部分物品的评分,我们希望预测目标用户对其他未评分物品的评分,进而将评分高的物品推荐给目标用户。比如下面的用户物品评分表: 用户物品 物品1 物品2 物品3 物品4 物品5 物品6 物品7 用户1 3 5 1 用户2 2 4 用户3 4 用户4 2 1 用户5 1 4   

  • 本文向大家介绍java算法实现红黑树完整代码示例,包括了java算法实现红黑树完整代码示例的使用技巧和注意事项,需要的朋友参考一下 红黑树 定义 红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。 红黑树的另一种定义是含有红黑链接并满足下列条件的二叉查找树: 红链接均为左链接;没有任何一个结点同时和两条红链接相连;该树

  • 本文向大家介绍Java编程实现A*算法完整代码,包括了Java编程实现A*算法完整代码的使用技巧和注意事项,需要的朋友参考一下 前言 A*搜寻算法俗称A星算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。常用于游戏中 通过二维数组构建的一个迷宫,“%”表示墙壁,A为起点,B为终点,“#”代表障碍物,“*”代表算法计算后的路径 本文实例代码结构: 算法理论 算法的核心公式为:F=

  • 本文向大家介绍用Python实现协同过滤的教程,包括了用Python实现协同过滤的教程的使用技巧和注意事项,需要的朋友参考一下 协同过滤 在 用户 —— 物品(user - item)的数据关系下很容易收集到一些偏好信息(preference),比如评分。利用这些分散的偏好信息,基于其背后可能存在的关联性,来为用户推荐物品的方法,便是协同过滤,或称协作型过滤(collaborative filte

  • 本文向大家介绍JAVA实现较完善的布隆过滤器的示例代码,包括了JAVA实现较完善的布隆过滤器的示例代码的使用技巧和注意事项,需要的朋友参考一下 布隆过滤器是可以用于判断一个元素是不是在一个集合里,并且相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数。但是它也是拥有一定的缺点:布隆过滤器是有一定的误识别率以及删除困难的。本文中给出的布隆过滤器

  • 本文向大家介绍Python实现EM算法实例代码,包括了Python实现EM算法实例代码的使用技巧和注意事项,需要的朋友参考一下 EM算法实例 通过实例可以快速了解EM算法的基本思想,具体推导请点文末链接。图a是让我们预热的,图b是EM算法的实例。 这是一个抛硬币的例子,H表示正面向上,T表示反面向上,参数θ表示正面朝上的概率。硬币有两个,A和B,硬币是有偏的。本次实验总共做了5组,每组随机选一个硬