Skip to content

Latest commit

 

History

History
400 lines (277 loc) · 38.6 KB

File metadata and controls

400 lines (277 loc) · 38.6 KB

プログラミング演習8: 異常検出とレコメンダー・システム

機械学習

はじめに

この演習では、異常検出アルゴリズムを実装し、それを適用してネットワーク上の障害のあるサーバーを検出します。 2番目のパートでは、協調フィルタリングを使用して映画のレコメンダー・システムを構築します。 プログラミング演習を始める前に、ビデオ講義を見て、関連トピックのレビュー質問を完了することを強くお勧めします。

演習を開始するには、スターター・コードをダウンロードし、演習を行うディレクトリーにその内容を解凍する必要があります。 必要に応じて、この演習を開始する前にOctave/MATLABのcdコマンドを使用して、このディレクトリーに移動してください。

また、コースウェブサイトの「環境設定手順」にOctave/MATLABをインストールするための手順も記載されています。

この演習に含まれるファイル

  • ex8.m - 演習の最初のパートのためのOctave/MATLABスクリプト
  • ex8_cofi.m - 演習の2番目のパートのためのOctave/MATLABスクリプト
  • ex8data1.mat - 最初のサンプルの異常検出のデータセット
  • ex8data2.mat - 2番目のサンプルの異常検出のデータセット
  • ex8_movies.mat - 映画のレビューのデータセット
  • ex8_movieParams.mat - デバッグ用に提供されるパラメーター
  • multivariateGaussian.m - ガウス分布の確率密度関数を計算する
  • visualizeFit.m - ガウス分布とデータセットを2次元にプロットする
  • checkCostFunction.m - 協調フィルタリングの勾配をチェックする
  • computeNumericalGradient.m - 数値的に勾配を計算する
  • fmincg.m - 関数最小化ルーチン(fminuncと同様)
  • loadMovieList.m - 映画のリストをセル配列にロードする
  • movie_ids.txt - 映画のリスト
  • normalizeRatings.m - 協調フィルタリングを平均正規化する
  • submit.m - 解答をサーバーに送信するスクリプト
  • [*] estimateGaussian.m - 対角共分散行列を持つガウス分布のパラメーターを推定する
  • [*] selectThreshold.m - 異常検出の閾値を見つける
  • [*] cofiCostFunc.m - 協調フィルタリングのためのコスト関数を実装する

* はあなたが完了する必要があるものを示しています。

演習の最初のパート(異常検出)では、ex8.mスクリプトを使用します。 2番目のパート(協調フィルタリング)では、ex8_cofi.mを使用します。 これらのスクリプトは、問題に対するデータセットをセットアップし、あなたが実装する関数を呼び出します。 こららのスクリプトを変更する必要はありません。 この課題の指示に従って、他のファイルの関数を変更することだけが求められています。

助けを得る場所

このコースの演習では、数値計算に適した高度なプログラミング言語であるOctave(※1)またはMATLABを使用します。 OctaveまたはMATLABがインストールされていない場合は、コースWebサイトのEnvironment Setup Instructionsのインストール手順を参照してください。

Octave/MATLABコマンドラインでは、helpの後に関数名を入力すると、組み込み関数のドキュメントが表示されます。 たとえば、help plotはプロットのヘルプ情報を表示します。 Octave関数の詳細なドキュメントは、Octaveのドキュメントページにあります。 MATLABのドキュメントは、MATLABのドキュメントページにあります。

また、オンライン・ディスカッションを使用して、他の学生との演習について話し合うことを強く推奨します。 しかし、他人が書いたソースコードを見たり、他の人とソースコードを共有したりしないでください。

※1:Octaveは、MATLABの無料の代替ソフトウェアです。 プログラミング演習は、OctaveとMATLABのどちらでも使用できます。

1. 異常検出

この演習では、異常検出アルゴリズムを実装して、サーバー・コンピューターの異常動作を検出します。 フィーチャーは、各サーバーのレスポンスのスループット(mb/s)と待ち時間(ms)です。 あなたは、サーバーが稼動している間に個のサンプルを収集しており、ラベルなしのデータセットを持っています。 これらのサンプルの大部分は、正常に動作するサーバーの「正常」な(異常ではない)サンプルですが、このデータセット内に異常な動作をするサーバーのサンプルもいくつか存在する可能性があります。

ガウスモデルを使用して、データセット内の異常なサンプルを検出します。 最初に、アルゴリズムが何をしているのかを可視化できる2Dのデータセットを表示することから始めます。 このデータセットにガウス分布を適合し、確率が非常に低い(それ故に異常と見なすことができる)値を見つけます。 その後、より大きな多次元のデータセットに異常検出アルゴリズムを適用します。 演習のこのパートでは、ex8.mを使用します。

ex8.mの最初のパートは、図1に示すようにデータセットを可視化します。

図1:最初のデータセット

     図1:最初のデータセット

1.1. ガウス分布

異常検出を実行するには、まずデータの分布にモデルを適合させる必要があります。

与えられたトレーニング・セット(ここで、)に対して、各フィーチャーのガウス分布を推定する必要があります。 の各フィーチャーに対して、番目の次元(各サンプルの番目の次元)のデータに適合するパラメーターを見つける必要があります。

ガウス分布は、以下の式で与えられます。

式1

ここで、は平均値、は分散を制御します。

1.2. ガウス分布のパラメーターの推定

次の式を使用して、番目のフィーチャーのパラメーター(, )を推定することができます。 平均を推定するには、次を使用し、

式2

分散に対しては、次を使用します。

式3

あなたがすべきことは、estimateGaussian.mのコードを完成させることです。 この関数は、データ行列Xを入力として受け取り、個のフィーチャーのすべての平均を保持する次元ベクトルmuと、すべてのフィーチャーの分散を保持する別の次元ベクトルsigma2を出力として返す必要があります。 すべてのフィーチャーとすべてのトレーニング・サンプルに対するforループを使用して、実装することができます。 ベクトル化された実装はより効率的かもしれませんが、そうしなくてもかまいません。 Octave/MATLABのvar関数のデフォルトでは、を計算するときにではなく、を使用することに注意してください。

estimateGaussian.mのコードを完成させると、ex8.mの次のパートでは、フィットしたガウス分布の輪郭が可視化され、図2のようなプロットが得られるはずです。 プロットから、ほとんどのサンプルは確率の最も高い領域にあり、異常なサンプルは確率の低い領域にあることが分かります。

ここで解答を提出する必要があります。

図2:データセットにフィットする分布のガウス分布の等高線

     図2:データセットにフィットする分布のガウス分布の等高線

1.3. 閾値を選択する

ガウス分布のパラメーターを推定したので、どの分布のサンプルが非常に高い確率であり、どの分布が非常に低い確率であるかを調べることができます。 低確率のサンプルは、データセットの中で異常である可能性が高いです。 どのサンプルが異常であるかを判断する1つの方法は、クロス・バリデーション・セットをもとに閾値を選択することです。 演習のこのパートでは、クロス・バリデーション・セットにスコアを使用して、閾値を選択するアルゴリズムを実装します。

ここで、selectThreshold.mのコードを完成させる必要があります。 このために、クロス・バリデーション・セットを使用します。 ここで、ラベルは異常なサンプルに対応し、は通常のサンプルに対応します。 各クロス・バリデーション・サンプルに対して、を計算します。 これらの確率のすべてのベクトルは、ベクトルpvalselectThreshold.mに渡されます。 対応するラベルは、ベクトルyvalで同じ関数に渡されます。

関数selectThreshold.mは2つの値を返す必要があります。 1つ目は選択された閾値です。 サンプルが低い確率である場合、それは異常とみなされます。 この関数はスコアも返す必要があります。 スコアは、特定の閾値を与えられたグラウンド・トゥルース(Ground Truth)の異常を見つけることがどれだけうまくいっているかを示します。 のさまざまな値に対して、現在の閾値が正しく分類されているかどうかのサンプル数を計算することで、結果のスコアを計算します。

スコアは、精度()と再現率()を用いて計算されます。

式4

次のように精度と再現率を計算します。

式5

  • は真陽性の数です。グラウンド・トゥルース・ラベルは異常であり、アルゴリズムでは正しく異常と分類されています。
  • は偽陽性の数です:グラウンド・トゥルース・ラベルは異常ではなく、アルゴリズムでは誤って異常として分類されています。
  • は偽陰性の数です:グラウンド・トゥルース・ラベルは異常ですが、アルゴリズムでは異常ではないと誤って分類しています。

提供したselectThreshold.mのコードには、すでにの多くの異なる値を試し、スコアに基づいて最適なを選択するループがあります。 ここで、selectThreshold.mのコードを完成する必要があります。 forループを使用して、すべてのクロス・バリデーション・サンプル(の値を計算する)を使用して、スコアの計算を実装できます。 約8.99e-05epsilonの値が表示されます。


実装上の注意:

を計算するために、すべてのサンプルをループするのではなく、ベクトル化された実装を使用できます。 これは、Octave/MATLABのベクトルと単一数値間の同等性テストによって実装できます。 次元バイナリー(二値)・ベクトルに複数のバイナリー値がある場合、sum(v == 0)を使用すると、このベクトルに0がいくつあるか分かります。 また、そのようなバイナリー・ベクトルに論理演算子を適用することもできます。 たとえば、cvPredictionsをクロス・バリデーション・セットと同じサイズのバイナリー・ベクトルで、番目の要素は、アルゴリズムがを異常とみなす場合は1であり、そうでない場合は0であるとします。 このようなとき、以下を使用して偽陽性の数を計算することができます。

fp = sum((cvPredictions == 1) & (yval == 0))


図3:分類された異常

     図3:分類された異常

selectThreshold.mのコードを完成すると、ex8.mの次のステップで異常検出コードが実行され、プロット内の異常を丸で囲みます(図3)。

ここで解答を提出する必要があります。

1.4. 高次元データセット

スクリプトex8.mの最後のパートは、より現実的ではるかに難しいデータセットで実装した異常検出アルゴリズムを実行します。 このデータセットでは、各サンプルが11のフィーチャーで記述されています(サーバーの多くのプロパティーをキャプチャーされています)。

このスクリプトでは、実装したコードを使用してガウス・パラメーター()を推定し、ガウス・パラメーターを推定したトレーニング・データXとクロス・バリデーション・セットXvalの両方の確率を評価します。 最後に、selectThresholdを使用して最も高い閾値を探します。 約1.38e-18epsilon値と117個の異常値が見つかるはずです。

2. レコメンダー・システム

この演習では、協調フィルタリングの学習アルゴリズムを実装し、映画の評価のデータセットに適用します。 このデータセットは、1〜5の尺度による評価から構成されます(※2)。 データセットは、人のユーザーと本の映画です。 演習のこのパートでは、スクリプトex8_cofi.mを使用して作業します。

この演習の次のパートでは、協調フィルタリングの目的関数と勾配を計算する関数cofiCostFunc.mを実装します。 コスト関数と勾配を実装した後、fmincg.mを使用して協調フィルタリングのパラメーターを学習します。

※2:GroupLens ResearchからのMovieLens 100k Datasetです。

2.1. 映画評価のデータセット

スクリプトex8_cofi.mの最初のパートは、データセットex8_movies.matをロードし、Octave/MATLAB環境に変数YRを提供します。

行列Ynum movies × num_usersの行列)は、1〜5の映画の評価を格納します。 行列Rは、ユーザーが映画に評価を与えた場合にはであり、そうでない場合にはであるバイナリーの指標行列です。 協調フィルタリングの目的は、ユーザーがまだ評価していない映画、すなわちの映画の評価を予測することです。 これにより、予測される評価が最も高い映画をユーザーに推薦することができます。

行列Yを理解するために、スクリプトex8_cofi.mは、最初の映画(Toy Story)の評価の平均を計算し、それを画面に出力します。

この演習のこのパートでは、行列XThetaを使って作業することになります。

式6

X行目は番目の映画のフィーチャー・ベクトルに対応し、Theta番目の行は(番目のユーザーの)1つのパラメーター・ベクトルに対応します。 はともに次元ベクトルです。 この演習では、を使用するため、となります。 それに対応して、Xの行列であり、Thetaの行列です。

2.2. 協調フィルタリングの学習アルゴリズム

ここから、協調フィルタリングの学習アルゴリズムの実装を開始します。 コスト関数(正則化なし)を実装することから始めます。

映画推薦の設定における協調フィルタリングのアルゴリズムは、次元パラメーター・ベクトルおよびの集合を考えます。 ここで、モデルはユーザーによる映画の評価をとして予測します。 いくつかのユーザーによって生成されたいくつかの映画に対する評価の集合からなるデータセットが与えられた場合に、最も適合する(二乗誤差を最小限に抑える)パラメーター・ベクトルを学習することが目的です。

cofiCostFunc.mのコードを完成させて、協調フィルタリングのコスト関数と勾配を計算します。 関数のパラメーター(つまり、学習しようとしている値)はXThetaです。 fmincgのような既製のミニマイザーを使用するために、パラメーターを単一のベクトルparamsにアンロールするようにコスト関数が設定されています。 以前、ニューラル・ネットワークのプログラミング演習で同じベクトル・アンローリングの方法を使用していました。

2.2.1. 協調フィルタリングのコスト関数

協調フィルタリングのコスト関数(正則化なし)は、以下で与えられます。

式7

変数Jでこのコストを返すように、cofiCostFunc.mを変更する必要があります。 の場合にのみ、ユーザーと映画のコストを累積する必要があります。 関数を完了すると、スクリプトex8_cofi.mによってコスト関数が実行されます。 22.22が出力されるはずです。

ここで解答を提出する必要があります。


実装上の注意:

後で最適化パッケージfmincgによって何度も呼び出されるため、ベクトル化された実装を使用してを計算することを強くお勧めします。 いつものように、(正しい答えが得られることを確認するため)最初にベクトル化されていない実装を書いて、ベクトル化された実装に変更する方が簡単かもしれません(ベクトル化のステップがアルゴリズムの出力を変更しないことを確認してください)。 ベクトル化された実装を考え出すには、次のヒントを参考にしてください。 行列Rを使用して、選択したエントリーを0に設定できます。 たとえば、R .* MMRの間で要素ごとの乗算を行います。 Rは0または1のいずれかの値を持つ要素しか持たないので、Rの対応する値が0の場合にのみMの要素を0に設定するという効果があります。 したがって、sum(sum(R.*M))は、Rの対応する要素が1に等しいMのすべての要素の合計です。


2.2.2. 協調フィルタリングの勾配

ここで、(正規化なしで)勾配を実装する必要があります。 具体的には、cofiCostFunc.mのコードを完成させ、X_gradTheta_gradの変数を返します。 X_gradXと同じ大きさの行列でなければならず、同様にTheta_gradThetaと同じ大きさの行列でなければなりません。 コスト関数の勾配は、以下で与えられます。

式8

この関数は、両方の変数の集合を1つのベクトルにアンロールすることによって、それらの勾配を返します。 勾配を計算するコードを完成させた後、スクリプトex8_cofi.mは勾配チェック(checkCostFunction)を実行し、勾配の実装を数値で確認します(※3)。 実装が正しい場合は、解析的勾配と数値的勾配が完全に一致することが分かります。

ここで解答を提出する必要があります。

※3:これは、ニューラル・ネットワークの演習で使用した数値チェックに似ています。


実装上の注意:

ベクトル化された実装を使用しなくても、この課題の完全な評価を得ることができますが、コードははるかに遅く(数時間かけて)実行されるため、実装をベクトル化することをお勧めします。

まず、(を計算する)映画のforループと(を計算する)ユーザーのforループを使って、勾配を実装できます。 最初に勾配を実装するときは、ベクトル化されていないバージョンから開始することができます。これは、集計の各要素を計算する別の内部forループを実装することで実現します。 このように勾配の計算を完了したら、実装をベクトル化(forループの内側をベクトル化)して、forループを二つだけ残すようにする必要があります(一つは映画ごとにを計算するためのループで、もう一つはユーザーごとにを計算するためのループです)。



実装のヒント:

ベクトル化を実行するには、次の情報が役立ちます。 に関するすべての導関数(すなわち、フィーチャー・ベクトルに関する導関数)を同時に計算する方法を考え出すべきです。 番目の映画のフィーチャー・ベクトルの導関数を次のように定義します。

式9

上記の式をベクトル化するには、ThetaYにインデックスを付けて、関心のある要素(つまりの要素)のみを選択します。 直感的に、番目の映画のフィーチャーを検討するときは、映画に評価を与えたユーザーの関心だけが必要です。 これにより、他のすべてのユーザーをThetaYから取り除くことができます。

具体的には、idx = find(R(i、:)== 1)を映画を評価したすべてのユーザーのリストに設定できます。 これにより、Theatatemp = Theta(idx、:)Ytemp = Y(i、idx)を作成して、ThetaYにインデックスを付けて、番目の映画を評価したユーザーの集合のみを与えることができます。 これにより、以下のように導関数を実装することができます:

式10

(注:上記のベクトル化された計算は、代わりに行ベクトルを返します。)

導関数の計算をに関してベクトル化した後、同様の方法を使ってに関してもベクトル化する必要があります。


2.2.3. 正則化されたコスト関数

正則化を伴う協調フィルタリングのコスト関数は、以下の通りです。

式11

ここで、コスト関数の元の計算に正規化を追加する必要があります。 完成後に、スクリプトex8_cofi.mは正則化されたコスト関数を実行すると、約31.34のコストとなるはずです。

ここで解答を提出する必要があります。

2.2.4. 正則化された勾配

正則化されたコスト関数を実装したので、勾配の正則化を実装する必要があります。 正則化項からの寄与を加えることによって正則化された勾配を戻すように、cofiCostFunc.mの実装に追加する必要があります。 正則化されたコスト関数の勾配は、以下で与えられることに注意してください。

式12

これは先ほど説明した変数X_grad(i,:)を加え、前述のTheta_grad(j,:)変数にを加えるだけでよいことを意味します。 勾配を計算するためのコードを完成すると、スクリプトex8_cofi.mは勾配の実装を数値で確認するために別の勾配チェック(checkCostFunction)を実行します。

ここで解答を提出する必要があります。

2.3. 映画のお勧めを学ぶ

協調フィルタリングのコスト関数と勾配の実装が完了したら、アルゴリズムのトレーニングを開始して映画のおすすめを自分で作成できます。 ex8_cofi.mスクリプトの次のパートでは、独自の映画設定を入力することができます。 その結果、アルゴリズムが実行された後で、自分の映画のお勧めを得ることができます。 私たちは自分の好みに応じていくつかの値を記入しましたが、あなたの好みに応じてこれを変更する必要があります。 データセット内のすべての映画のリストとその番号は、ファイルmovie_idx.txtにリストされています。

2.3.1. お勧め

Top recommendations for you:
Predicting rating 9.0 for movie Titanic (1997)
Predicting rating 8.9 for movie Star Wars (1977)
Predicting rating 8.8 for movie Shawshank Redemption, The (1994)
Predicting rating 8.5 for movie As Good As It Gets (1997)
Predicting rating 8.5 for movie Good Will Hunting (1997)
Predicting rating 8.5 for movie Usual Suspects, The (1995)
Predicting rating 8.5 for movie Schindler's List (1993)
Predicting rating 8.4 for movie Raiders of the Lost Ark (1981)
Predicting rating 8.4 for movie Empire Strikes Back, The (1980)
Predicting rating 8.4 for movie Braveheart (1995)
Original ratings provided:
Rated 4 for Toy Story (1995)
Rated 3 for Twelve Monkeys (1995)
Rated 5 for Usual Suspects, The (1995)
Rated 4 for Outbreak (1995)
Rated 5 for Shawshank Redemption, The (1994)
Rated 3 for While You Were Sleeping (1995)
Rated 5 for Forrest Gump (1994)
Rated 2 for Silence of the Lambs, The (1991)
Rated 4 for Alien (1979)
Rated 5 for Die Hard 2 (1990)
Rated 5 for Sphere (1998)

     図4:映画のお勧め

評価がデータセットに追加されると、スクリプトは協調フィルタリングのモデルをトレーニングします。 これにより、パラメーターXThetaを学習します。 ユーザーの映画に対する評価を予測するには、を計算する必要があります。 スクリプトの次のパートでは、すべての映画とユーザーの評価が計算され、スクリプトで先に入力された評価に従って、推薦する映画が表示されます(図4)。 ランダムな初期化が異なるため、異なる予測セットが得られる可能性があることに注意してください。

提出と採点

この課題が完了したら、送信機能を使用して解答を我々のサーバーに送信してください。 以下は、この演習の各パートの得点の内訳です。

パート 提出するファイル 点数 
ガウス分布のパラメーターの推定 estimateGaussian.m 15 点
閾値の選択 selectThreshold.m 15 点
協調フィルタリングのコスト cofiCostFunc.m 20 点
協調フィルタリングの勾配 cofiCostFunc.m 30 点
正則化されたコスト cofiCostFunc.m 10 点
正則化された勾配 cofiCostFunc.m 10 点
合計点 100 点

解答を複数回提出することは許可されており、最高のスコアのみを考慮に入れます。