🤩

LibRecommenderが使いやすかった話

2024/06/15に公開

はじめに

  • Two-Towerなどの推薦アルゴリズムについて調査を進めている中で、LibRecommenderについての日本語の記事がなかったので、復習がてら、執筆しました。参考になれば幸いです。

Librecommenderとは?(以下、引用)

概要

LibRecommender は、エンドツーエンドの推奨プロセスに重点を置いた、使いやすい推奨システムです。トレーニング (libreco) およびサービング (libserving) モジュールが含まれており、ユーザーはさまざまな種類の推奨モデルをすばやくトレーニングしてデプロイできます。

主な機能は次のとおりです:

  • FM、DIN、LightGCN などの一般的な推奨アルゴリズムを多数実装しています。完全なアルゴリズム リスト を参照してください。
  • ハイブリッド推奨システム。ユーザーは、協調フィルタリングまたはコンテンツベースの機能のいずれかを使用できます。新機能は、オンザフライで追加できます。
  • メモリ使用量が少なく、カテゴリおよび多値カテゴリ機能をスパース表現に自動的に変換します。
  • 明示的および暗黙的なデータセットの両方のトレーニング、および暗黙的なデータのネガティブ サンプリングをサポートします。
  • エンドツーエンドのワークフロー (データ処理/前処理 -> モデル トレーニング -> 評価 -> 保存/読み込み -> 提供) を提供します。
  • コールド スタート予測と推奨をサポートします。
  • 動的な機能とシーケンスの推奨をサポートします。
  • すべてのアルゴリズムに統一された使いやすい API を提供します。
  • 新しいデータから新しいユーザー/アイテムを使用してモデルを簡単に再トレーニングできます。

References

Algorithm Category Backend Sequence Graph Embedding Paper
userCF / itemCF pure Cython, Rust Item-Based Collaborative Filtering
SVD pure TensorFlow1 Matrix Factorization Techniques
SVD++ pure TensorFlow1 Factorization Meets the Neighborhood
ALS pure Cython 1. Matrix Completion via Alternating Least Square(ALS)
2. Collaborative Filtering for Implicit Feedback Datasets
3. Conjugate Gradient for Implicit Feedback
NCF pure TensorFlow1 Neural Collaborative Filtering
BPR pure Cython, TensorFlow1 Bayesian Personalized Ranking
Wide & Deep feat TensorFlow1 Wide & Deep Learning for Recommender Systems
FM feat TensorFlow1 Factorization Machines
DeepFM feat TensorFlow1 DeepFM
YouTubeRetrieval feat TensorFlow1 Deep Neural Networks for YouTube Recommendations
YouTubeRanking feat TensorFlow1 Deep Neural Networks for YouTube Recommendations
AutoInt feat TensorFlow1 AutoInt
DIN feat TensorFlow1 Deep Interest Network
Item2Vec pure / Item2Vec
RNN4Rec / GRU4Rec pure TensorFlow1 Session-based Recommendations with Recurrent Neural Networks
Caser pure TensorFlow1 Personalized Top-N Sequential Recommendation via Convolutional
WaveNet pure TensorFlow1 WaveNet: A Generative Model for Raw Audio
DeepWalk pure / DeepWalk
NGCF pure PyTorch Neural Graph Collaborative Filtering
LightGCN pure PyTorch LightGCN
GraphSage feat DGL, PyTorch Inductive Representation Learning on Large Graphs
PinSage feat DGL, PyTorch Graph Convolutional Neural Networks for Web-Scale
TwoTower feat TensorFlow1 1. Sampling-Bias-Corrected Neural Modeling for Large Corpus Item
2. Self-supervised Learning for Large-scale Item
Transformer feat TensorFlow1 1. BST
2. Transformers4Rec
3. RMSNorm
SIM feat TensorFlow1 SIM
Swing pure Rust Swing

[1] Category: pure は行動データのみを使用する協調フィルタリング アルゴリズムを意味し、feat は他の副次的特徴を含めることができることを意味します。

[2] Sequence: ユーザーの行動シーケンスを活用するアルゴリズム。

[3] Graph: グラフ埋め込み (GE) やグラフ ニューラル ネットワーク (GNN) などのグラフ情報を活用するアルゴリズム。

[4] Embedding: 最終的なユーザーおよびアイテムの埋め込みを生成できるアルゴリズム。

デモ(TwoTower)

Open in Colab

データ準備

  • 数値とカテゴリのカラムを設定してデータを準備する
    ※この際に、ユーザーに該当するからむを’user’,アイテムに該当するカラムを’item’、スコアやレートに該当するカラムを'label'に変名し、左側に置いておかないとエラーになります。
from libreco.data import DatasetFeat

sparse_col = ["sex", "occupation", "genre1", "genre2", "genre3"]
dense_col = ["age"]
user_col = ["sex", "age", "occupation"]
item_col = ["genre1", "genre2", "genre3"]

train_data, data_info = DatasetFeat.build_trainset(train_data, user_col, item_col, sparse_col, dense_col)
eval_data = DatasetFeat.build_evalset(eval_data)
test_data = DatasetFeat.build_testset(test_data)

学習

  • 今回は少し細かく設定しています。
from libreco.algorithms import TwoTower

model = TwoTower(
    "ranking",
    data_info,
    loss_type='softmax', 
    embed_size=16, 
    norm_embed=False, 
    n_epochs=5, 
    lr=0.001, 
    batch_size=256, 
    sampler='popular', 
    num_neg=1, 
    use_bn=True, 
    dropout_rate=0.1, 
    hidden_units=(128, 64, 32), 
    margin=1.0, 
    use_correction=True, 
    temperature=1.0, 
    remove_accidental_hits=True, 
    ssl_pattern=None, 
    alpha=0.2, 
    seed=42, 
    tf_sess_config=None
)
model.fit(train_data, 
          neg_sampling=True,
          verbose=2, 
          shuffle=True, 
          eval_data=eval_data, 
          metrics=["loss", "roc_auc", "precision", "recall", "ndcg"],
          k=10, 
          eval_batch_size=8192)
# train: 100%|██████████| 1563/1563 [00:16<00:00, 94.80it/s] 
# Epoch 5 elapsed: 16.498s
# 	 train_loss: 5.1638
# eval_pointwise: 100%|██████████| 13/13 [00:00<00:00, 541.06it/s]
# eval_listwise: 100%|██████████| 2797/2797 [00:01<00:00, 1860.42it/s]
# 	 eval log_loss: 0.4866
# 	 eval roc_auc: 0.8689
# 	 eval precision@10: 0.0451
# 	 eval recall@10: 0.0827
# 	 eval ndcg@10: 0.1794
# ==============================

評価

from libreco.evaluation import evaluate

evaluate(
    model=model,
    data=test_data,
    neg_sampling=True,  # perform negative sampling on test data
    metrics=["loss", "roc_auc", "precision", "recall", "ndcg"],
)
# eval_pointwise: 100%|██████████| 13/13 [00:00<00:00, 405.12it/s]
# eval_listwise: 100%|██████████| 2834/2834 [00:01<00:00, 1905.65it/s]
# {'loss': 0.4876128090140591,
#  'roc_auc': 0.8681895942994191,
#  'precision': 0.04418563613905064,
#  'recall': 0.08114577510636821,
#  'ndcg': 0.17590274424371724}

予測

  • ユーザ名(ID)だけで予測可能です。
model.recommend_user(user=1, n_rec=3)
# {1: array([ 34, 595, 588])}
  • 複数ユーザも同時予測可能
model.recommend_user(user=[1, 2, 3], n_rec=3)
# {1: array([ 34, 595, 588]),
# 2: array([ 480,  377, 1617]),
# 3: array([1198, 2028, 1210])}
  • 属性情報を追加(またはその一部だけでも)も対応可能
model.recommend_user(user=1, n_rec=3, user_feats={"sex": "M", "age": 33})
# {1: array([1219,  919, 2858])}
  • ユーザーとアイテムのスコア算出も可能で、コールドスタート問題が発生した場合は平均で対応できる
model.predict(user=1, item=100, cold_start = 'average')
# array([0.01761321], dtype=float32)

感想

  • 個人的に扱ってみて良かったと思う点は以下です。
    • 属性情報(ユーザーの性別やアイテムのジャンル)を自動で処理してくれる
    • モデルの評価も自動でしてくれる
    • 予測の際に学習時に使用した属性情報を一部入力しなくとも予測ができる
    • 検索もスコア算出にも対応している
    • 商用利用可能

* バッチ予測系のタスクの場合であれば、業務上でも使える場面は多いのかなと感じました。

参考リンク

Discussion