Python入門トップページ


目次

  1. 協調フィルタリングによる推薦システム
  2. 顧客間の類似度に基づいた手法
  3. 個別データを順にマージしてみる
  4. 個別データを一気にマージしてみる
  5. 行列分解
  6. サンプルコードのまとめ
  7. Surprise による顧客間類似度に基づいた手法
  8. Surprise による行列分解
  9. ユーザごとの推薦アイテムリストを作成する
  10. 推薦アルゴリズムの性能を評価する
  11. 適合率と再現率
  12. クロスバリデーション
  13. 学習済みモデルの保存と読み込み

協調フィルタリングによる推薦システムを作ってみよう

ユーザごとの推薦アイテムリストを作成する

データの準備と確認

前のページでは行列分解によって評価データからレイティングの予測値を求めました.ここでは,アイテム数を10個に増加させたデータを利用してユーザごとに推薦アイテムのリストを作成することを考えます.

まずは,データを確認するために,GitHub のリポジトリ から新たなサンプルデータを読み込み,それらをここで説明した手順で結合します.


import pandas as pd
import numpy as np

url_items = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_items2.csv?raw=true"
df_items = pd.read_csv(url_items)
url_customers = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_customers.csv?raw=true"
df_customers = pd.read_csv(url_customers )
url_ratings = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_ratings2.csv?raw=true"
df_ratings = pd.read_csv(url_ratings)

tbl = pd.merge(
    pd.merge(
        df_ratings, df_items,
        left_on = 'item',
        right_on = 'id',
    ),
    df_customers,
    left_on = 'customer', right_on = 'id'
)
tbl = tbl.rename(columns={'item_y': 'item', 'id_y': 'id'})
tbl = tbl.loc[:,['id', 'name','item','rating']]
df = tbl.pivot_table('rating', index=['id', 'name'], columns='item', aggfunc='sum')
print(df)
item        A    B    C    D    E    F    G    H    I    J
id name
0  Eto    5.0  4.0  3.0  NaN  NaN  2.0  4.0  2.0  3.0  5.0
1  Sato   NaN  2.0  4.0  2.0  3.0  1.0  3.0  4.0  3.0  2.0
2  Kato   2.0  3.0  4.0  NaN  NaN  1.0  3.0  4.0  3.0  2.0
3  Muto   2.0  3.0  2.0  NaN  2.0  2.0  2.0  2.0  2.0  1.0
4  Kito   4.0  3.0  3.0  4.0  NaN  4.0  4.0  3.0  2.0  4.0
5  Goto   2.0  5.0  NaN  2.0  3.0  3.0  3.0  2.0  4.0  1.0
6  Bito   3.0  3.0  2.0  NaN  1.0  4.0  1.0  2.0  2.0  4.0
7  Saito  4.0  4.0  5.0  NaN  5.0  2.0  5.0  5.0  4.0  4.0
8  Naito  5.0  5.0  4.0  2.0  1.0  1.0  2.0  2.0  4.0  5.0
9  Koto   3.0  NaN  2.0  2.0  2.0  3.0  2.0  1.0  2.0  3.0

上に表示された評価値のデータのうち,ハイライトされた数値はまだ観測されていないものとして残りのデータを訓練データとして利用します.そのうえで4人のユーザに対して,予測値が高い順番に推薦アイテムのリストを提示することを考えます.

目次に戻る

ユーザごとの推薦アイテムリストを作成する

まずはプログラムの全体像とその実行結果を示します.

プログラムの全体像
import pandas as pd
import numpy as np
from surprise import Dataset, Reader, SVD
from surprise.model_selection import train_test_split
from collections import defaultdict

np.set_printoptions(precision=3)    # 小数点以下の表示桁数を設定
np.set_printoptions(suppress=True)  # 指数表示を行わないように

def get_top_n(predictions, n=10):
    """
    ユーザごとにレイティングの予測値が高いN個の推薦リストを作成する
    """
    # ユーザごとの予測値リストを作成
    top_n = defaultdict(list)
    for uid, iid, true_r, est, _ in predictions:
        top_n[uid].append((iid, est))

    # ソートして上位 n個のリストを作成する
    for uid, user_ratings in top_n.items():
        user_ratings.sort(key=lambda x: x[1], reverse=True)
        top_n[uid] = user_ratings[:n]

    return top_n

# データの読み込み
url_ratings = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_ratings2.csv?raw=true"
df_ratings = pd.read_csv(url_ratings)

# レイティングのスケールを設定する
reader = Reader(rating_scale=(1, 5))
# 列名を指定してデータフレームからデータセットを読み込む
data = Dataset.load_from_df(df_ratings[["customer", "item", "rating"]], reader)

# 19件をテストデータにする
trainset, testset = train_test_split(data, test_size=0.21, shuffle=False)  # シャッフルなし
# trainset, testset = train_test_split(data, test_size=0.21)               # シャッフルあり

# 学習データの数をカウントする
n_train = sum(len(d) for d in trainset.ur.values())

# データ数などを確認する
print(f"number of trainset customers  ={trainset.n_users:4d}")
print(f"number of trainset items      ={trainset.n_items:4d}")
print(f"number of elements in matrix  ={trainset.n_users * trainset.n_items:4d}")
print(f"number of null ratings        ={trainset.n_users * trainset.n_items - df_ratings['rating'].shape[0]:4d}")
print(f"number of ratings in data     ={df_ratings['rating'].shape[0]:4d}")
print(f"number of ratings in trainset ={n_train:4d}")
print(f"number of ratings in testset  ={len(testset):4d}")

# 学習データを行列形式に変換し,元の順番に並べ替えた行列も作成する
trainset_matrix = np.zeros((trainset.n_users, trainset.n_items))
train_raw_matrix = np.zeros((trainset.n_users, trainset.n_items))  # 元のデータ
trainset_matrix[:,:] = np.nan
train_raw_matrix[:,:] = np.nan
for u, vals in trainset.ur.items():
  for i, rating in vals:
    trainset_matrix[u, i] = rating
    train_raw_matrix[trainset.to_raw_uid(u), trainset.to_raw_iid(i)] = rating

# 因子数
n_factors = 5
# エポック数
n_epochs = 100000
# バイアスを利用するか
biased = False
# biased = True
# 学習率
lr_all = 0.005
# 正則化パラメータ
reg_all = 0.02
# モデルの設定
mf = SVD(n_factors=n_factors,
         n_epochs=n_epochs,
         biased=biased,
         lr_all=lr_all,
         reg_all=reg_all
         )
# モデルの当てはめ(学習)を行う
mf.fit(trainset)

# 予測評価値のマトリックス
predict_matrix = np.zeros((trainset.n_users, trainset.n_items))
for uid in range(trainset.n_users):
    for iid in range(trainset.n_items):
        pred = mf.predict(uid, iid, verbose=False)
        predict_matrix[uid, iid] = pred.est

# テストデータのマトリックス
test_raw_matrix = np.zeros((trainset.n_users, trainset.n_items))
test_raw_matrix[:] = np.nan
for r, c, v in testset:
    test_raw_matrix[r, c] = v

print("----- trainset -------")
print(train_raw_matrix)
print("----- testset -----")
print(test_raw_matrix)

print("----- s -------")
print(predict_matrix)

print("----- train_predict -------")
train_predict_matrix = np.copy(train_raw_matrix)
train_predict_matrix = np.where(~np.isnan(train_predict_matrix), predict_matrix, np.nan)
print(train_predict_matrix)

print("----- test_predict -------")
test_predict_matrix = np.copy(test_raw_matrix)
test_predict_matrix = np.where(~np.isnan(test_predict_matrix), predict_matrix, np.nan)
print(test_predict_matrix)

# テストデータに対しての予測を実行
test_predictions = mf.test(testset)

top_n = get_top_n(test_predictions, n=5)  # ここで抽出するアイテム数 n を設定する
print("---- ユーザごとの推薦アイテム ----")
for uid, user_ratings in top_n.items():
    print(f"ユーザ {uid} への推薦アイテム: {[iid for (iid, _) in user_ratings]}")
number of trainset customers  =  10
number of trainset items      =  10
number of elements in matrix  = 100
number of null ratings        =  11
number of ratings in data     =  89
number of ratings in trainset =  70
number of ratings in testset  =  19
----- trainset -------
[[ 5.  4.  3. nan nan nan nan nan nan nan]
 [nan  2.  4.  2.  3. nan nan nan nan nan]
 [ 2.  3.  4. nan nan nan nan nan nan nan]
 [ 2.  3.  2. nan  2.  2. nan nan nan nan]
 [ 4.  3.  3.  4. nan  4.  4.  3.  2.  4.]
 [ 2.  5. nan  2.  3.  3.  3.  2.  4.  1.]
 [ 3.  3.  2. nan  1.  4.  1.  2.  2.  4.]
 [ 4.  4.  5. nan  5.  2.  5.  5.  4.  4.]
 [ 5.  5.  4.  2.  1.  1.  2.  2.  4.  5.]
 [ 3. nan  2.  2.  2.  3.  2.  1.  2.  3.]]
----- testset -----
[[nan nan nan nan nan  2.  4.  2.  3.  5.]
 [nan nan nan nan nan  1.  3.  4.  3.  2.]
 [nan nan nan nan nan  1.  3.  4.  3.  2.]
 [nan nan nan nan nan nan  2.  2.  2.  1.]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]]
----- s -------
[[4.937 3.993 3.01  2.736 1.836 2.556 2.369 1.595 2.642 5.   ]
 [2.155 2.037 3.891 2.033 2.976 1.    3.113 4.036 2.813 2.374]
 [2.026 3.    3.919 1.806 2.796 1.    2.955 3.77  3.48  2.029]
 [2.001 2.959 2.004 1.643 1.977 1.994 2.028 1.412 2.273 1.642]
 [3.934 3.015 2.981 3.876 4.201 3.947 3.956 2.987 2.046 4.02 ]
 [2.01  4.895 2.9   1.973 3.001 2.956 2.98  1.991 3.941 1.084]
 [2.999 2.985 2.009 1.874 1.048 3.901 1.049 1.929 1.984 3.945]
 [3.993 3.985 5.    3.812 4.921 2.042 4.946 4.908 3.955 3.95 ]
 [4.909 4.915 3.967 1.958 1.077 1.062 2.007 2.002 3.962 4.958]
 [3.023 3.182 1.901 2.132 1.877 2.932 1.982 1.137 2.005 2.896]]
----- test_predict -------
[[  nan   nan   nan   nan   nan 2.556 2.369 1.595 2.642 5.   ]
 [  nan   nan   nan   nan   nan 1.    3.113 4.036 2.813 2.374]
 [  nan   nan   nan   nan   nan 1.    2.955 3.77  3.48  2.029]
 [  nan   nan   nan   nan   nan   nan 2.028 1.412 2.273 1.642]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]]
---- ユーザごとの推薦アイテム ----
ユーザ 0 への推薦アイテム: [9, 8, 5, 6, 7]
ユーザ 1 への推薦アイテム: [7, 6, 8, 9, 5]
ユーザ 2 への推薦アイテム: [7, 8, 6, 9, 5]
ユーザ 3 への推薦アイテム: [8, 6, 9, 7]

上のコード35行目では,読み込んだデータ data を訓練データとテストデータに分割しています.なお,GitHub から読み込んだ collaborative_filtering_ratings2.csv というファイルにおいて,テストデータとして利用したいデータを最後の19行に記録しているので,データをシャフルせず,最後の21%(つまり19件)のデータがテストデータになるようにしています.通常は shuffle=False を指定せずにデータをシャッフルしてから訓練データとテストデータに分割するとよいでしょう.あるいは,評価データに評価日時の情報もあれば評価日時でソートしてからシャッフルせずに分割する方法も考えられるでしょう.

19件をテストデータにする
trainset, testset = train_test_split(data, test_size=0.21, shuffle=False)  # シャッフルなし
# trainset, testset = train_test_split(data, test_size=0.21)               # シャッフルあり

訓練データとテストデータに分割した後,思った通りに分割されているかを上の38行目からのコードで確認します.訓練データには10人の顧客と10種類のアイテムがあり,100個の要素からなる評価値行列が作成されています.このうち,11個には評価が存在せず,89個の評価値データがあります.89個の評価値のうち,70個が訓練データとして利用され,19個がテストデータとして利用されることが確認できました.

正しく分割されていることを確認する
# 学習データの数をカウントする
n_train = sum(len(d) for d in trainset.ur.values())

# データ数などを確認する
print(f"number of trainset customers  ={trainset.n_users:4d}")
print(f"number of trainset items      ={trainset.n_items:4d}")
print(f"number of elements in matrix  ={trainset.n_users * trainset.n_items:4d}")
print(f"number of null ratings        ={trainset.n_users * trainset.n_items - df_ratings['rating'].shape[0]:4d}")
print(f"number of ratings in data     ={df_ratings['rating'].shape[0]:4d}")
print(f"number of ratings in trainset ={n_train:4d}")
print(f"number of ratings in testset  ={len(testset):4d}")
number of trainset customers  =  10
number of trainset items      =  10
number of elements in matrix  = 100
number of null ratings        =  11
number of ratings in data     =  89
number of ratings in trainset =  70
number of ratings in testset  =  19

上のコードにおいて50行目から86行目までは前のページと同様です.88行目から97行目ではテストデータのみの行列を作成し,訓練データと並べて表示ています.この部分は必ずしも必要ではありませんが,結果を視覚的に確認しやすくなる利点があるでしょう.


# テストデータのマトリックス
test_raw_matrix = np.zeros((trainset.n_users, trainset.n_items))
test_raw_matrix[:] = np.nan
for r, c, v in testset:
    test_raw_matrix[r, c] = v

print("----- trainset -------")
print(train_raw_matrix)
print("----- testset -----")
print(test_raw_matrix)
----- trainset -------
[[ 5.  4.  3. nan nan nan nan nan nan nan]
 [nan  2.  4.  2.  3. nan nan nan nan nan]
 [ 2.  3.  4. nan nan nan nan nan nan nan]
 [ 2.  3.  2. nan  2.  2. nan nan nan nan]
 [ 4.  3.  3.  4. nan  4.  4.  3.  2.  4.]
 [ 2.  5. nan  2.  3.  3.  3.  2.  4.  1.]
 [ 3.  3.  2. nan  1.  4.  1.  2.  2.  4.]
 [ 4.  4.  5. nan  5.  2.  5.  5.  4.  4.]
 [ 5.  5.  4.  2.  1.  1.  2.  2.  4.  5.]
 [ 3. nan  2.  2.  2.  3.  2.  1.  2.  3.]]
----- testset -----
[[nan nan nan nan nan  2.  4.  2.  3.  5.]
 [nan nan nan nan nan  1.  3.  4.  3.  2.]
 [nan nan nan nan nan  1.  3.  4.  3.  2.]
 [nan nan nan nan nan nan  2.  2.  2.  1.]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]
 [nan nan nan nan nan nan nan nan nan nan]]

99行目から110行目では,レイティング予測値の行列から,訓練データだけの予測値とテストデータだけの予測値を作成しています.この部分も必ずしも必要はありませんが,視覚的に理解をすることが目的です.なお,下の6行目や11行目では np.where~np.isnan を利用していることに注意してください.


print("----- s -------")
print(predict_matrix)

print("----- train_predict -------")
train_predict_matrix = np.copy(train_raw_matrix)
train_predict_matrix = np.where(~np.isnan(train_predict_matrix), predict_matrix, np.nan)
print(train_predict_matrix)

print("----- test_predict -------")
test_predict_matrix = np.copy(test_raw_matrix)
test_predict_matrix = np.where(~np.isnan(test_predict_matrix), predict_matrix, np.nan)
print(test_predict_matrix)
----- s -------
[[4.937 3.993 3.01  2.736 1.836 2.556 2.369 1.595 2.642 5.   ]
 [2.155 2.037 3.891 2.033 2.976 1.    3.113 4.036 2.813 2.374]
 [2.026 3.    3.919 1.806 2.796 1.    2.955 3.77  3.48  2.029]
 [2.001 2.959 2.004 1.643 1.977 1.994 2.028 1.412 2.273 1.642]
 [3.934 3.015 2.981 3.876 4.201 3.947 3.956 2.987 2.046 4.02 ]
 [2.01  4.895 2.9   1.973 3.001 2.956 2.98  1.991 3.941 1.084]
 [2.999 2.985 2.009 1.874 1.048 3.901 1.049 1.929 1.984 3.945]
 [3.993 3.985 5.    3.812 4.921 2.042 4.946 4.908 3.955 3.95 ]
 [4.909 4.915 3.967 1.958 1.077 1.062 2.007 2.002 3.962 4.958]
 [3.023 3.182 1.901 2.132 1.877 2.932 1.982 1.137 2.005 2.896]]
----- train_predict -------
[[4.937 3.993 3.01    nan   nan   nan   nan   nan   nan   nan]
 [  nan 2.037 3.891 2.033 2.976   nan   nan   nan   nan   nan]
 [2.026 3.    3.919   nan   nan   nan   nan   nan   nan   nan]
 [2.001 2.959 2.004   nan 1.977 1.994   nan   nan   nan   nan]
 [3.934 3.015 2.981 3.876   nan 3.947 3.956 2.987 2.046 4.02 ]
 [2.01  4.895   nan 1.973 3.001 2.956 2.98  1.991 3.941 1.084]
 [2.999 2.985 2.009   nan 1.048 3.901 1.049 1.929 1.984 3.945]
 [3.993 3.985 5.      nan 4.921 2.042 4.946 4.908 3.955 3.95 ]
 [4.909 4.915 3.967 1.958 1.077 1.062 2.007 2.002 3.962 4.958]
 [3.023   nan 1.901 2.132 1.877 2.932 1.982 1.137 2.005 2.896]]
----- test_predict -------
[[  nan   nan   nan   nan   nan 2.556 2.369 1.595 2.642 5.   ]
 [  nan   nan   nan   nan   nan 1.    3.113 4.036 2.813 2.374]
 [  nan   nan   nan   nan   nan 1.    2.955 3.77  3.48  2.029]
 [  nan   nan   nan   nan   nan   nan 2.028 1.412 2.273 1.642]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]]

上のコード113行目ではテストデータでテストを行っています.その結果は test_predictions 次のとおり格納されています.


test_predictions = mf.test(testset)
test_predictions
[Prediction(uid=0, iid=5, r_ui=2.0, est=2.555887634896381, details={'was_impossible': False}),
 Prediction(uid=1, iid=5, r_ui=1.0, est=1, details={'was_impossible': False}),
 Prediction(uid=2, iid=5, r_ui=1.0, est=1, details={'was_impossible': False}),
 Prediction(uid=0, iid=6, r_ui=4.0, est=2.3688414499823414, details={'was_impossible': False}),
 Prediction(uid=1, iid=6, r_ui=3.0, est=3.11335734405957, details={'was_impossible': False}),
 Prediction(uid=2, iid=6, r_ui=3.0, est=2.954813314836426, details={'was_impossible': False}),
 Prediction(uid=3, iid=6, r_ui=2.0, est=2.027915113978186, details={'was_impossible': False}),
 Prediction(uid=0, iid=7, r_ui=2.0, est=1.5945790718983173, details={'was_impossible': False}),
 Prediction(uid=1, iid=7, r_ui=4.0, est=4.035744538184163, details={'was_impossible': False}),
 Prediction(uid=2, iid=7, r_ui=4.0, est=3.77035814328444, details={'was_impossible': False}),
 Prediction(uid=3, iid=7, r_ui=2.0, est=1.4122252335038672, details={'was_impossible': False}),
 Prediction(uid=0, iid=8, r_ui=3.0, est=2.6418791394427394, details={'was_impossible': False}),
 Prediction(uid=1, iid=8, r_ui=3.0, est=2.812874758153092, details={'was_impossible': False}),
 Prediction(uid=2, iid=8, r_ui=3.0, est=3.47959405725432, details={'was_impossible': False}),
 Prediction(uid=3, iid=8, r_ui=2.0, est=2.2728922587523437, details={'was_impossible': False}),
 Prediction(uid=0, iid=9, r_ui=5.0, est=5, details={'was_impossible': False}),
 Prediction(uid=1, iid=9, r_ui=2.0, est=2.373842411543232, details={'was_impossible': False}),
 Prediction(uid=2, iid=9, r_ui=2.0, est=2.028637946005516, details={'was_impossible': False}),
 Prediction(uid=3, iid=9, r_ui=1.0, est=1.6420496970184506, details={'was_impossible': False})]

上で求めた test_predictions を利用して,ユーザごとに予測値が高いアイテムを順に最大5件取り出します.なお,上のコード11行目からの関数 get_top_n の実装については,こちらを参照してください.


def get_top_n(predictions, n=10):
    """
    ユーザごとにレイティングの予測値が高いN個の推薦リストを作成する
    """
    # ユーザごとの予測値リストを作成
    top_n = defaultdict(list)
    for uid, iid, true_r, est, _ in predictions:
        top_n[uid].append((iid, est))

    # ソートして上位 n個のリストを作成する
    for uid, user_ratings in top_n.items():
        user_ratings.sort(key=lambda x: x[1], reverse=True)
        top_n[uid] = user_ratings[:n]

    return top_n

...(中略)...

print(test_predict_matrix)

...(中略)...

top_n = get_top_n(test_predictions, n=5)  # ここで抽出するアイテム数 n を設定する
print("---- ユーザごとの推薦アイテム ----")
for uid, user_ratings in top_n.items():
    print(f"ユーザ {uid} への推薦アイテム: {[iid for (iid, _) in user_ratings]}")
----- test_predict -------
[[  nan   nan   nan   nan   nan 2.556 2.369 1.595 2.642 5.   ]
 [  nan   nan   nan   nan   nan 1.    3.113 4.036 2.813 2.374]
 [  nan   nan   nan   nan   nan 1.    2.955 3.77  3.48  2.029]
 [  nan   nan   nan   nan   nan   nan 2.028 1.412 2.273 1.642]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]
 [  nan   nan   nan   nan   nan   nan   nan   nan   nan   nan]]
---- ユーザごとの推薦アイテム ----
ユーザ 0 への推薦アイテム: [9, 8, 5, 6, 7]
ユーザ 1 への推薦アイテム: [7, 6, 8, 9, 5]
ユーザ 2 への推薦アイテム: [7, 8, 6, 9, 5]
ユーザ 3 への推薦アイテム: [8, 6, 9, 7]

つまり,ユーザ 0 (Etoさん) への推薦アイテムトップ5は 9(商品J),8(商品I),5(商品F),6(商品G),7(商品H)であることがわかりました.ただし,テストデータのサイズが小さいことから,レイティングの予測値が低い商品であっても推薦アイテムのリストに含まれる可能性があることには注意してください.特にユーザ 1 や 2 への推薦アイテムの中に評価値が最低ランク(1)であるアイテムが含まれていることに注意してください.

また,このページでは行列分解による推薦モデルに基づいてユーザごとの推薦アイテムリストを生成しました.しかしながら,surprise に利用できる他のモデルであっても同じ様にユーザごとの推薦アイテムリストを生成できることにも注意してください.

目次に戻る