Maison  >  Article  >  développement back-end  >  Explication détaillée de l'algorithme de recommandation de filtrage collaboratif implémenté en Python

Explication détaillée de l'algorithme de recommandation de filtrage collaboratif implémenté en Python

小云云
小云云original
2018-05-30 09:18:3510224parcourir

Différentes données et différents programmeurs écrivent différents algorithmes de recommandation de filtrage collaboratif, mais leur noyau est le même. Cet article présente principalement l'exemple de code complet d'implémentation d'un algorithme de recommandation de filtrage collaboratif en Python, qui a une certaine valeur de référence. Pour référence. J'espère que cela aide tout le monde.

Données de test

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

Les principaux points du filtrage collaboratif algorithme de recommandation Pour :

1. Basé sur les utilisateurs. En fonction des utilisateurs voisins, prédisez les éléments non impliqués pour lesquels l'utilisateur actuel n'a aucune préférence et calculez une liste triée d'éléments à recommander

2. Basé sur les éléments. Si les utilisateurs qui aiment l'élément A aiment également l'élément C, alors nous pouvons savoir que l'élément A et l'élément C sont très similaires et que l'utilisateur C aime l'élément A, alors nous pouvons en déduire que l'utilisateur C peut également aimer l'élément C.

Différentes données et différents programmeurs écrivent différents algorithmes de recommandation de filtrage collaboratif, mais leur noyau est le même :

1. Collectez les préférences des utilisateurs

1) Différents groupes de comportements

.

2) Différents regroupements sont pondérés pour calculer les préférences totales des utilisateurs

3) Débruitage et normalisation des données

2 Trouver des utilisateurs similaires (en fonction des utilisateurs) ou des éléments (en fonction des éléments). )

3. Calculez la similarité et triez. Recommander des utilisateurs en fonction de la similarité

Le processus de cet exemple :

1. Initialiser les données

Obtenir des films et des notes

Convertir en données userDict pour représenter un certain Un ensemble de notes pour tous les films d'un utilisateur, et normaliser les notes en les divisant par 5

Convertir en données ItemUser représente l'ensemble de tous les utilisateurs qui ont participé à la note d'un certain film

2. Calculer la similarité de tous les utilisateurs avec userId

Découvrez tous les utilisateurs qui regardent des films qui ont une intersection avec userId

Bouclez et calculez la similarité avec userId pour ces utilisateurs

Obtenez le relation entre l'utilisateur A et l'userId Union. Le format est : {'Movie ID', [Note d'un utilisateur, note de l'ID utilisateur]}, aucune note n'est enregistrée comme 0

Calculez la distance cosinusoïdale entre l'utilisateur A et l'ID utilisateur, plus ils sont grands, plus ils sont similaires

3. Générer une liste de films recommandés en fonction de la similarité

4. Afficher la liste recommandée et la précision

#!/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))

Résumé

Ce qui précède est l'intégralité du contenu de cet article sur l'exemple de code complet d'implémentation d'un algorithme de recommandation de filtrage collaboratif en python. J'espère que cela sera utile à tout le monde.

Recommandations associées :

Mise en œuvre de l'algorithme de filtrage collaboratif php+mysql

Filtrage collaboratif

Tutoriel sur l'implémentation du filtrage collaboratif en Python

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn