はじめに
Pythonによるベイズモデルの実装をきちんと学ぼうと思い,森賀新・木田悠歩・須山敦志 著 「Pythonではじめるベイズ機械学習入門」を読むことにした。
本記事は,第4章「潜在変数モデル」のうち確率的行列分解に関する読書メモである。
- 本書の紹介ページ
4.2 行列分解モデル
行列分解モデル(Matrix Factorization Model)は,観測値を表す行列を,より次元の小さい行列の積に分解することである。
ノイズを除外した本質的なデータの特徴を得られることや,欠損値を補完できることがその利点である。
4.2.4 モデル概要 : 確率的行列分解
レコメンデーションにおいて,協調フィルタリング(Collaborative Filtering)は最も一般的な手法である。
確率的行列分解は,協調フィルタリングの代表的な手法の1つである。
確率的行列分解では,ユーザおよびアイテムを,その潜在的な特徴を表す低次元の埋め込みベクトルで表現する。ユーザとアイテムの埋め込みベクトルの類似度を評価し,類似度が高いほど両者がマッチしている,と評価する。
具体的なモデル式について説明する。
ユーザの数を,アイテムの数を
,ユーザ
のアイテム
に対する評価を
とする。
このため,レーティング行列は,
となる。
ユーザの埋め込みベクトルを,アイテムの埋め込みベクトルを
とする。
さらに,をまとめた行列
を
,
をまとめた行列
を
とする。
の関係を表すと下図のようになる。

次に確率モデルを考える。
ユーザはすべてのアイテムを評価しているわけではないので,ユーザがアイテム
を評価している場合に1,それ以外は0となる指示変数
を導入する。
レーティング行列が従う確率分布を以下のように定義する。
また,の事前分布は平均0のガウス分布とする。
精度パラメータに事前分布を設定してもよいが,本節では簡単のため固定値とする。
4.2.5 実装:確率的行列分解によるレコメンデーション
サンプルコードを動かしながら,挙動を確認した。
github.com
データの準備
データは,GroupLensが公開しているMovieLens 100Kという,映画のレーティングに関するデータセットを題材とする。
http://files.grouplens.org/datasets/movielens/ml-100k/u.data
列は,ユーザID(user_id),映画ID(item_id),レーティング(rating)の順に並んでいる。
| user_id | item_id | rating | |
|---|---|---|---|
| 0 | 196 | 242 | 3 |
| 1 | 186 | 302 | 3 |
| 2 | 22 | 377 | 1 |
| 3 | 244 | 51 | 2 |
| 4 | 166 | 346 | 1 |
このデータは,
- ユーザ数:943人
- 映画:1682本
- レーティングがついていない割合:94%
という,欠損値が非常に多いデータである。
本節では,MovieLens 100Kのデータを学習データとテストデータに分割し,確率的行列分解によるレーティングの予測性能を評価する。
なおテストデータには,ランダムに選択した10%を用いる。
評価
評価指標には,二乗平均平方誤差(Root Mean Squared Error; RMSE)を用いる。
また予測結果と比較するために,ユーザごとの平均レーティング・映画ごとの平均レーティング・全体の平均レーティングの3つの平均値の平均をベースラインとする。
なお,ベースラインのRMSEは1.02であった。
MCMCによる事後分布からのサンプリング
MCMCによるサンプリングを行なう。2024年12月現在,PyMC3ではなくPyMCを使うので,ライブラリのインポート設定は以下のようになる。
#import pymc3 as pm import pymc as pm
本節において,サンプリングにはHMCを用いるが,サンプルの自己相関が高めだったため,MCMCで得られる5つのサンプルごとに1つだけ取り出す(間引き(thinning))。
は大きい行列であるため,各パラメータのトレースプロットを確認することは,膨大なパラメータを確認する必要があり難しい。
そのため,各ステップにおけるのフロベニウスノルムを可視化する。なおフロベニウスノルムは,
のように定義する。
フロベニウスノルムの推移は下図の通りである。

確認したところ,フロベニウスノルムは安定して推移しているように見える。
レーティングの予測
得られた事後分布からのサンプルを用いて,予測性能の評価を行なう。
MCMCにより,ステップごとののサンプルが得られるので,このサンプルを用いて
の確率分布を定義し,この確率分布から得られるサンプルをRのサンプルとみなす。
またRのサンプルについて,①各時点でのサンプルの値と,②各時点までのサンプルの平均値 の2種類が考えられる。
これに学習データとテストデータを組合わせて,以下の4種類のRMSEを評価する。
- per-step-train : ある時点の
の予測値と,学習データとのRMSE
- running-train : ある時点までの
の予測値の平均と,学習データとのRMSE
- per-step-test : ある時点の
の予測値と,テストデータとのRMSE
- running-test : ある時点までの
の予測値の平均と,テストデータとのRMSE
MCMCのサンプルごとの各種RMSEの推移は下図のようになる。

per-step-trainとper-step-test,およびrunning-trainとrunning-testとを比較すると,いずれも学習データのRMSEが小さくなっているため過剰適合を起こしているが,ベースラインのRMSEである1.02よりも良い値(小さい値)が得られていることが確認できた。
まとめと感想
潜在変数モデルのうち,確率的行列分解について学んだ。
行列分解により,行列の潜在的な特徴が得られて,ユーザ間の類似度を計算できるようになるなど,様々な情報を得られることが分かった。
行列分解の手法や用途は他にもあると考えられるので,今後調べてみたい。
本記事を最後まで読んでくださり,どうもありがとうございました。