推荐系统实践第四章: 利用用户标签

Image(16)

基本上可以通过3种方式联系用户兴趣和物品:

  • 用户喜欢过的物品(item-cf)
  • 用户的好友或者有相似兴趣的好友喜欢过的物品(user-cf)
  • 用户具有哪些feature, 哪些物品保护

之前用了user-cf,item-cf, 现在考虑使用标签进行推荐。

标签是一种无层次化结构的、用来描述信息的关键词。

给物品打标签:

  • 专家、作者
  • 用户

标签系统中存在的问题:

  • 如何基于标签推荐
  • 如何给用户推荐标签

基于标签的推荐系统示例:

利用Delicious数据集:(待链接)

     格式:userID     bookmarkID     tagID     timestamp

方法如书上介绍:

image

代码如下:

# -*- coding: UTF-8 -*-
'''
Created on 2014��9��15��

@author: joeyqzhou
'''


import random



def addValueToMat(theMat,key,value,incr):
    #theMat是字典格式
    #它的value也是字典格式
    if key not in theMat: #如果key没出先在theMat中
        theMat[key]=dict();
        theMat[key][value]=incr;#
    else:
        if value not in theMat[key]:
            theMat[key][value]=incr;
        else:
            theMat[key][value]+=incr;





user_tags = dict();
tag_items = dict();
user_items = dict();
user_items_test = dict();


def InitStat():
    #init: 
    data_file = open('E:\\RecomDataSet\\Decilious\\bookTag\\user_taggedbookmarks-timestamps.dat')
    line = data_file.readline(); ##去掉第一行
    line = data_file.readline(); 
    while line:
        if random.random()>0.1:##添加xunlianji
            terms = line.split("\t");
            user=terms[0];
            item=terms[1];
            tag=terms[2];
            addValueToMat(user_tags,user,tag,1)
            addValueToMat(tag_items,tag,item,1)
            addValueToMat(user_items,user,item,1)
            line = data_file.readline();
        else:
   
            addValueToMat(user_items_test,user,item,1)
    data_file.close();   





def Recommend(usr):
    recommend_list = dict();
    tagged_item = user_items[usr];
    for tag_,wut in user_tags[usr]:
        for item_,wit in tag_items[tag_]:
            if item_ not in tagged_item:
                if item_ not in recommend_list:
                    recommend_list[item_]=wut*wit;
                else:
                    recommend_list[item_]+=wut*wit;


InitStat();
#Recommend(8);

recom_len=0;#推荐的总长度
hit=0;#预测准确的个数
test_len=0;#测试集长度


for user in user_items_test:#计算测试集的长度,来计算召回率
    test_len+=user_items_test[user].__len__();


for user in user_items:
    for item in user_items[user]: #item被用户打过的标签至少打过一次
        if user_items[user][item]>0:#如果打过三次以上就推荐
            recom_len+=1;
            if item in user_items_test:
                hit+=1;


print "precision="+str(hit*1.0/recom_len);
print "recall="+str(hit*1.0/test_len);

###利用内置sorted函数排序
#print sorted(user_items['8'].items(),key=lambda dic:dic[1],reverse=True)

把数据集分为10%测试,90%训练,个人程序跑的结果如下:

准确率:1.8%

召回率:5.6%

  • 上面简单的方法可能会造成容易推荐热门,可以利用TF-IDF来优化
  • 对于新用户或者新item,标签比较稀疏,那么可以进行标签扩展。方法有:
    • topic model
    • 利用数据统计标签相似度image

标签清理

    • 不是所有标签都反应用户的兴趣(比如“不好笑)
    • 有利于给推荐解释
    • 方法:去掉停止词,合并同义词或者分隔符造成的同义词。
posted @ 2014-09-18 11:38 joey周琦 阅读(...) 评论(...) 编辑 收藏