协同过滤

协同过滤算法

协同过滤算法(Collaborative Filtering, CF)是很常用的一种算法,在很多电商网站上都有用到。CF算法包括基于用户的CF(User-based CF)和基于物品的CF(Item-based CF)。

基于用户的协同过滤算法

基于用户的CF原理如下:

1.  分析各个用户对item的评价(通过浏览记录、购买记录等);

2.  依据用户对item的评价计算得出所有用户之间的相似度;

3.  选出与当前用户最相似的N个用户;

4.  将这N个用户评价最高并且当前用户又没有浏览过的item推荐给当前用户。

类似下图:

基于物品的协同过滤算法

基于物品的CF原理大同小异,只是主体在于物品:

1.  分析各个用户对item的浏览记录。

2.  依据浏览记录分析得出所有item之间的相似度;

3.  对于当前用户评价高的item,找出与之相似度最高的N个item;

4.  将这N个item推荐给用户

类似下图:

相似度的度量方法

相似性的度量方法必须满足拓扑学中的度量空间的基本条件:假设d是度量空间M上的度量:,其中度量d满足:

第一种相似性度量方法:欧氏距离

第二种相似性度量方法:皮尔逊相关系数

在欧氏距离中,不同特征之间的量级的影响较大,入A(0.05,1),B(1,1),C(0.05,4)AB之间距离是0.95,AC之间距离是3,此时不能很好的判断AB,AC之间相似性的大小(WHY)。皮尔逊相关系数计算公式如下:

皮尔逊相似度对量级不敏感,AB之间为0.5186,AC之间为-0.4211.

第三种相似性度量方法:余弦相似度

余弦相似度是文本相似度度量中使用较多的一种方法

越接近1表示相似度越大

例如:

原始数据:下图行是用户对每一种商品的一个评价分数,利用用户-商品矩阵计算用户相似度矩阵w,w(i,j)代表的是用户i和j的相似度。然后利用不同用户之间的相似度,将商品推荐给用户。

表1用户-商品矩阵

表2用户相似度矩阵

对于用户0来说,没有评价过2,4号商品。所以0号用户对2号商品的推荐值为,N(i)是对商品i评价过的用户的集合,Wu,v是用户u,v之间的相关度,Rv,i用户v对商品i的评价。如0号用户对2号商品的推荐值 =0.749269*4 + 0.32*5 + 0.252982*2 = 5.10284,对4号商品的推荐值 = 0.32*3 + 0.252982*5 = 2.22491.如下图:

# coding:UTF-8
'''
Date:20160928
@author: zhaozhiyong
'''

import numpy as np

def load_data(file_path):
    '''导入用户商品数据
    input:  file_path(string):用户商品数据存放的文件
    output: data(mat):用户商品矩阵
    '''
    f = open(file_path)   
    data = []
    for line in f.readlines():
        lines = line.strip().split("\t")
        tmp = []
        for x in lines:
            if x != "-":
                tmp.append(float(x))  # 直接存储用户对商品的打分
            else:
                tmp.append(0)
        data.append(tmp)
    f.close()
    
    return np.mat(data)

def cos_sim(x, y):
    '''余弦相似性
    input:  x(mat):以行向量的形式存储,可以是用户或者商品
            y(mat):以行向量的形式存储,可以是用户或者商品
    output: x和y之间的余弦相似度
    '''
    numerator = x * y.T  # x和y之间的额内积
    denominator = np.sqrt(x * x.T) * np.sqrt(y * y.T) 
    return (numerator / denominator)[0, 0]


def similarity(data):
    '''计算矩阵中任意两行之间的相似度
    input:  data(mat):任意矩阵
    output: w(mat):任意两行之间的相似度
    '''
    m = np.shape(data)[0]  # 用户的数量
    # 初始化相似度矩阵
    w = np.mat(np.zeros((m, m)))
    
    for i in range(m):
        for j in range(i, m):
            if j != i:
                # 计算任意两行之间的相似度
                w[i, j] = cos_sim(data[i, ], data[j, ])
                w[j, i] = w[i, j]
            else:
                w[i, j] = 0
    return w

def user_based_recommend(data, w, user):
    '''基于用户相似性为用户user推荐商品
    input:  data(mat):用户商品矩阵
            w(mat):用户之间的相似度
            user(int):用户的编号
    output: predict(list):推荐列表
    '''
    m, n = np.shape(data)
    interaction = data[user, ]  # 用户user与商品信息
    
    # 1、找到用户user没有互动过的商品
    not_inter = []
    for i in range(n):
        if interaction[0, i] == 0:  # 没有互动的商品
            not_inter.append(i)
    
    # 2、对没有互动过的商品进行预测
    predict = {}
    for x in not_inter:
        item = np.copy(data[:, x])  # 找到所有用户对商品x的互动信息
        for i in range(m):  # 对每一个用户
            if item[i, 0] != 0:  # 若该用户对商品x有过互动
                if x not in predict:
                    predict[x] = w[user, i] * item[i, 0]
                else:
                    predict[x] = predict[x] + w[user, i] * item[i, 0]
    # 3、按照预测的大小从大到小排序
    return sorted(predict.items(), key=lambda d:d[1], reverse=True)

def top_k(predict, k):
    '''为用户推荐前k个商品
    input:  predict(list):排好序的商品列表
            k(int):推荐的商品个数
    output: top_recom(list):top_k个商品
    '''
    top_recom = []
    len_result = len(predict)
    if k >= len_result:
        top_recom = predict
    else:
        for i in range(k):
            top_recom.append(predict[i])
    return top_recom   
          
if __name__ == "__main__":
    # 1、导入用户商品数据
    print ("------------ 1. load data ------------")
    data = load_data("data.txt")
    # 2、计算用户之间的相似性
    print ("------------ 2. calculate similarity between users -------------")    
    w = similarity(data)
    # 3、利用用户之间的相似性进行推荐
    print ("------------ 3. predict ------------")    
    predict = user_based_recommend(data, w, 0)
    # 4、进行Top-K推荐
    print ("------------ 4. top_k recommendation ------------")
    top_recom = top_k(predict, 2)
    print (top_recom)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值