在
开源框架taste
中有SlopOne的Java实现,效果不错。使用
movielens
的数据,代码如下
代码
#coding:utf-8
import re
import math
#读取数据,并生成矩阵
def getMatrix():
mat = {}
f = open("u.data", "r")
for line in f:
list = map(int, line.strip("\n").split("\t"))
if list[0] in mat:
mat[ list[0] ][ list[1] ] = list[2]
else:
mat[ list[0] ] = { list[1] : list[2] }
f.close()
return mat
#计算某个用户的平均分
def getAvg(usr):
res = 0.0
for i in usr:
res += usr[i]
return res / len(usr)
#预测分数, 返回矩阵mat中用户usr对item的评分
def getSlopOne(mat, user, item):
#用户user的所有item的列表
list = mat[user]
#分子
mole = 0.0
#分母
demo = 0.0
#对于每一个物品,都计算它和物品item的差值,最终算出相对它item的score
for it in list:
diff_sum = 0.0
user_num = 0
for us in mat:
us_it = mat[us]
#如果该user同时评价过这两个item,则采纳他的评分
if item in us_it and it in us_it:
diff_sum += us_it[item] - us_it[it]
user_num += 1
#如果item被人评价过
if user_num:
diff_avg = diff_sum / user_num
mole += (list[it] + diff_avg) * user_num
demo += user_num
#如果没有人评价过,则取这个人的平均分
if user_num == 0:
return getAvg(list)
#否则返回最终的score
return mole / demo
def main():
mat = getMatrix()
rf = open("u.data", "r")
wf = open("o.data", "w")
for line in rf:
list = map(int, line.strip("\n").split("\t"))
score = getSlopOne(mat, list[0], list[1])
output = str(list[0]) + "\t" + str(list[1]) + "\t" + str(list[2]) + "\t" + str(score) + "\n"
wf.write(output)
rf.close()
wf.close()
if __name__ == "__main__":
main()
版权声明:本文为ACdreamers原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。