推荐系统其实最重要的是推荐算法的实现,我认为掌握每一种推荐算法,就会非常容易通过代码实现。
有时候代码又非常精妙,区区几行就可以实现一个非常棒的算法,例如基于 item 的相似性做出的推荐算法
,这里有个 物品间的相似距离的度量,和最后的综合得分,这两个非常关键,还有就是在代码中不断变换的集合 字典,照实让人眼花缭乱
原始的数据如下
user score item
dingdanglbh,4.0 ,25862578
Luna-cat,5.0 ,25862578
aiyung,5.0 ,25862578
39553070,5.0 ,25862578
3639653,5.0 ,25862578
myliu,5.0 ,25862578
46910030,5.0 ,25862578
xiyuweilan,5.0 ,25862578
49118031,4.0 ,25862578
changanamei,4.0 ,25862578
seasonshadgone,5.0 ,25862578
78728561,5.0 ,25862578
bdleizi,5.0 ,25862578
violetblue,5.0 ,25862578
frogsun,4.0 ,25862578
yican,4.0 ,25862578
Alaleio,5.0 ,25862578
78468518,1.0 ,25862578
以下是代码部分
#!/usr/bin/env python
#-*-coding:utf-8-*-
'''
Created on 2016-5-30
@author: thinkgamer
'''
import math
class ItemBasedCF:
def __init__(self,train_file):
self.train_file = train_file
self.readData()
def readData(self):
#读取文件,并生成用户-物品的评分表和测试集
self.train = dict() #用户-物品的评分表
for line in open(self.train_file):
# user,item,score = line.strip().split(",")
user,score,item = line.strip().split(",")
self.train.setdefault(user,{})
#生成的字典为嵌套字典 ,value 其实也是字典
self.train[user][item] = int(float(score))
# print("**********")
# print(user)
# print('________')
# print(item)
# print('________')
# print(score)
# for k ,v in self.train.items():
# print("**********")
# print(k)
# print('________')
# for ki,vi in v.items():
# print(ki)
# print('___----__')
# print(vi)
def ItemSimilarity(self):
#建立物品-物品的共现矩阵
C = dict() #物品-物品的共现矩阵
N = dict() #物品被多少个不同用户购买
for user,items in self.train.items():
for i in items.keys(): #物品列表遍历
N.setdefault(i,0) #放物品的字典,最后是物品 对应 物品一共被所有人购买的次数
N[i] += 1
C.setdefault(i,{}) #放物品的字典 key 是物品,value 是字典 所有用户 购买的其他物品,对应的 购买次数
for j in items.keys():
if i == j : continue
C[i].setdefault(j,0)
C[i][j] += 1
#计算相似度矩阵
self.W = dict()
for i,related_items in C.items():
self.W.setdefault(i,{})
for j,cij in related_items.items():
self.W[i][j] = cij / (math.sqrt(N[i] * N[j]))
return self.W
#给用户user推荐,前K个相关用户
def Recommend(self,user,K=3,N=10):
rank = dict()
action_item = self.train[user] #用户user产生过行为的item和评分
for item,score in action_item.items():
for j,wj in sorted(self.W[item].items(),key=lambda x:x[1],reverse=True)[0:K]:
if j in action_item.keys():
continue
rank.setdefault(j,0)
if rank[j]==0:
rank[j] = score * wj
else:
print(" 竟然有重复的 %s"%j) #换一个第一个for 的item 就可能存在可以上一个item 共同存在的j
rank[j] += score * wj
return dict(sorted(rank.items(),key=lambda x:x[1],reverse=True)[0:N])
#声明一个ItemBased推荐的对象
Item = ItemBasedCF("uid_score_bid.dat")
Item.ItemSimilarity()
recommedDic = Item.Recommend("xiyuweilan")
for k,v in recommedDic.items():
print (k,"\t",v)