BigQueryML で好みのアニメを探してみる

Miki Katsuragi
google-cloud-jp
Published in
6 min readJun 29, 2020

この記事では、BigQueryML(BQML) で利用できるようになった行列分解のモデルでアニメの推薦システムを作ってみます。

注:2020年6月時点で BigQuery のオンデマンド料金プランでは行列分解モデルはご利用できません。試して頂くには、BigQuery の Reservations でクエリ定額制のスロットを購入してください。参考として、一時的に定額スロットが使用できるflex slotの料金はこちらを参照ください。

行列分解(Matrix Factorization)とは、一般的に、商品、映画、アプリなどの推薦システムに使用される行列分解の手法で、協調フィルタリングアルゴリズムの一種です。行列をアイテムとユーザの好みに分解し、目に見えないアイテムのうちどれがユーザーにとって関心があるかを予測するため、ユーザーの既存のアイテム評価から学習を行います。

データの準備

ここでは、KaggleのAnime Recommendations Databaseを使って自分好みのアニメを予測するモデルを作成します。このデータセットでは、Myanimelist.netの76000ユーザのアニメレビューデータで構成されており、1から10までの十段階で各アニメが評価されており(-1はレートがないことを意味します)、以下のようなデータ構造になっています。

anime(アニメの情報)
rating (ユーザのレーティング)

BigQueryで「anime」というデータセットを作成し、取り込んでみましょう。学習には、ユーザとレーティング情報を持つrating表を使いますが、事前に以下のSQLで重複したレーティングを持つユーザを除外します。

SELECT  *
FROM anime.rating
where rating > 0
and user_id not in (
SELECT user_id
FROM anime.rating
GROUP BY user_id,anime_id
HAVING
COUNT(rating) > 1
)

モデルの学習

上記の結果をanime.data_cleanという名称で保存し、次の SQL でモデルをトレーニングします。model_typeに「matrix_factorization」を指定し、user_col、item_col,rating_col にそれぞれユーザー、商品、評価レートを入力することになります。*l2_regは L2 正規化の量を、num_factors は行列分解モデルに使用する潜在的要素の数を示しています。

CREATE OR REPLACE MODEL anime.recommend
OPTIONS (model_type=’matrix_factorization’, user_col=’user_id’,
item_col=’anime_id’,rating_col=’rating’, l2_reg=9.83, num_factors=40) AS
SELECT * FROM anime.data_clean

ML.EVALUATEでモデルを評価してみましょう。この結果は、線形回帰モデルと同様の指標を返します。

SELECT * from ML.EVALUATE(MODEL anime.recommend)
ML.EVALUATE実行結果

予測

このアニメデータにはまだ私の評価が入っていないため、上位20件の高評価アニメが比較的自分と好みが似ていそうなid=22243におすすめのアニメを表示してみたいと思います。なお、好みが近そうなユーザは自分が好きなアニメをいくつかピックアップして以下のSQLで抽出しました。

SELECT d.user_id, count(a.name) cnt
FROM anime.data_clean d,anime.anime a
WHERE a.anime_id=d.anime_id
AND d.user_id in (
SELECT user_id
FROM anime.data_clean d
WHERE anime_id in (1,513,523,3572,9253,9756,10721,15227,11757)
GROUP BY d.user_id
HAVING count(anime_id) > 7
)
GROUP BY 1
ORDER BY 2 ASC

id=22243のユーザが高く評価しているアニメは以下のようなものがあげられます。

SELECT a.name,d.rating
FROM anime.data_clean d,anime.anime a
WHERE a.anime_id=d.anime_id
AND d.user_id = 22243
ORDER BY 2 DESC
id=22243が高く評価しているアニメの例

このユーザに対する推薦結果は、ML.RECOMMEND で表示することが可能です。

SELECT a.name,r.predicted_rating
FROM ML.RECOMMEND(MODEL anime.recommend) r,anime.anime a
WHERE a.anime_id=r.anime_id
AND r.user_id=22243
ORDER BY predicted_rating desc

この結果、おすすめのアニメ上位10件は以下のような結果となりました。モデルの決定係数はそれほど高くないものの、「君の名は」「Steins;Gate」といった自分が好きな作品が含まれていたので全く見当違いという結果でもなさそうです。一位の銀河英雄伝説はまだみたことがなかったので、機会があればぜひみてみようと思います。

--

--