我尝试使用Redis和Python来实现协同过滤(推荐)功能
这次制作的东西
让我们尝试创建类似亚马逊的「购买了该商品的人也购买了这些商品」功能。
要素技术和实施方法 sù hé
一般而言,所谓的推荐功能(推荐功能)。推荐的实现方法主要有两种,分别是“协同过滤”和“内容基准过滤”。
コンテンツベースフィルタリングは、例えば上記例の『老人と海(ヘミングウェイ)』のお勧め商品をコンテンツベースで実装する場合は、事前に商品に属性のタグを打っておく。例えば作者という属性でタグを打っておけば、同じヘミングウェイが記した本をお勧めとして表示する。
協調過濾是指顯示其他購買了此商品的人的購買推薦。
这次我们要实现”协同过滤”。
我们会使用Redis和Python。
Redis是一个键值存储系统(KVS)。
使用Redis的SortedSet结构。
Redis安装步骤
MacPorts: http://blog.katsuma.tv/2010/03/start_redis.html
HomeBrew: http://qiita.com/items/3d2a2fc683ae19302071
MacPorts: http://blog.katsuma.tv/2010/03/start_redis.html
HomeBrew: http://qiita.com/items/3d2a2fc683ae19302071
使用Redis的原因
由于从计算量的角度来看,每次计算推荐商品并不现实,因此需要事先计算并以便于获取和记录的形式进行存储。(只要能够方便取出和记录,除了Redis之外的其他工具也可以使用)
SortedSet是一种数据结构
将数据放入,并由Redis自动重新排序的列表。
协调过滤算法的实现
只要能够获取对商品X的每个商品的相似度值,就可以进行实现。
相似度的计算公式
有各种方法,但通常使用Jaccard指数(ジャッカールしすう)。
在下面的样本数据中,商品A的计算公式为1÷5。
1表示同时购买商品X和商品A的客户数量为1,即交集。
5表示购买商品X和商品A中任意一个的客户总数,即并集。
使用本次的样本数据
实施
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import unicode_literals
def jaccard(e1, e2):
"""
ジャッカード指数を計算する
:param e1: list of int
:param e2: list of int
:rtype: float
"""
set_e1 = set(e1)
set_e2 = set(e2)
return float(len(set_e1 & set_e2)) / float(len(set_e1 | set_e2))
def get_key(k):
return 'JACCARD:PRODUCT:{}'.format(k)
# 商品Xを購入した顧客IDが1,3,5ということ
product_x = [1, 3, 5]
product_a = [2, 4, 5]
product_b = [1, 2, 3]
product_c = [2, 3, 4, 7]
product_d = [3]
product_e = [4, 6, 7]
# 商品データ
products = {
'X': product_x,
'A': product_a,
'B': product_b,
'C': product_c,
'D': product_d,
'E': product_e,
}
# redis
import redis
r = redis.Redis(host='localhost', port=6379, db=10)
# ジャッカード指数を計算して商品毎にredisのSortedSetに記録する
for key in products:
base_customers = products[key]
for key2 in products:
if key == key2:
continue
target_customers = products[key2]
# ジャッカード指数を計算
j = jaccard(base_customers, target_customers)
# redisのSortedSetに記録する
r.zadd(get_key(key), key2, j)
# 例1 商品Xを買った人はこんな商品も買っています。
print r.zrevrange(get_key('X'), 0, 2)
# > ['B', 'D', 'A']
# 例2 商品Eを買った人はこんな商品も買っています。
print r.zrevrange(get_key('E'), 0, 2)
# > ['C', 'A', 'X']
让我们来查看一下Redis中存储的值。
让我们来做个验证
购买商品X的人向他们推荐了商品B,D,A。根据校验结果,它们分别具有0.5,0.33和0.2的相似度,所以可以说它们被适当地推荐了。
这种方法的问题所在
当顾客数量和商品数量增加时,计算量会急剧增加并导致系统崩溃。
解决方案 (jiě jué àn)
Amazon希望与您一同创建倒排索引。请访问http://www.cs.umd.edu/~samir/498/Amazon-Recommendations.pdf。