今回は↓cofiCostFunc.mのCollaborative Filetering Costに取り組みます。
問題文を読む
VideoであったRecommender Systemを作成する問題です。
943のユーザー(nu)
1,682の映画(nm)
が1-5の評価をしている
cofiCostFunc.mはcollaborative filteringとGradientを計算する。
costFunctionとGradientを計算の後に
fmincg.mでCollaborative filteringのthetaを計算する。
少し違和感があるので書き留めておきます。
costfunctionとGradientは最適θを探す常套手段ですが、
そのcostfunctionの基はcollaborative fileteringかと思ってました。
costfunction/Gradient/fmincig/最適thetaはセットだと思っていたので、
「後に」と順序がつくことに違和感を感じました。
きっと正しく理解できていないから違和感があると思います。
課題に取り組むときに引っかかるかと思ったので書き留めました。
Yは映画のレビュー(1から5)のDataということです。
1682映画の943ユーザーのデータなので、
1682X943のベクトルで構成要素が1~5です。
Rは同じく映画のレビューのDataで、
レビューがあるかないかに特化したDataで
同じく1682映画の94ユーザーで構成要素が0か1です。
図にするとこういうことだと思います↓
XとthetaもDataとして設定されていますが、こちらがよくわかりません。
絵にするとこういうことだと思いますが↓
『 Both x(i) and (j) are n-dimensional vectors.』がよくわかりません。
Xは1682のmovieを軸にしたレビューの計算用パラメーターかと推測します。
Thetaは943のユーザーを軸にしたレビューの計算用パラメーターかと推測します。
それでも、nの数を勝手に決めていいのか、
最適なnを決める方法はあるのか、課題に取り組みながら考えます。
movieを軸とした計算、ユーザーを軸とした計算をコラボさせて
最適パラメーターを探すということですね。
CostFunctonの答えは22.22ということが問題文の中で示されてるので
試行錯誤の中では22.22を目指して頑張りたいと思います。
プログラム全体版(ex8_cofi.m)を読む
movie1つ目の平均を出すために↓の式が書かれていました。
mean(Y(1, R(1, :))))
R(1,:)で1682X943のベクトルの1列目だけを抜粋してあり、
1X943で構成要素はすべて1か0になってます。
続いてY(1,R(1,:))でRが1のYだけが表示されるので、平均をとれています。
元々は1682X943のベクトルですが、サンプルを減少させて計算する方針のようです。
'ex8_movieParams.mat`は
Y 5X4
R 5X4
X 1682X10
Theta 943X10
とかなり削減された数になっています。
これをさらに
X 5X3
Theta 4X3
Xはmovie用のパラメーターなのでmovieの5に合わせて、
Thetaはユーザー用のパラメーターなので4に合わせているという感じですかね(-.-)
10-->3にしたのは計算を削ってることになりそうです。
プログラム詳細版(cofiCostFunc.m)を読む
[J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
num_features, lambda)
の式を計算するので、
結果はJとgradで入力変数がparams,Y,R,num_users, num_movies, num_features, lambdaになっています。
今回は
num_users = 4; num_movies = 5; num_features = 3
と設定されています。
lambdaはRegularization用ですね。最初は不要のようです。
paramsは何か分かりませんね、試行錯誤の中でみてみます。
試行錯誤する
まずはDataをみてみます。
5X4、つまり5個の映画と4人のユーザーの評価をしめすYとRは↓でした。
loadしたてのX;5X3とTheta;4X3は↓でした。
3がnのことなのでこれはXとThetaで共通になるということなんでしょうか。
これは制約/条件かもしれませんね。
つまり映画系のパラメーターを10次元で、ユーザー系のパラメーターは5次元
という風に違えることはできないという制約/条件があるかもしれないと思いました。
次にCostFunctionの計算をする前に、いろいろと前処理が既に
書かれていたのでこれを解読していきます。
paramsは何かを見ていたのですが、
問題文全体(ex8cofi.m)に
cofiCostFunc([X(:) ; Theta(:)], Y, R, num_users, num_movies, ...
num_features, 0)
問題文詳細(cofiCostFunc)に
cofiCostFunc(params, Y, R, num_users, num_movies, ...
num_features, lambda)
とあるので、
params=[X(:) ; Theta(:)]
ですね。
X(:)は縦一列にする式でした。↓参照
『;』は列追加なので↓は縦一列になります。
Xが5X3、Thetaが4X3だったので合計27ですね。
X = reshape(params(1:num_movies*num_features), num_movies, num_features);
そしてXを再編成しています。
num_users = 4; num_movies = 5; num_features = 3なので、
1から15までのparamsのDataを5X3に直すということですね。
元々Xは5X3だったので同じままです。
Theta = reshape(params(num_movies*num_features+1:end), ...
num_users, num_features);
これはThetaの再編成ですが、16から最後(27)までを
4X3に直すので、これまた同じままです。
ここでようやく解読が終了してCostFunctionを考え始めます。
要はするにこのYで0のところにいい予測をしなさいということだと思いますが、
予測があってるかどうか検討できるサンプルは6個だけということですね。
(Yで1-5になっているのが6個なので)
とりあえずY.*RにしてR=0で未入力のものをレビューでも確実に0にします。
Y.*Rがレビューサンプル(5X4)で、
映画側からの予測値はX'*Y.*Rで3X5と5X4の掛け算で3X4と考えてみました。
ユーザー側からの予測値はY.*R*Thetaで5X4と4X3の掛け算で5X4と考えてみました。
無理やり次元で↑このように考えましたがだめですね。
最終的にはY.*Rの5X4から予測値5X4を引いて誤差を計算したいので、
予測値が5X4以外になってしまうと、引き算ができません。
予測値は5X4でなければならないので、
5X4 X パラメーター =5X4 になるのは4X4以外にはありえないと考えてみました。
しかし手持ちのパラメーターはXが5X3、Thetaが4X3です。
たとえLinear Regressionみたいに1次元を足すことをしても4X4にはなりません。。。
やはり次元から考えて、あまり本質を見てなかった気がするので、
考え方を変えてみます。
映画ごと目線で考えてみました↓
でもAがわからないですね。。。
一回Videoに戻ることにします。
この特に
ですね。
Videoの時はよくわかってませんでしたが、
θjはユーザーj用のパラメータでそれxiで映画iとかけています。
そうするとθjはここではTheta 4X3で
xiは5X4を1列ずつ取り出すので1X4の列です。
と思いましたが違和感あります。
今回はここまでです。また次回頑張ります。