【論文実装】Variational Bayesian Approach to Movie Rating PredictionをJuliaで実装
概要
個人的にBayesianなアプローチとMatrix Factorizationに最近興味を持っています。
そんなわけで今のところ以下のように色々と実験してきました。
その流れで今回はBayesianなMatrix Factorizationを変分推論で行うアルゴリズムをJulia*1で実装してみたいと思います。
変分推論でのアルゴリズムに関しては以下論文で導出されているものを使います。
https://www.cs.uic.edu/~liub/KDD-cup-2007/proceedings/variational-Lim.pdf
実験
実装の細かいところは見ていきませんが、今回の全体のコードは以下になります。
VariationalBayesianProbabilisticMatrixFactorization.ipynb · GitHub
データは毎度おなじみのMovie Lensを使います。
まずはMovie Lensに入る前に適当なデータで試してみます。
データを生成して、
#data r = [0 0 7; 0 1 6; 0 2 7; 0 3 4; 0 4 5; 0 5 4; 1 0 6; 1 1 7; 1 3 4; 1 4 3; 1 5 4; 2 1 3; 2 2 3; 2 3 1; 2 4 1; 3 0 1; 3 1 2; 3 2 2; 3 3 3; 3 4 3; 3 5 4; 4 0 1; 4 2 1; 4 3 2; 4 4 3; 4 5 3] #ユニークユーザー、ユニークアイテム n_user = length(unique(r[:, 1])) n_item = length(unique(r[:, 2]))
学習データをそのまま予測してみると、
#predict VBPMF = VariationalBayesianProbabilisticMatrixFactorization.VariationalBayesianProbabilisticMatrixFactorizationModel(r, n_user, n_item, 10, [], [], 1, [], [], 1) VariationalBayesianProbabilisticMatrixFactorization.fit(VBPMF) VariationalBayesianProbabilisticMatrixFactorization.predict(VBPMF, r)
こんな感じになり、
26-element Array{Float64,1}: 6.692476057466172 6.1856309538003025 6.6023995851109225 3.843760930267997 4.368901630969246 3.8651527589913917 5.379784014391833 6.080367423692413 3.8000648534494146 3.570123259237677 4.132226272977147 2.432525435655192 2.2979338001075487 1.385521188507398 1.3317745378407813 1.4525667678497998 2.3190717457234187 1.82068120537136 2.3566533381545547 2.4921900542852646 3.168846326743875 1.1256917357867615 1.288459642477627 1.8376837156781873 2.0115436500847883 2.458109288645016
なんとなく学習・予測できてそうです。
次にMovie Lensをやってみます。
using DataFrames using CSV #データ読み込み r = CSV.read("ml-100k/u.data", header = false, delim = '\t') #配列化 r = convert(Array{Int64}, r[:, 1:3]) #オフセット idの最小値を0にする r[:, 1, :] = r[:, 1, :] .- 1 r[:, 2, :] = r[:, 2, :] .- 1 #ユニークユーザー、ユニークアイテム n_user = length(unique(r[:, 1])) n_item = length(unique(r[:, 2]))
データの準備ができたので、速度計算のための準備をします。
function main() VBPMF = VariationalBayesianProbabilisticMatrixFactorization.VariationalBayesianProbabilisticMatrixFactorizationModel(r, n_user, n_item,10, [], [], 1, [], [], 10) VariationalBayesianProbabilisticMatrixFactorization.fit(VBPMF) sqrt(mean((r[:, 3] - VariationalBayesianProbabilisticMatrixFactorization.predict(VBPMF, r)) .^ 2)) end
速度を確認すると、
@time main()
結果としては、
26.401632 seconds (148.09 M allocations: 23.299 GiB, 5.14% gc time)
となりなんとなく速い気がします*2。
最後に学習データと検証データを分けて精度も確認します。
#学習データとテストデータ分割 N = size(r)[1] train_size = Int64(N * 0.8) train_df = r[1:train_size, :] test_df = r[train_size:N, :] #predict VBPMF = VariationalBayesianProbabilisticMatrixFactorization.VariationalBayesianProbabilisticMatrixFactorizationModel(train_df, n_user, n_item,10, [], [], 1, [], [], 10) VariationalBayesianProbabilisticMatrixFactorization.fit(VBPMF) sqrt(mean((test_df[:, 3] - VariationalBayesianProbabilisticMatrixFactorization.predict(VBPMF, test_df)) .^ 2))
精度は、
0.9579913656751956
いい感じに学習できてそうです。
まとめ
Bayesian Matrix Factorizationを変分推論で行うアルゴリズムをJuliaで実装してみました。
変分推論で行うことで計算速度の速さはなんとなく実感することができました。
ただちゃんと他のアルゴリズムの場合と比較しないとわからない点も多いと思うので、今後は他のアルゴリズムであるGibbs Sampling等との精度比較や速度比較をできたらと思います。
それでは間違い等ありましたらご指摘お願いいたします。