レコメンデーションの検証(Python+Redis)


## はじめに

Amazonの買い物で重宝されるレコメンデーション機能(自分だけ?)、
「この商品を買った人はこんな商品も買っています」から予想外の発見があったり。

レコメンデーション(推薦)の実装については、先人たちがすでに理論から実践まで
たくさんナレッジを残してくださっていました、感謝感謝。

## レコメンデーションをサクッと試してみたい

PyPI に公開されているレコメンデーションエンジン [cf_recommender](https://pypi.org/project/cf_recommender/) を検証してみます。 

- PyPI(Python Package Index)とは
    - プログラミング言語Pythonの、サードパーティーソフトウェアリポジトリ
    - すべてのオープンソースなPythonパッケージの包括的なカタログ

- cf_recommenderとは
    - 協調フィルタリング型のリアルタイムレコメンデーションエンジン
    - Python言語で実装されている
    - Redis(インメモリデータベース)をバックエンドとして使用

## 検証環境

### ハードウェア

```
CPU: Intel(R) Core(TM) 3.30GHz(4コア8スレッド)
メモリ: 16 GB
```

### OS

Ubuntu 20.04 LTS を使用しました。

Windows 10で管理者権限で、Ubuntu 導入しました。

```
> wsl --install -d Ubuntu-20.04
```

### Redisを導入

Redis 3.0.7 を使用しました。
cf_recommender 最後のリリースが2016年ですので、合わせて古いバージョン使用。

- ダウンロード
http://download.redis.io/releases/
- インストール手順
https://www.digitalocean.com/community/tutorials/how-to-install-redis-from-source-on-ubuntu-18-04
    - make
    - sudo make install
- 起動
```
$ /usr/local/bin/redis-server
```
またはサービス登録し起動

### Pythonと関連ライブラリを導入

#### Python 2.7.18を使用
えー、と声が聞こえますが、
cf_recommenderがPython 3.5以上に未対応で、
Pythonと関連ライブラリを2016年ぐらいの古いバージョン使用。

```
$ sudo apt update
$ sudo apt install python2
$ python --version
Python 2.7.18
```

#### pip 20.3.4を使用

```shell
$ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
$ python get-pip.py
$ pip --version
pip 20.3.4 from /home/users/.local/lib/python2.7/site-packages/pip (python 2.7)
```

#### redis-py 2.10.5を使用

こちらも古いバージョンを使用。

```
$ pip install -Iv redis==2.10.5
```

#### cf_recommenderの導入

```
$ pip install cf_recommender
```

#### 確認

```shell
$ pip list
Package        Version
-------------- -------
cf-recommender 1.0.1
pip            20.3.4
redis          2.10.5
```

## サンプルコードでレコメンデーション検証

以下のコードで試してみました。

```python:sample.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from cf_recommender.recommender import Recommender

cf_settings = {
    # redis
    'expire': 3600 * 24 * 30,
    'redis': {
        'host': 'localhost',
        'port': 6379,
        'db': 0
    },
    # recommendation engine settings
    'recommendation_count': 10,
    'recommendation': {
        'update_interval_sec': 600,
        'search_depth': 100,
        'max_history': 1000,
    },
}

recommendation = Recommender(cf_settings)

# register history
user_id = 'user-00001'
buy_items = ['Item10', 'Item10', 'Item10', 'Item3', 'Item3', 'Item1']
for item_id in buy_items:
    recommendation.register(item_id)
recommendation.like(user_id, buy_items)

user_id = 'user-00002'
buy_items = ['Item10', 'Item9', 'Item9', 'Item3', 'Item2', 'Item1']
for item_id in buy_items:
    recommendation.register(item_id)
recommendation.like(user_id, buy_items)

user_id = 'user-00003'
buy_items = ['Item10', 'Item10', 'Item4', 'Item3', 'Item1', 'Item1']
for item_id in buy_items:
    recommendation.register(item_id)
recommendation.like(user_id, buy_items)

item_id = 'Item1'
print '商品 Item1 を見た人は以下の商品も見ています'
print recommendation.get(item_id, count=2)
```

実行したら、

```
$ python sample.py
商品 Item1 を見た人は以下の商品も見ています
['Item10', 'Item3']
```

## おわりに

簡単ですが、レコメンデーションエンジン cf_commendation を検証してみました。
これを使っていろいろ面白い機能が実現できそうです。