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中的实现

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

(0)

相关推荐

  • Python数据结构与算法之完全树与最小堆实例

    本文实例讲述了Python数据结构与算法之完全树与最小堆.分享给大家供大家参考,具体如下: # 完全树 最小堆 class CompleteTree(list): def siftdown(self,i): """ 对一颗完全树进行向下调整,传入需要向下调整的节点编号i 当删除了最小的元素后,当新增加一个数被放置到堆顶时, 如果此时不符合最小堆的特性,则需要将这个数向下调整,直到找到合适的位置为止""" n = len(self) # 当 i 节

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

    逆向最大匹配方法 有正即有负,正向最大匹配算法大家可以参阅http://www.jb51.net/article/127404.htm 逆向最大匹配分词是中文分词基本算法之一,因为是机械切分,所以它也有分词速度快的优点,且逆向最大匹配分词比起正向最大匹配分词更符合人们的语言习惯.逆向最大匹配分词需要在已有词典的基础上,从被处理文档的末端开始匹配扫描,每次取最末端的i个字符(分词所确定的阈值i)作为匹配字段,若匹配失败,则去掉匹配字段最前面的一个字,继续匹配.而且选择的阈值越大,分词越慢,但准确性

  • Python使用三种方法实现PCA算法

    主成分分析,即Principal Component Analysis(PCA),是多元统计中的重要内容,也广泛应用于机器学习和其它领域.它的主要作用是对高维数据进行降维.PCA把原先的n个特征用数目更少的k个特征取代,新特征是旧特征的线性组合,这些线性组合最大化样本方差,尽量使新的k个特征互不相关.关于PCA的更多介绍,请参考:https://en.wikipedia.org/wiki/Principal_component_analysis. 主成分分析(PCA) vs 多元判别式分析(MD

  • Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个点到其他各顶点的路径--单源最短路径 # 初始化图参数 G = {1:{1:0, 2:1, 3:12}, 2:{2:0, 3:9, 4:3}, 3:{3:0, 5:5}, 4:{3:4, 4:0, 5:13, 6:15}, 5:{5:0, 6:4}, 6:{6:0}} # 每次找到离源点最近的一个顶

  • Python数据结构与算法之字典树实现方法示例

    本文实例讲述了Python数据结构与算法之字典树实现方法.分享给大家供大家参考,具体如下: class TrieTree(): def __init__(self): self.root = {} def addNode(self,str): # 树中每个结点(除根节点),包含到该结点的单词数,以及该结点后面出现字母的键 nowdict = self.root for i in range(len(str)): if str[i] not in nowdict: # 发现新的组合方式 nowdi

  • Python数据结构与算法之二叉树结构定义与遍历方法详解

    本文实例讲述了Python数据结构与算法之二叉树结构定义与遍历方法.分享给大家供大家参考,具体如下: 先序遍历,中序遍历,后序遍历 ,区别在于三条核心语句的位置 层序遍历  采用队列的遍历操作第一次访问根,在访问根的左孩子,接着访问根的有孩子,然后下一层 自左向右一一访问同层的结点 # 先序遍历 # 访问结点,遍历左子树,如果左子树为空,则遍历右子树, # 如果右子树为空,则向上走到一个可以向右走的结点,继续该过程 preorder(t): if t: print t.value preorde

  • Python数据结构与算法之图的基本实现及迭代器实例详解

    本文实例讲述了Python数据结构与算法之图的基本实现及迭代器.分享给大家供大家参考,具体如下: 这篇文章参考自<复杂性思考>一书的第二章,并给出这一章节里我的习题解答. (这书不到120页纸,要卖50块!!,一开始以为很厚的样子,拿回来一看,尼玛.....代码很少,给点提示,然后让读者自己思考怎么实现) 先定义顶点和边 class Vertex(object): def __init__(self, label=''): self.label = label def __repr__(sel

  • Python语言描述KNN算法与Kd树

    最近邻法和k-近邻法 下面图片中只有三种豆,有三个豆是未知的种类,如何判定他们的种类? 提供一种思路,即:未知的豆离哪种豆最近就认为未知豆和该豆是同一种类.由此,我们引出最近邻算法的定义:为了判定未知样本的类别,以全部训练样本作为代表点,计算未知样本与所有训练样本的距离,并以最近邻者的类别作为决策未知样本类别的唯一依据.但是,最近邻算法明显是存在缺陷的,比如下面的例子:有一个未知形状(图中绿色的圆点),如何判断它是什么形状? 显然,最近邻算法的缺陷--对噪声数据过于敏感,为了解决这个问题,我们可

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

    测试数据 http://grouplens.org/datasets/movielens/ 协同过滤推荐算法主要分为: 1.基于用户.根据相邻用户,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表进行推荐 2.基于物品.如喜欢物品A的用户都喜欢物品C,那么可以知道物品A与物品C的相似度很高,而用户C喜欢物品A,那么可以推断出用户C也可能喜欢物品C. 不同的数据.不同的程序猿写出的协同过滤推荐算法不同,但其核心是一致的: 1.收集用户的偏好 1)不同行为分组 2)不同分组进行加权计算用

  • Java编程实现基于用户的协同过滤推荐算法代码示例

    协同过滤简单来说是利用某兴趣相投.拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要. 协同过滤又可分为评比(rating)或者群体过滤(social filtering)协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热 UserCF的核心思想即为根据用户数据模拟向量相似度,我们根据这个相似度,来找出指定用户的相似用户,然后将相似用

  • Python编程二分法实现冒泡算法+快速排序代码示例

    本文分享的实例主要是Python编程二分法实现冒泡算法+快速排序,具体如下. 冒泡算法: #-*- coding: UTF-8 -*- #冒泡排序 def func(lt): if type(lt).__name__ !='list' and type(lt).__name__ !='tuple': return if type(lt).__name__ == 'tuple': return list(lt) for i in range(1,len(lt)-1): for j in range

  • Python编程使用tkinter模块实现计算器软件完整代码示例

    Python 提供了多个图形开发界面的库.Tkinter就是其中之一. Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里.Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中. 该计算器使用Python tkinter模块开发 效果如下图 import tkinter #导入tkinter模块 root = t

  • java算法实现红黑树完整代码示例

    红黑树 定义 红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组. 红黑树的另一种定义是含有红黑链接并满足下列条件的二叉查找树: 红链接均为左链接:没有任何一个结点同时和两条红链接相连:该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同. 满足这样定义的红黑树和相应的2-3树是一一对应的. 旋转 旋转又分为左旋和右旋.通常左旋操作用于将一个向右倾斜的红色链接旋转为向左链接.对比操作前后,可以看出,该操作

  • Java编程实现A*算法完整代码

    前言 A*搜寻算法俗称A星算法.这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法.常用于游戏中 通过二维数组构建的一个迷宫,"%"表示墙壁,A为起点,B为终点,"#"代表障碍物,"*"代表算法计算后的路径 本文实例代码结构: % % % % % % % % o o o o o % % o o # o o % % A o # o B % % o o # o o % % o o o o o % % % % % % % % =======

  • Python计算公交发车时间的完整代码

    问题描述 公交车每天会按照一定间隔发车 , 由于不同时间段经过拥堵路段的用时不 - 样,所以给定路线下公交车每趟 ( 每车次 ) 行驶时间差异也很大,现在给出某路线某天各车次公交车离开始发站和到达终点站的时间,请求出该天耗时最长车次的行驶时间.输入说明 : 第 - - 行是一个整数 N, 示接下来的公交车车次的总数.之后是 N 行,每行开始是字母 S 或 Z, 表示是从始发站开出还是终点站开出.之后两个时间表示起始时间,时间给出方式为小时 + 分钟的形式,如 S 0830 1210 表示 8 点

  • Python获取百度热搜的完整代码

    好久没写了,就把上课做的一个小东西拿出来分享一下吧. 百度网页截图如下 ↓↓↓ 程序运行输出结果截图 ↓↓↓ 上代码 ↓↓↓ from lxml import etree from lxml import html import requests headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36'}

  • python生成器和yield关键字(完整代码)

    下列代码用于先体验普通列表推导式和生成器的差别: # def add(): #     temp = ["姓名", "学号", "班级", "电话"] #     dic = {} #     lst = [] #     for item in temp: #         inp = input("请输入{}:".format(item)) #         if inp == "exit

  • python连接读写操作redis的完整代码实例

    python读写操作redis数据库 redis有16个逻辑数据库(编号db0到db15),每个逻辑数据库数据是隔离的,默认db0.选择第n个逻辑数据库,命令select n ,python连接时可指定数据库编号(0~15). 为python安装支持库: pip install redis 连接redis 第一种方式,直连: import redis def redis_opt(): redis_conn = redis.Redis(host='127.0.0.1', port=6379, pa

随机推荐