ログデータのクラスタリングについてココンの情報をいつでも、どこでも。2018.05.24ログデータのクラスタリングについてツイートAI戦略室の坂本です。前回に引き続き、時系列データに対する機械学習について書こうと思います。今回のエントリは、実際のプログラムコードを元にした技術的な解説になります。時系列データの取り扱いについての基本的な考え方は、前回のエントリを参考にしてください。結果の確認まとめログデータのクラスタリング機械学習による分析を必要とする時系列データとしては、Webやアプリ等のログデータが代表的なものですが、ここではログデータのクラスタリングについて考えてみます。ログデータのクラスタリングとは一口に言えば、多種多様なユーザーの行動ログから、行動傾向毎にユーザーを分析する、というものになります。分析の目的としては異常検出やゲームのチート行為の検出、ユーザーの分類によるマーケ分析などが挙げられますね。異常値について、「これが異常データだ」という異常系が予め定義出来ない場合など、「他のみんなとは違うことをやっている」ユーザーを発見することで、クラッキング行為を行っている(あるいは行おうと調査している)ユーザーを発見したり、仕様の穴を付いて開発側の想定していない使い方をしているユーザーを発見したり出来る訳です。実際には、ここで紹介するような単純な分散表現+クラスタリングだけではなく、もっと多面的にデータ解析を行い、ブラック/ホワイトリストのロジックを組み合わせて全体としての解析モデルを作成するので、ここではあくまでニューラルネットワークによるログデータの可視化について、動作原理を紹介する程度となります。Accessサンプルデータセットを使用します。https://archive.ics.uci.edu/ml/datasets/Amazon+Access+Samplesこのデータは、Amazonのサービスにおけるアクセス権の要求ログを匿名化し、機械学習による分析用にフリーで公開しているものです(もちろん、Amazonの全ログではなく、一部のみを取りだしたものですが)。このデータセットには二つのファイルが含まれていて、「amzn-anon-access-samples-history-2.0.csv」には、ユーザーのアクセス権要求の履歴が保存されていて、「amzn-anon-access-samples-2.0.csv」には、それぞれのユーザーが持っている権限が保存されています。この二つのファイルを組み合わせれば、「実際には持っていない権限を要求してきたユーザー」等を見つけることも出来る訳です。ここでは分析アルゴリズムを紹介するだけなので、権限の比較などは行わずに、アクセス権の要求ログから、アクセス権の追加と削除の要求を時系列的に並べて(面倒なので時間間隔やセッションについても無視します)、何らかの形でデータを分離できないか、試してみることにします。np.unique(df.LOGIN.values)まずはデータの確認から。logdata[u].append(d)ユーザーID毎に「add_access」か「remove_access」かの履歴からなるディクショナリを作成します。0]中身はこんな感じです。使用するニューラルネットワークここでは、上の0と1からなる時系列データから、ニューラルネットワークを使用してユーザー毎の分散表現を作成する事になります。使用するニューラルネットワークは、RNNを使用したEncoder-Decoderモデルとします。今回もフレームワークとしてChainerを使用しました。含めた4単語を扱うEncoder-Decoderモデルです。RNN層としてはノード数2のGRUを、隠れ層としてノード数6の全結合層を使用し、エンコーダー側とデコーダー側とは別のパラメーターを学習させます。Encoder-Decoderモデルの学習Encoder-Decoderモデルの学習はカスタムのUpdaterクラスを作成し、update_core関数内で一つ一つデータをエンコーダーに入力し、デコーダーからの出力をsoftmax_cross_entropyにかけます。エンコーダー側の入力とデコーダー側の出力とが逆順になっているのは、Encoder-Decoderモデルを使用する際の基本的なテクニックで、学習効果の向上効果があります。詳しくは拙著「Chainerで作るコンテンツ自動生成AIプログラミング入門」を参照してください。[]引き継いだステータスを経由してエンコーダー側にも逆伝播がかかるので、このまま学習させることが出来ます。Adamアルゴリズムで、ランダムに選択したデータを100000回学習させています。最後に、全てのデータに対して学習済みのモデルを適用して、結果を取得します。RNN層のノード数を2にしているので、取得できる分散表現の次元数も2となり、ちょうど散布図にして可視化することが出来ます。下のコードはそれぞれのデータをX,Yとして、元のデータの文字列表現をDとして保存します。%d'%(len(XY),len(logdata.keys())))それを、Scikit-learnのAgglomerativeClusteringでクラスタリングし、matplotlibで散布図にして保存します。結果をまとめてresult.csvとして保存します。colormap='cool')plt.savefig('result.png')plt.clf()出来上がった散布図は、以下のようになりました。図の形から、大きく分けて二つの系統が作成されていることが解ります。クラスタリングのアルゴリズムはそれらの系統を正しく分離できています。分離された二つの系統の中身はどうなっているでしょうか。保存されたresult.csvを読み込んで、元データの中身を確認してみます。objectこれだけでは良く解らないので、時系列データ内の数値をUniqしてみます。df[df.c==1].d.values]){'0'}系統1(クラスタ0)にはデータの1と0(「remove_access」と「add_access」)が含まれている一方、系統2(クラスタ1)には0のみ(「add_access」のみ)が含まれていることが解ります。このことから、データに「remove_access」が含まれているかどうかで、大きな系統の差が作成されていることが解ります。まとめ今回は単純な1と0の羅列からなる時系列データを分散表現にしただけですが、それでもデータの傾向によるクラスタリング(「remove_access」が含まれているかどうかのクラスタ)を発見することが出来ました。それだけを判断するのであれば、ニューラルネットワークなど使わずに単純なIf文で事足りるのですが、データ内にどのような傾向が潜在しているのか解らない状態から、教師なし学習により何らかの傾向を発見し可視化することで、データ内に潜在している傾向を発見することが出来るのだ、という一連の流れのサンプルとして捉えて頂ければと思います。そのほかにも、系統の中での座標の差が何を反映しているのかを分析することも出来ますが、今回はここまでとします。今回作成したプログラムは、以下のURLにて公開しています。https://github.com/cocon-ai-group/amznlog-cluster-sample繰り返しになりますが、実際のログ分析ではもっと多面的なデータ解析が必要で、ニューラルネットワークを使えば全てのパターンで異常を検出することが出来る訳ではありません。Learning(類似学習)の手法を使う方が良い場合が多いようですが、それについてはまた別の機会にしたいと思います。2020」参加レポート広報の馬場です。