推薦システムにおける評価手法の話

概要

この記事では、推薦システムにおける評価手法について詳述する。

評価手法の定義や性質、応用例について数式とPythonのコードを用いて具体例を示す。

また、評価手法のメリットとデメリットについても論じ、具体的な利用例として「movielens-100k」データセットを用いた実装例を紹介する。

いつか備忘録としてまとめようと思っていた内容で、簡潔にまとめて残しておく。

ソースコード

github

  • jupyter notebook形式のファイルはこちら

google colaboratory

  • google colaboratory で実行する場合はこちら

実行環境

OSはmacOSである。LinuxやUnixのコマンドとはオプションが異なりますので注意していただきたい。

!sw_vers
ProductName:		macOS
ProductVersion:		13.5.1
BuildVersion:		22G90
!python -V
Python 3.9.17

基本的なライブラリをインポートし watermark を利用してそのバージョンを確認しておきます。 ついでに乱数のseedの設定をします。

import random

import numpy as np


seed = 123
random_state = 123

random.seed(seed)
np.random.seed(seed)


from watermark import watermark

print(watermark(python=True, watermark=True, iversions=True, globals_=globals()))
Python implementation: CPython
Python version       : 3.9.17
IPython version      : 8.17.2

numpy     : 1.25.2
matplotlib: 3.8.1
pandas    : 2.0.3
scipy     : 1.11.2

Watermark: 2.4.3

推薦システムにおける評価手法

概要

推薦システムは、ユーザーにパーソナライズされたアイテムを提供するための技術である。 その性能を正確に評価することは、システムの改善とユーザー満足度の向上に直結する。 本記事では、私の推薦システム構築経験に基づきの評価手法について、基本的な評価指標から、オフライン評価とオンライン評価、そしてユーザー体験の評価までを網羅的に解説する。 数式とPythonのコード例を交えて、具体的な評価手法を説明する。

1. はじめに

推薦システムは、オンラインショッピング、動画配信サービス、音楽ストリーミングなど多くの分野で利用されている。 ユーザーに適切なアイテムを提供することで、ユーザーエンゲージメントを高め、ビジネスの成功に直結する。 評価手法の選定と実行は、システムの性能を理解し、最適化するために不可欠である。以下にその具体的な評価手法を解説する。

2. 推薦システムの基本評価指標

推薦システムの性能を評価する基本的な指標には、精度評価と誤差の評価がある。

2.1 精度評価

推薦システムの精度を評価する基本指標として、正解率(Precision)、再現率(Recall)、およびF1スコアがある。これらの指標は、推薦システム以外にも分類問題の評価においても広く用いられる。

  • 正解率(Precision) $$ \text{Precision} = \frac{TP}{TP + FP} $$ ここで、$TP$は真陽性(True Positives)、$FP$は偽陽性(False Positives)である。
from sklearn.metrics import precision_score

y_true_list = [1, 0, 1, 1, 0, 1, 0, 0, 1, 1]
y_pred_list = [1, 0, 1, 0, 0, 1, 0, 1, 0, 1]

precision = precision_score(y_true_list, y_pred_list)
print("Precision:", round(precision, 2))
Precision: 0.8
  • 再現率(Recall) $$ \text{Recall} = \frac{TP}{TP + FN} $$ ここで、$FN$は偽陰性(False Negatives)である。
from sklearn.metrics import recall_score

recall = recall_score(y_true_list, y_pred_list)
print("Recall:", round(recall, 2))
Recall: 0.67
  • F1スコア $$ \text{F1 Score} = \frac{2 \cdot \text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}} $$
from sklearn.metrics import f1_score

f1 = f1_score(y_true_list, y_pred_list)
print("F1 Score:", round(f1, 2))
F1 Score: 0.73

2.2 誤差

誤差を評価する指標として、平均絶対誤差(MAE)と二乗平均平方根誤差(RMSE)がある。これらの指標は、ratingの予測や回帰問題においても重要である。

  • 平均絶対誤差(MAE) $$ \text{MAE} = \frac{1}{N} \sum_{i=1}^{N} \left| y_i - \hat{y}_i \right| $$ ここで、$N$はサンプル数、$y_i$は実際の値、$\hat{y}_i$は予測値である。
from sklearn.metrics import mean_absolute_error

y_true_list = [3.5, 2.0, 4.0, 3.0, 5.0]
y_pred_list = [3.7, 2.1, 3.9, 3.2, 4.8]

mae = mean_absolute_error(y_true_list, y_pred_list)
print("MAE:", round(mae, 2))
MAE: 0.16
  • 二乗平均平方根誤差(RMSE) $$ \text{RMSE} = \sqrt{\frac{1}{N} \sum_{i=1}^{N} \left( y_i - \hat{y}_i \right)^2} $$
from sklearn.metrics import mean_squared_error
import numpy as np

mse = mean_squared_error(y_true_list, y_pred_list)
rmse = np.sqrt(mse)
print("RMSE:", round(rmse, 2))
RMSE: 0.17

3. 推薦システム特有の評価指標

推薦システムには、特有の評価指標がいくつか存在する。

これらは、一般的な精度評価や誤差の評価とは異なり、ユーザーの行動やランキングの精度を重視するものである。

3.1 Hit Rate (ヒット率)

ヒット率は、ユーザーが興味を示したアイテムが推薦リストに含まれている割合を示す。これは、推薦システムの基本的な成功指標の一つである。

  • ヒット率の定義 $$ \text{Hit Rate} = \frac{\text{Number of Hits}}{\text{Total Number of Users}} $$
def hit_rate(recommended_list, relevant_list):
    hits = sum([1 for rec in recommended_list if rec in relevant_list])
    return hits / len(recommended_list)


recommended_list = [1, 2, 3, 4, 5]
relevant_list = [1, 2, 3, 6, 7]

hr = hit_rate(recommended_list, relevant_list)
print("Hit Rate:", round(hr, 2))
Hit Rate: 0.6

3.2 MAP (平均順位平均精度)

平均順位平均精度(MAP)は、推薦結果の順位情報を考慮した評価指標である。ユーザーにとっての有用性をより正確に評価できる。

  • MAPの定義 $$ \text{MAP} = \frac{1}{|U|} \sum_{u \in U} \text{AP}(u) $$ ここで、$\text{AP}(u)$はユーザー$u$の平均精度、$|U|$はユーザー数である。
def average_precision(recommended_list, relevant_list):
    hits = 0
    sum_precisions = 0
    for i, rec in enumerate(recommended_list):
        if rec in relevant_list:
            hits += 1
            sum_precisions += hits / (i + 1)
    return sum_precisions / len(relevant_list)


recommended_list = [1, 2, 3, 4, 5]
relevant_list = [1, 2, 3]

ap = average_precision(recommended_list, relevant_list)
print("Average Precision:", round(ap, 2))

3.3 nDCG (正規化割引累積利得)

nDCG (正規化割引累積利得)は、順位の重要性を考慮した評価指標である。高順位のアイテムがより重要視される。

  • NDCGの定義 $$ \text{nDCG} = \frac{DCG}{IDCG} $$ ここで、$DCG$は割引累積利得、$IDCG$は理想的な累積利得である。
def dcg(recommended_list, relevant_list):
    return sum((1 if rec in relevant_list else 0) / np.log2(idx + 2) for idx, rec in enumerate(recommended_list))


def ndcg(recommended_list, relevant_list):
    dcg_val = dcg(recommended_list, relevant_list)
    idcg_val = dcg(sorted(relevant_list, reverse=True), relevant_list)
    return dcg_val / idcg_val


recommended_list = [1, 2, 3, 4, 5]
relevant_list = [1, 2, 6]

ndcg_val = ndcg(recommended_list, relevant_list)
print("NDCG:", round(ndcg_val, 2))
NDCG: 0.77

4. オフライン評価とオンライン評価

推薦システムの評価には、オフライン評価とオンライン評価の2種類がある。各手法にはそれぞれメリットとデメリットが存在する。

4.1 オフライン評価

オフライン評価は、事前に収集したデータを用いて評価を行う手法である。

  • メリットとデメリット

    メリットとして、低コストで迅速に評価が可能である。デメリットとして、実際のユーザー行動とは異なる可能性がある。

  • 適用方法と事例

    過去のデータを用いてシミュレーションを行い、システムの性能を評価する。例えば、MovieLensデータセットを使用して、評価を行うことができる。

import pandas as pd
from sklearn.model_selection import train_test_split

# データの読み込み
ratings = pd.read_csv(
    "https://files.grouplens.org/datasets/movielens/ml-100k/u.data",
    sep="\t",
    names=["user_id", "item_id", "rating", "timestamp"],
)

# 訓練データとテストデータに分割
train_data, test_data = train_test_split(ratings, test_size=0.2)

# 訓練データのサンプル表示
display(train_data.head())
user_iditem_idratingtimestamp
390027611552882607017
340315067721874873247
587286437393891449476
31812218545874951657
151972694143891449624

4.2 オンライン評価

オンライン評価は、実際のユーザーを対象に評価を行う手法である。

  • A/Bテスト A/Bテストは、異なるバージョンのシステムを比較するために用いられる。ユーザーをランダムにグループに分け、それぞれに異なるバージョンを提供し、その効果を比較する。

  • メリットとデメリット メリットとして、実際のユーザー行動を反映した評価が可能である。デメリットとして、実施に時間とコストがかかる。

# A/Bテストのシミュレーション例

# 適当なユーザーのクリック率を仮定
group_a_clicks = np.random.binomial(1, 0.1, 1000)  # グループAのクリック率10%
group_b_clicks = np.random.binomial(1, 0.15, 1000)  # グループBのクリック率15%

# クリック率の平均を計算
click_rate_a = np.mean(group_a_clicks)
click_rate_b = np.mean(group_b_clicks)

print("Group A Click Rate:", round(click_rate_a, 2))
print("Group B Click Rate:", round(click_rate_b, 2))

5. ユーザー体験の評価

推薦システムの成功には、ユーザー体験の評価も重要である。これには、ユーザー満足度とエンゲージメントの評価が含まれる。

5.1 ユーザー満足度

ユーザー満足度は、アンケートやフィードバックを通じて評価される。これは、システムの改善に直接役立つ情報を提供する。

  • アンケートやフィードバックの活用

    アンケートを通じてユーザーから直接意見を収集し、その結果をもとにシステムの改良を行う。

# 適当なサンプルアンケートデータ

feedback_data = {"user_id": [1, 2, 3, 4, 5], "satisfaction": [5, 4, 3, 4, 5]}

feedback_df = pd.DataFrame(feedback_data)
average_satisfaction = feedback_df["satisfaction"].mean()

print("Average User Satisfaction:", round(average_satisfaction, 2))

5.2 エンゲージメント

エンゲージメント指標は、ユーザーがシステムをどれだけ頻繁に利用しているかを示す。これにより、ユーザーの忠実度を測ることができる。

  • エンゲージメント指標の定義と重要性

    エンゲージメント指標は、ユーザーのシステム利用頻度や利用時間を測定する。これにより、ユーザーがシステムにどれだけ依存しているかを評価できる。

import pandas as pd

# 適当なサンプルエンゲージメントデータ
engagement_data = {
    "user_id": [1, 2, 3, 4, 5],
    "sessions": [10, 15, 5, 20, 25],
    "time_spent": [300, 450, 150, 600, 750],
}

engagement_df = pd.DataFrame(engagement_data)

average_sessions = engagement_df["sessions"].mean()
average_time_spent = engagement_df["time_spent"].mean()

print("Average Sessions per User:", round(average_sessions, 2))
print("Average Time Spent per User (minutes):", round(average_time_spent, 2))
Average Sessions per User: 15.0
Average Time Spent per User (minutes): 450.0

6. まとめ

評価手法の選択と組み合わせが重要である。継続的に評価と改善(PDCA)を行い、システムの性能を最適化することが求められる。評価は、システムの成功とユーザー満足度の向上に不可欠である。

結論

この記事では、推薦システムの評価手法について、基本指標から、オフライン評価とオンライン評価、ユーザー体験の評価まで幅広くざっと説明した。

適切な評価手法を選び、継続的にシステムの改善を行うことが、成功する推薦システムの構築には不可欠である。

推薦システム全体、評価指標などは以下の参考文献が最も参考になる。

参考文献:

  1. Aggarwal, C. C. (2016). Recommender Systems: The Textbook. Springer.