itemCF 基于物品的协同过滤

来源:互联网 发布:led灯 知乎 编辑:程序博客网 时间:2024/05/17 23:49

itemCF 基于物品的协同过滤

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

# -*- coding=utf-8 -*-import mathimport sysimport pandasimport numpy as npfrom texttable import Texttablefrom 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())
原创粉丝点击