Recommenders で推薦システムを作ろう

タグ

投稿日: 2021/10/02 09:27:00

著者: 代表取締役CEO 木村 優志

推薦システム

AmazonやNetflixを使うとき、「他の人はこちらも買っています!」や「〇〇を見た人にはこれがおすすめ」と推薦されます。様々なウェブサービスでは推薦システムを利用して、ユーザー体験の向上を図っています。今回は、推薦システムを構築するためのフレームワークについて説明します。

Microsoft Recommenders

Microsoft Recommenders は Microsoft が開発しているオープンソースの推薦システムフレームワークです。30 種類超のアルゴリズムが利用でき、推薦システムを簡単に構築できます。

ソースコードは github から得られます。https://github.com/microsoft/recommenders

ここでは、簡単な例で Recommenders の利用方法を見ていきましょう。なお、公式の examples とほぼ同じ内容です。 以下の例は、Recommenders で LightGBM アルゴリズムをつかって、Criteo dataset の学習、推薦を行うコードです。 今回の例は、どちらかというと、LightGBM 学習に渡すためのデータの整形を Recommenders でしています。 Criteo dataset はユーザーのクリック履歴のデータです。

import sys
import os
import numpy as np
import lightgbm as lgb
import papermill as pm
import pandas as pd
import category_encoders as ce
from tempfile import TemporaryDirectory
from sklearn.metrics import roc_auc_score, log_loss

import recommenders.models.lightgbm.lightgbm_utils as lgb_utils
import recommenders.datasets.criteo as criteo

# LightGBMのパラメータ
MAX_LEAF = 64
MIN_DATA = 20
NUM_OF_TREES = 100
TREE_LEARNING_RATE = 0.15
EARLY_STOPPING_ROUNDS = 20
METRIC = "auc"
SIZE = "sample"
params = {
    'task': 'train',
    'boosting_type': 'gbdt',
    'num_class': 1,
    'objective': "binary",
    'metric': METRIC,
    'num_leaves': MAX_LEAF,
    'min_data': MIN_DATA,
    'boost_from_average': True,
    #set it according to your cpu cores.
    'num_threads': 20,
    'feature_fraction': 0.8,
    'learning_rate': TREE_LEARNING_RATE,
}

nume_cols = ["I" + str(i) for i in range(1, 14)]
cate_cols = ["C" + str(i) for i in range(1, 27)]
label_col = "Label"

header = [label_col] + nume_cols + cate_cols
with TemporaryDirectory() as tmp:
    all_data = criteo.load_pandas_df(size=SIZE, local_cache_path=tmp, header=header)
# display(all_data.head())

# split data to 3 sets
length = len(all_data)
train_data = all_data.loc[:0.8*length-1]
valid_data = all_data.loc[0.8*length:0.9*length-1]
test_data = all_data.loc[0.9*length:]

# Label-encoding and Binary-encoding
# Recommendersをつかって Label Encoding と Binary Encodingを行います。
num_encoder = lgb_utils.NumEncoder(cate_cols, nume_cols, label_col)
train_x, train_y = num_encoder.fit_transform(train_data)
valid_x, valid_y = num_encoder.transform(valid_data)
test_x, test_y = num_encoder.transform(test_data)
del num_encoder
print('Train Data Shape: X: {trn_x_shape}; Y: {trn_y_shape}.\nValid Data Shape: X: {vld_x_shape}; Y: {vld_y_shape}.\nTest Data Shape: X: {tst_x_shape}; Y: {tst_y_shape}.\n'
      .format(trn_x_shape=train_x.shape,
              trn_y_shape=train_y.shape,
              vld_x_shape=valid_x.shape,
              vld_y_shape=valid_y.shape,
              tst_x_shape=test_x.shape,
              tst_y_shape=test_y.shape,))

# LightGBMを学習
lgb_train = lgb.Dataset(train_x, train_y.reshape(-1), params=params)
lgb_valid = lgb.Dataset(valid_x, valid_y.reshape(-1), reference=lgb_train)
lgb_model = lgb.train(params,
                      lgb_train,
                      num_boost_round=NUM_OF_TREES,
                      early_stopping_rounds=EARLY_STOPPING_ROUNDS,
                      valid_sets=lgb_valid)

# 予測と結果の表示
test_preds = lgb_model.predict(test_x)
auc = roc_auc_score(np.asarray(test_y.reshape(-1)), np.asarray(test_preds))
logloss = log_loss(np.asarray(test_y.reshape(-1)), np.asarray(test_preds), eps=1e-12)
res_optim = {"auc": auc, "logloss": logloss}
print(res_optim)

推薦の精度は以下のとおりでした。AUC は約 77.6% でした。

{'auc': 0.7758548016657666, 'logloss': 0.46030887404896165}

ラベルや特徴量のエンコーディングが Recommenders で簡単にできるため便利です。もちろん、Recommenders が独自で実装しているアルゴリズムもあります。