Isolation Forest と異常検知(ネットアクセスログを用いて)

【はじめに】

日頃データサイエンスの研修においては、教師あり機械学習から入門し、それをビジネスの花形として紹介することが多いです。ただし世の中の問題に向き合うと実に教師なし機械学習の存在が大きいのも知っていただきたいです。その1つが異常検知です。

異常検知は異常値や外れ値を検出する手法を指しています。金融の不正取引識別、故障検知・故障予測、検品、設備管理、医療、セキュリティなど多岐にわたる分野で貢献しています。この記事では、異常検知の使いやすいかつ有力な教師なし学習手法の1つであるIsolation Forest手法を説明し、それを用いて不正侵入パケットに対する予測モデルの構築の例を示していきます。

 

演習に使用するデータ

インターネットの普及により,悪意のあるソフトウェア(マルウエア; Malicious Software)による攻撃が問題として現れています。コンピュータが感染すると、使えなくなったり、機密情報が流出したりします。全種類の攻撃から守ことは難しいですが、現在、攻撃に対抗するシステムが色々開発されております。大きく分けて、攻撃検知型 ( IDS=Intrusion Detection System)と検知後に脅威を排除する攻撃防御型 ( IPS=Intrusion Prevention System)の2タイプがあります。アクセスデータに対する分析手法も2タイプあります。攻撃パターンを把握し合致した通信データを得た場合に攻撃と判断する「シグネチャ型」、もう1つは正常通信のパターンを定義し、そこから性質が離れている通信データを攻撃と判断する「アノマリ型」があります。

IDS や IPS の研究で扱われる代表的なデータセットとしてKDD CUP 99 Data Set があります。UCI Machine Learning Repository から入手できます:http://kdd.ics.uci.edu/databases/kddcup99/kddcup99.html

約 500 万件(4,898,930) のフルセットから 10%を抽出した約 50 万件(494,021)の 10%データセットを今回、異常検知タスクの題材とします。自分で精度を評価したかったので、学習用データセットのみ使用します。

学習用データの、"label" 列に正常通信(normal)と22 種類の攻撃が含まれています。normalから不正を識別するためには、もちろん様々な機械学習の手法を使用できます(SVM、教師ありアンサンブル、ディープラーニングK-Meansなどの距離ベース)が、今回はIsolation Forest を使った分析例を紹介します。

 

【Isolation Forestについて】

分析手法の仕組み

Isolation forestは異常検知に特化して設計された教師なし学習の手法です。異常データを「孤立させる(isolate)」ことにより認識します。

馴染みの深いRandom Forestと同様に、Isolation Forest もアンサンブル学習器です。データ(行)と特徴量(列)をサンプリングして個別の木々(Isolation Trees) を作り、組み合わせることでロバストさを図ります。

簡単にIsolation Forest のデータ処理の流れを説明します。特徴量の中から1変数を選び出し、初期的にその変数の(最小値, 最大値)区間で「分割点」をランダムに選びます。最終的には、上記の分割点が節、データ点が葉である木構造になります。この分割操作を、満足の基準になるまで再帰的に分割を繰り返します。

各データ点に対して、葉にたどり着くまでの分割数はルートノードから葉までの距離に対応します。この距離(path length) path length という概念が重要です。なぜなら、 Isolation Forest アルゴリズム「異常値は量が少ない、かつ 正常データと性質がかけ離れている」という仮定に基づいています。異常データは、早い(木の浅い)段階で分割される確率が高く、結果としてpath length が小さくなります。この傾向を利用して異常データを正常データから見分けます(*)。

個別の木々を組み合わせる時、各データ点に対して、path lengthを森全体でとった平均を最終判断として採用します。この平均深さがまさに異常スコアに対応します。

(*)を直感的に理解するための例として、会社員の1ヶ月の給料のは概ね30万を中心に分布していますが、たまたま給料1000万のデータがあると、そのデータの区間は(30くらい,  1000)になります。この区間で分割する値をランダムに決める(一様分布とする)と、1000万のデータ点がisolateされる確率は圧倒的に高いですよね。

Isolation Forestの利点

異常検知の手法は他にも色々あります。その多くは「正常データ」のプロファイルを作り、それと比較して「遠い」ものを異常と判定します。この距離の概念は特徴量空間で形成されます。Isolation Forestは違います。「正常」の定義をしない、データ間の距離を計算に使わない、が差別化ポイントです。そのようなIsolation Forest のメリットとしては以下が挙げられます:

  • 高速に異常値を検出可能(理由:他のdistance-based手法と違って正常データのプロファイル作成不要のため、計算コストが比較的少ない)
  • メモリ占有率が比較的少ない(↑と似た理由)
  • 木が発達する深さを表すパラメータ max_depth を小さく設定できる(理由:異常データは短いパスのうちに既に識別できるから)
  • 小さなデータセットでも不利益が少ない
  • 不均衡データにも使いやすい (**)

(**)の補助説明:一般的に、正常データと異常データの間の不均衡問題が難しいです。不均衡をなくすために、データに重み付けをする方法とデータ数を調整する方法があります。後者では少ない方のデータを増やすオーバーサンプリングと多い方を減らすアンダーサンプリングがあります。一方で、Isolation Forest は不均衡問題にさほど敏感ではなくなるような設計なので、データ前処理の工数も削減できます。

 

【不正パケット検出のデモ】

演習を見せながら残りの解説をします。(本質ではないコードの部分を省略)

データの読み込み・概観

f:id:gri-blog:20200705164912p:plain

図1
 
正常、不正常データの割合を観察

今回はサービスの種類を http (よくあるもの)に限定した分析としました。

文字列データのlabel encoding を行いました。

f:id:gri-blog:20200705165050p:plain

図2
データを学習用と検証用に分割

Isolation Forestは教師あり学習ではないのですが、訓練データと評価データがあります。訓練データにもラベルがついている必要はありません。訓練データを用いて、Isolation Forestを学習させます。評価データでは、データを森に入れて、各データ点に対して異常スコアを取得します。

  • 入力:データ
  • 出力:各データ点の異常スコア

f:id:gri-blog:20200705165305p:plain

図3

 

モデルの定義・パラメータ設定・学習

Isolation Forest で重要となるパラメータは以下です。

  • n_estimators :アンサンブル内の木の数。デフォルトは100です。ここで500。
  • max samples:: それぞれの木を作るためにランダムサンプリングされるデータ数。 'auto' にしている場合 max_samples=min(256, n_samples)
  • contamination: 最も敏感に反応するパラメータの1つであり、その初期設定に要注意です。データせっとの中の期待される異常値の割合です。これはスコアの算出や判定閾値を出すときにも重要です。ここでは1割とする。

f:id:gri-blog:20200705165428p:plain

図4
異常スコアの算出・可視化

検証用と呼ばれている部分のデータに学習済みモデルを当てて、異常スコアを算出します。棒グラフで視覚化すると、異常判定の閾値が見えてきます。

f:id:gri-blog:20200705165659p:plain

図5

精度算出

図5において、スコアに対する閾値を0.19と決めました。

検証用データには正解がついており、それを用いて評価したAUCスコアは98.2でした。

f:id:gri-blog:20200705165908p:plain

図6

ちなみに、同じ課題を、アップまたはダウンサンプリングを行わずでKMeansで対応したところ、精度は85%程度でした。これだけの少ない工数でIsolation Forest手法を用いて、リアル世界の問題に対処できたのは素晴らしいと思います。

 

課題

今回は一発だけIsolation Forest の使い方を試しましたが、現実には精度を保証するために注意が必要です。例えば ....

  • 個別の攻撃を用いた場合、攻撃の種類、正常通信と攻撃通信の割合など学習データのバリエーションを増やした上での精度も評価すべき
  • 学習データにはない種類の攻撃が検証データにあったら精度はどうなるのか?

今度は、教師あり手法(random forest, SVM)やきちんと不均衡問題を解消するための前処理を施した上での kMeansの結果ときちんと比較したいと思います。

 

担当: ヤン・ジャクリン(分析官・講師)

 

参考

Scikit-learnのドキュメント

https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html

https://scikit-learn.org/stable/auto_examples/ensemble/plot_isolation_forest.html

論文

Liu, F. T., Ting, K. M., & Zhou, Z. H. (2008, December). Isolation forest. In 2008 Eighth IEEE International Conference on Data Mining (pp. 413-422). IEEE.

 

花束の画像から花の本数を特定する手法

花束の画像から機械学習を用いて花の名前と本数を特定する手法について考えてみます。 機械学習に慣れていない方が実際にこのようなタスクを行う場合には、多くの画像認識の手法の中からどの手法を選ぶとよいのか悩んでいるかもしれません。 また、API等の利用を考えているかもしれません。 今回は画像認識の手法ごとの違いやAPIを利用する場合、しない場合の違いを考え、どのように手法を選ぶべきかというのをまとめています。

画像認識手法の分類

まずは、画像認識全体の手法について見ていきます。 近年のDeep Learningの盛り上がりによって多くの画像認識手法が生み出されていますが、それらは大きく以下の図のように分類することができます。 f:id:gri-blog:20200630154552p:plain Image Classificationとはクラス分類を行う手法です。 画像の中に何が写っているのかを導き出す手法です。 画像から"CAT"であると判断するようなモデルがこれになります。 もし画像のどこに猫が写っているのかを知りたいのであれば、Image Localizationを行います。 そして、"犬と猫"のように複数の物体の位置を知りたい場合にはObject Detectionを行います。 Image LocalizationやObject Detectionではどこに"Dog"がいるのかを矩形によって表現しましたが、ピクセル単位で知りたい場合にはImage Segmentationを行う必要があります。 Image Segmentationを行うと複数の物体の形まで認識することができます。

複数の花が写っている画像から花の名前と本数を知りたいのであれば、Object Detectionを行う必要があります。 複数の花が写っているためImage Localizationでは不十分です。 また本数が分かれば、位置を正確に知る必要はないため、Image Segmentationを行う必要はありません。

Object Detectionの実現手法

Object Detectionを行うための手法は3つあります。 これらの手法は実現までの早さ、作業量、実現できるタスクの細かさ(=自由度)に違いが現れます。

1つ目はAPIを利用する手法です。 仮に画像から花の位置と名前を正確に特定できるAPIが存在するのであれば、それを利用することを検討すべきです。 既存のAPIを利用すれば、早く、少ない作業量で目的を達成することができます。 ただし、その分自由度は低くなり、望んでいるラベルが存在しないことも考えられます。 f:id:gri-blog:20200701101439p:plain

2つ目はタスクを分割し、複数のAPIを利用する手法です。 今回のタスクの場合には、花の位置を特定するAPIと花の名前を特定するAPIによって実現することができます。 前者は花の名前が分からずとも、位置が認識できれば、花1本ずつの画像を切り出してくることができます。 後者はImage Classificationを行い、花の名前を特定します。 この手法の場合にも早く目的を達成することができます。 作業量は1つ目の手法よりは増えますが、その分自由度も高くなる可能性があります。 ただし、API次第であることには変わりないため、望んでいるラベルが存在しないことも十分に考えられます。 f:id:gri-blog:20200701101530p:plain

3つ目は自作のモデルを構築する手法です。 この場合には自由度が最も高くなり、望んでいるラベルを用意することができます。 ただし、大量の訓練データも用意する必要があります。 作業量が大きくなり、モデルを構築するまでに多くの時間がかかることも考えられます。 f:id:gri-blog:20200701101648p:plain

APIの調査

ここからはAPIが実際に存在しているのか、今回のタスクに利用できるのかを調べていきます。

まず、画像から花の位置と名前を特定するAPIですが、2020年7月1日時点では見つけることができませんでした。 そのため、1つ目の手法を選択することはできないと判断します。

次に、位置を特定するAPIと名前を特定するAPIについて調べてみました。 その結果、それぞれGoogle Cloud Vision APIとPlant.idというAPIが見つかりました。 それぞれを試してみます。

Google Cloud Vision APIにバラの画像を入力した結果は以下のようになります。 f:id:gri-blog:20200701104901p:plain 2本とも"Flower"であると正しく認識されています。

花束の画像でも試してみます。 f:id:gri-blog:20200701105339p:plain こちらは3本のみしか見つけることができませんでした。 今回のタスクでは花束の画像を扱うため、APIの利用を控えた方が良さそうです。

Plant.idについても見ていきます。コスモスの画像を入力します。 f:id:gri-blog:20200701111905j:plain コスモスであることが正しく認識されています。

次にシャクナゲを入力してみます。 f:id:gri-blog:20200701112028j:plain シャクナゲの場合には正しく認識することができませんでした。 実際に名前と本数を特定したい画像にシャクナゲの画像が入っている場合には注意が必要であることが分かります。

調査の結果、花束の画像に対してはAPIの利用が難しいことが分かりました。 そのため今回のタスクを行う場合には、自作のモデルを構築する必要があります。

終わりに

花束の画像から花の名前と本数を特定するための手法について考えてみました。 早さや作業量、自由度のどれを重要視するのかによってAPIを利用するかどうかを決めます。 ただし、APIを利用する場合には望んでいるように画像を認識できるかどうかを十分に調査する必要があります。

私が1ヶ月でBIツール Tableauをマスターしたステップとおすすめコンテンツ

私が入社2ヶ月目に考えてやっていたことと、知っておきたかったことを整理して、これからTableauプロジェクトに入る人向けにどう習得したらいいかを書いてみました。Webや書籍として点在しているコンテンツの場所や、見る順番などを書いております。2020年6月時点版です。

Tableauって?

わかっている人は、ここは飛ばしてください。

Tableauって何かと言えば、ダッシュボードが作れるツールだと思います。 ではダッシュボードとは何か?「デジタルダッシュボード」についてはWikiにこうあります。

続きを読む

クラウドネイティブなELTツールMatillionで多テーブルの結合処理

クラウドを前提にしたELTツールのMatillionを使うと、意外な驚きに出くわします

 

多くのETLツールは、BigQueryをデータソースとして前処理を行うと、一度BQよりデータをツール側に取り出して処理を行います。これは、BQの力を最大限に活かせず、処理は、できるだけBQ側のリソースで行えるツールが欲しくなります。Matillionは、そんなことを手軽にできるツールです。

 

そんなツールで、多数のテーブルの結合処理が一つのコンポーネントだけで、なかなか面白い感じで記述できるので紹介します。

 

f:id:gri-blog:20200604204736j:plain

オレンジの3つがBigQueryの3つのテーブルで、赤枠で囲まれたJoinコンポーネント1つで、この3つのテーブルの結合処理を記述できます。よくあるETLツールは、一つのJoinコンポーネントで2つのテーブルを結合する記述です。たくさんのテーブルの結合をまとめて記述できれば、データフローを直感的に記述できます。今までのツールだと、プロのマエショリストが多段の結合処理をする場合、どの順番で結合するかを考えるのが腕の見せ所でしたが、Matillionだと、これらの処理はMatillionが適当にSQL文にしてBQに投げてくれる感じです

 

より詳しくは公式のYouTube動画を

www.youtube.com

 

古幡征史

PDFの中に埋め込まれているテーブルをデータフレームで取り出す、Rで

PDFの中に埋め込まれているテーブルからデータを抜き出したいという状況って頻繁にあると思います。まぁもしもそんな状況は一度もなかったとしても、それが簡単にできるということでせっかくなのでちょっと試してみようと思います。Rを使います。

 

きっかけは、Exploratory西田さんのこのツイートです。tabulizerというライブラリを使うようです。

 

続きを読む

仕事ってなんだ、10の心構え

新社会人にとっては、社会人始まったばかりなのに新型コロナウィルスでいきなり在宅勤務という状況だと思います。そんな状況に、私個人の仕事に関する価値観とそのベースになっている言葉を本棚から引っ張り出してきて、偉そうにまとめてみました。

もう少しマーケティングや分析よりの話題まで含めようと思っていたが、長くなってしまったので、別の回に。

 

f:id:gri-blog:20200422162517j:plain

 

続きを読む

Prophet時系列予測モデルをExploratoryで数クリックで実行

時系列予測モデルProphetExploratoryで使いこなして、50年ほど時計の針を進めましょう。

Prophet時系列予測モデルの革新

時系列予測モデルを扱うには、定期的な時間間隔(テンポ)の入力データが扱いやすいのが通例です。月次データであれば、毎月の数値データのデータセットです。ただし、日次データになると急に予測モデルでの扱いが難しくなります。株式市場などのビジネスデータは土・日・祝日の休日や、数年に一度のレベルで起こるサーキットブレーカーの発動などのイレギュラーなイベントがあり、テンポがずれた時系列データとなり、予測精度を保つのが急に難しくなります。ウェブ企業は365日営業しているので、日レベルの時系列予測の需要はとても高いです。

そんな中、2018年のはじめごろFacebook社のProphet時系列予測モデルが素晴らしいと聞き、試してみたところ、驚きました。よく使われる日次データの予測が非常に頼もしく、営業数値などを扱っている部署では月内着地予想などを作りやすいと思いました。また、チェンジ・ポイントでトレンドの変化点などもつかみ取りやすいです。

facebook.github.io

 

Prophetの今までの課題とExploratoryでの扱いやすさ

ProhetはRやPythonで動きますが、インストールに手間取ったり(Stanを入れるときやlibrary間の依存関係の解消)、入力データのカラム名命名規則(ds, yなど役割ごとに決められたカラム名にしなければならない)があったり、そもそもRやPythonでプログラミングに抵抗がある人がいます。

TableauにてPythonやRと連携できるようになったので、2018年の秋ごろ、この連携ならノンプログラミングを希望するユーザにとって良いと思い、実際に試してみました。連携をするために、ものすごく設定が多く、コマンドや前処理をかなり書かなければいけないので、人を選ぶやり方です。なお、Tableauで実装されているのは指数平滑化法(Exponential Smoothing)で1940年~1957年ごろに作られた手法です。この手法が今でも汎用的に真っ先に試されるものですが、月次データで3年以上の履歴データが最低限必要で、ビジネスでは適用範囲が限られます。

2019年にExploratoryで標準メニューに入ったのですが、ようやく試してみたら、数クリックで予測が終わり、とても使いやすく驚いています。Prophetの命名規則に縛られることもなく快適です。

exploratory.io

使い方の例

ExploratoryでのProphetの使い方は、西田さんのYoutubeが分かりやすいです。時系列予測の基礎知識に関する説明も含まれています

www.youtube.com

 

この記事では、 Prophet公式にあるアメフトのPeyton Manning選手Wikiへのアクセスログを対数化したものを例に、Prophetの使い方を見てみます。

f:id:gri-blog:20200417131900j:plain

このデータは2007/12/10~2016/1/20までの2,906日分のアクセスログ(対数化済み)です。なんとなく周期的な変動と、たまに突発的なスパイクがあるのが見て取れます。

f:id:gri-blog:20200417132407j:plain

その際、Exploratoryに読み込ませたのは上記の2列のデータです。

実行手順

「アナリティクス」タブから「時系列予測(Prophet)」を選びます。

f:id:gri-blog:20200417133110j:plain

 

変数やパラメタを設定する画面が出るので

f:id:gri-blog:20200417133327j:plain

  • 日付/時間の列にdsを設定(今回は時間粒度が年月日なので"DAY"を選択)
  • 数値データの列にyを設定(データはSUMのままにしておく。変更しても一つのデータなので特に変化はない)
  • 詳細情報を設定する場合は歯車マークで設定

分析結果

実行ボタンを押すと下記6種類のプロットとデータタブが自動で出力されます。

予測結果 

「予測結果」タブで過去実績とProphetによる予測値のグラフが出力されます

f:id:gri-blog:20200417134632j:plain

  • 青線: 実績データy
  • オレンジ: 予測データ

過去実績期間があるのは、バックテストで予測数値を過去方向に伸ばしているものです。これにより過去データに足して、それっぽい予測値が出ているのが見て取れます。また、予測期間に対しても、職人が手で作りそうな形状の予測値ができています。

 

トレンド 

 「トレンド」タブにて、Prophetの予測によるトレンド成分が出力されます

f:id:gri-blog:20200417135428j:plain

緑の曲線がトレンド線で、緑の縦棒がトレンド変化点の変化の大きさです。2012年まで上昇トレンドにありましたが、それ以降は下降気味です。これはManning選手が2012年年3月7日に解雇されるまでインディアナポリス・コルツに在籍し、同年3月20日デンバーブロンコスと契約するタイミングで、トレンドが変化していることを捉えています。

年周期 

「年周期」タブにて、1年の中での周期性を確認します

f:id:gri-blog:20200417143856j:plain

1月下旬にピークがあるのは2月上旬に開催されるアメフトのスーパーボールの時期に合致します。それ以降はオフシーズンですので、季節性は低く、秋ごろ以降季節性が高くなっていく様子を捉えております

 

週周期

「週周期」タブにて週内の周期性を見ます

f:id:gri-blog:20200417144503j:plain

月曜日がピークで、土曜日に向け周期性の成分が下降しています。これは直感と合わず、季節性の分解に失敗している可能性があります。恐らく、何かのイベント効果などのデータが必要かもしれません。今は飛ばしてしまいます

 

効果

 「効果」タブにてトレンドや季節性の影響を比較します

f:id:gri-blog:20200417150842j:plainバックテストの結果として

  • Trend成分で予測の大半は成り立っており
  • Yearly Seasonality(月効果)成分でギザギザの形状の大半を説明し、
  • Weekly Seasonality(曜日効果)成分で微調整をしている

変数重要度

「変数重要度」タブで変数間(トレンドを除く)の重要度を把握する

f:id:gri-blog:20200417151650j:plain

Yearlyが0.6弱で、Weeklyが0.2弱。残りはイレギュラーな成分なのかもしれないが、詳細は要調査

データ

 「データ」タブには元データとProphetによって出力された値、信頼区間の範囲、各種成分が表示されます

f:id:gri-blog:20200417152949j:plain

まとめとそれ以外のこと

上記ではProphetが簡単に使えて、時系列予測の情報を得ることができることを示しました。ここから、さらに知りたいことの例として、こんなことが挙げられます。

  • 予測精度の表示
  • 年月日より粗い時間粒度(月や週)での実行結果
  • ダミー変数(外部予測変数)の利用(スーパーボールの日フラグ、オフシーズン・フラグ)
  • 祝日効果の利用
  • チェンジポイントの活用
  • 欠損値の効果
  • 多種データの処理(一つのデータセットに多くの種類の予測対象があり、それらをループして予測。例えば、店舗ごとの予測値を出力し、それを全体で集約した全体予測値を算出)

 

古幡征史