ここで考える問題は,販売店がそれぞれの顧客にどの商品をおすすめ商品として提示するかを決めることです.
まず,必要なライブラリをインポートして,GitHub のリポジトリからデータを読み込んで表示してみます.
import pandas as pd
import numpy as np
url = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_matrix.csv?raw=true"
# url = 'collaborative_filtering_matrix.csv' # ローカルにダウンロードしてから開く場合
df = pd.read_csv(url)
print(df)
id name A B C D E 0 0 Eto 5.0 4.0 3.0 NaN NaN 1 1 Sato NaN 2.0 4.0 2.0 3.0 2 2 Kato 2.0 3.0 4.0 NaN NaN 3 3 Muto 2.0 3.0 2.0 NaN 2.0 4 4 Kito 4.0 3.0 3.0 4.0 NaN 5 5 Goto 2.0 5.0 NaN 2.0 3.0 6 6 Bito 3.0 3.0 2.0 NaN 1.0 7 7 Saito 4.0 4.0 5.0 NaN 5.0 8 8 Naito 5.0 5.0 4.0 2.0 1.0 9 9 Koto 3.0 NaN 2.0 2.0 2.0
上の表は顧客が商品について評価した結果であるレイティング(1〜5点:1が低評価,5が高評価)を集計したものです.販売店は「A」から「E」までの商品を取り扱うものとします.商品「D」と「E」をまだ購入していない顧客 Kato さんと Eto さんそれぞれにどちらを優先的におすすめするかを決定します.顧客 Kato さんと Eto さんはすでに商品「A」,「B」,「C」を購入済みで,各商品に対するレイティング(評価)が得られています.顧客データベースを検索して抽出した結果が上の表です.具体的には,商品「A」「B」「C」から少なくとも2つの商品についてレイティングの情報があり,かつ,商品「D」「E」の1つ以上のレイティング情報をもつ顧客を抽出した結果です.なお,「NaN (Not a Number)」は値がない,つまり,まだレイティングの情報がないということを意味しています.
ここで,評価データを視覚的に確認しておきます.作成したグラフの横軸が商品で,縦軸が顧客を表しており,上の数値での表示と同じ並びになっています.白の部分は評価がない箇所で,色が濃いほど評価値が高いことを意味しています.
import matplotlib.pyplot as plt
# from IPython.display import set_matplotlib_formats # バージョンによってはこちらを有効に
from matplotlib_inline.backend_inline import set_matplotlib_formats
set_matplotlib_formats('retina')
Z = df.iloc[:, 2:].values # レイティングだけを2次元配列に
Z = Z[::-1,:] # 上下逆順に並べる
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
c = ax.pcolor(Z, cmap=plt.get_cmap('Greens'), alpha=0.8)
ax.set_xticks([])
ax.set_yticks([])
c.set_array(Z)
fig.colorbar(c, ticks=range(6))
# plt.savefig('ratings.png', dpi=300, facecolor='white')
plt.show()
このセクションでは,協調フィルタリングと呼ばれる2種類の手法を使って,Kato さん, Eto さんそれぞれに近い好み(嗜好・特徴)を持つ顧客の集団を特定し,その集団による評価値をもとに商品「D」や「E」のスコアを推定することを考えます.具体的には,顧客間の類似度に基づいた手法と行列分解 (matrix factorization)について説明しながら実際にコードを示します.