itemCF 基于物品的协同过滤

itemCF 基于物品的协同过滤

代码来自csdn分享的开源。
我加入一些输出。得到矩阵的内容。


# -*- coding=utf-8 -*-
import math
import sys
import pandas
import numpy as np
from texttable import Texttable
from collections import defaultdict
# from Wtemp import *
from operator import itemgetter


# 读取文件
def readFile(fileData):
    data = []
    rates = []
    f = open(fileData, "r")
    data = f.readlines()
    f.close()
    for line in data:
        dataLine = line.split("\t")
        rates.append([int(dataLine[0]), int(dataLine[1]), int(dataLine[2])])
    return rates


# 创建字典,生成用户评分的数据结构
#   输入:数据集合,格式:用户id\t硬盘id\t用户评分
#   输出:1.用户字典:dic[用户id]=[(电影id,电影评分)...]
#        2.电影字典:dic[电影id]=[用户id1,用户id2...]
def createDict(rates):
    user_dict = {}
    movie_dict = {}
    for i in rates:
        if i[0] in user_dict:
            user_dict[i[0]].append((i[1], i[2]))
        else:
            user_dict[i[0]] = [(i[1], i[2])]
        if i[1] in movie_dict:
            movie_dict[i[1]].append(i[0])
        else:
            movie_dict[i[1]] = [i[0]]
    user_txt=pandas.Series(user_dict)
    user_txt.to_csv('user_txt.csv')
    item_txt = pandas.Series(movie_dict)
    item_txt.to_csv('movie_txt.csv')
    return user_dict, movie_dict


# 建立物品倒排表,计算物品相似度
def itemCF(user_dict):
    N = dict()
    C = defaultdict(defaultdict)
    W = defaultdict(defaultdict)
    for key in user_dict:
        for i in user_dict[key]:
            if i[0] not in N.keys():  # i[0]表示movie_id
                N[i[0]] = 0
            N[i[0]] += 1  # N[i[0]]表示评论过某电影的用户数
            for j in user_dict[key]:
                if i == j:
                    continue
                if j not in C[i[0]].keys():
                    C[i[0]][j[0]] = 0
                C[i[0]][j[0]] += 1  # C[i[0]][j[0]]表示电影两两之间的相似度,eg:同时评论过电影1和电影2的用户数
    for i, related_item in C.items():
        for j, cij in related_item.items():
            W[i][j] = cij / math.sqrt(N[i] * N[j])
            data = [i,j,W[i][j]]
            print >>f,(data)
    return W


# 结合用户喜好对物品排序
def recommondation(user_id, user_dict, K):
    rank = defaultdict(int)
    l = list()
    W = itemCF(user_dict)
    for i, score in user_dict[user_id]:  # i为特定用户的电影id,score为其相应评分
        for j, wj in sorted(W[i].items(), key=itemgetter(1), reverse=True)[0:K]:  # sorted()的返回值为list,list的元素为元组
            if j in user_dict[user_id]:
                continue
            rank[j] += score * wj  # 先找出用户评论过的电影集合,对每一部电影id,假设其中一部电影id1,找出与该电影最相似的K部电影,计算出在id1下用户对每部电影的兴趣度,接着迭代整个用户评论过的电影集合,求加权和,再排序,可推荐出前n部电影,我这里取10部。
    l = sorted(rank.items(), key=itemgetter(1), reverse=True)[0:10]
    return l


# 获取电影列表
def getMovieList(item):
    items = {}
    f = open(item, "r")
    movie_content = f.readlines()
    f.close()
    for movie in movie_content:
        movieLine = movie.split("\t")
        items[int(movieLine[0])] = movieLine[1:]
    item_txt = pandas.Series(items)
    item_txt.to_csv('item_txt.csv')
    return items


# 主程序
if __name__ == '__main__':
    itemTemp = getMovieList("D:/PycharmProjects/reMov/artists.item")  # 获取电影列表
    fileTemp = readFile("D:/PycharmProjects/reMov/user_artists.data")  # 读取文件
    user_dic, movie_dic = createDict(fileTemp)  # 创建字典
    #numpy.savetxt('user_dict.txt', user_dic)
    print("创建字典")
    user_id = 66
    movieTemp = recommondation(user_id, user_dic, 80)  # 对电影tuijian排序
    movieTemp_txt = pandas.Series(movieTemp)
    movieTemp_txt.to_csv('movieTemp_txt.csv')
    print("创建字典2")
    rows = []
    table = Texttable()  # 创建表格并显示
    table.set_deco(Texttable.HEADER)
    table.set_cols_dtype(['t', 'f', 'a'])
    table.set_cols_align(["l", "l", "l"])
    rows.append(["user name", "recommondation_movie", "from userid"])
    for i in movieTemp:
        rows.append([user_id, itemTemp[i[0]][0], ""])
    table.add_rows(rows)
    print(table.draw())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值