
だから、PerlのSVD。 として実行できる完成したスクリプト
こちらからダウンロードできます 。 トレーニング自体を行う一部を紹介します。./svd.pl _ dataset.csv
# SVD: , while (abs($old_rmse - $rmse) > 0.00001 ) { $old_rmse = $rmse; $rmse = 0; foreach my $u ( keys %l ) { foreach my $v ( keys %{$l{$u}} ) { # $err = $l{$u}{$v} - ($mu + $b_u[$u] + $b_v[$v] + dot($u_f[$u], $v_f[$v]) ); # $rmse += $err * $err; # ... $mu += $eta * $err; $b_u[$u] += $eta * ($err - $lambda2 * $b_u[$u]); $b_v[$v] += $eta * ($err - $lambda2 * $b_v[$v]); # ... for (my $f=0; $f < $features; ++$f) { $u_f[$u][$f] += $eta * ($err * $v_f[$v][$f] - $lambda2 * $u_f[$u][$f]); $v_f[$v][$f] += $eta * ($err * $u_f[$u][$f] - $lambda2 * $v_f[$v][$f]); } } } ++$iter_no; # , RMSE $rmse = sqrt($rmse / $total); print "Iteration $iter_no:\tRMSE=" . $rmse . "\n"; # RMSE , if ($rmse > $old_rmse - $threshold) { $eta = $eta * 0.66; $threshold = $threshold * 0.5; } }
ご覧のとおり、絶対に大丈夫です-重みの更新プロセスを開始し、収束するまで続行するだけです。 収束は、RMSE(二乗平均平方根誤差)-二乗平均平方根誤差、つまり 二乗誤差の合計のルートをテストケースの数で割ったもの。 確率的勾配降下法を実装します。各テストケースの後、すぐにパラメーターを変更し、データベース全体でエラー統計を収集しません。
RMSEが著しく改善されなくなると、学習速度が低下します。 このアプローチでは、遅かれ早かれ、プロセスは収束するはずです(つまり、RMSEの変更が停止するはずです)。 ここでλとは何ですか-次に説明しますが、今日の例ではゼロになります。
次に、最初のテキストの1つで検討した評価マトリックスに、持っているものを適用します。

適切な形式で、 ここからダウンロードできます (注文は保存されます)。 このデータセットでスクリプトを実行すると、次のようなものが得られます。
その結果、何が得られましたか? ほぼ予想どおり。 ユーザーは優しさに応じて基本的な予測因子を受け取りました。ペトロヴィッチは邪悪な観客であることが判明し、それとは対照的に、残りは優しく、特にジャンノチカです。 映画は、「全体的な品質」(評価によって自然に表現される)に従って基本的な予測因子を受け取りました。5人のユーザーと5つのURLを読みます。 反復1:RMSE = 1.92845291697284 反復2:RMSE = 1.28481736445124 反復3:RMSE = 1.14159530044051 ... 反復808:RMSE = 0.0580161117835789 反復809:RMSE = 0.0580061123741253 mu:2.54559533638261 ユーザーベース:0.7271 0.1626 0.7139 1.9097 -0.9677 アイテムベース:0.8450 0.6593 0.2731 0.7328 0.0354 ユーザー機能 ユーザー0:-0.5087 -0.8326 ユーザー1:1.0220 1.2826 ユーザー2:-0.9509 0.2792 ユーザー3:0.1031 -0.4814 ユーザー4:0.6095 0.0557 アイテムの特徴: アイテム0:-0.8368 0.2511 アイテム1:1.1101 0.4120 アイテム2:-0.4159 -0.4073 アイテム3:-0.3130 -0.9115 アイテム4:0.6408 1.2205
しかし、最も興味深いのは、残りのユーザー設定を2つの要因に合理的に分解したことです。 この例はもちろんおもちゃであり、データセットは最初、映画が「子豚について」と「トラクターについて」の映画に分けられることを暗示していました。 強力な機器を好むユーザーもいれば、豚の軟骨が好きなユーザーもいます。
実際、最初の要因はトラクターに関するフィルムの量であり、2番目の要因は豚に関するフィルムの量であることは明らかです。 特定の値には深い意味はなく、それらの比率のみが重要です。
ちなみに、私はデータセットに特に適合しませんでした。この場合、兆候を伴うおかしなケースがありました。SVDは、トラクター、VasyaとValerikaが好きな2人のユーザーに「トラクター」係数の負の値を教えました。 しかしこれに伴い、SVDは実際にトラクターに関する映画の「トラクター」係数にマイナスの値を教えました。マイナスはマイナスになります。 そして、ペトラの1.0220とは正反対に、彼のトラクターは豚と比較してまったく興味がないということです...
これで、トラクタードライバーに対するVasyaの評価の値を次のように予測できます。
2.5456 + 0.7271 + 0.8450 +(-0.5087)*(-0.8368)+(-0.8326)* 0.2511 = 4.3343143
まあ、Vasyaがトラクタードライバーを好むと本当に仮定できました。
次回は、過剰適合と正則化について説明します-それが何であるか、なぜそれが必要であるか、そしてそれをSVDで実装する方法。