技術者ブログ

クラウド型WAF「Scutum(スキュータム)」の開発者/エンジニアによるブログです。
金床“Kanatoko”をはじめとする株式会社ビットフォレストの技術チームが、“WAFを支える技術”をテーマに幅広く、不定期に更新中!

2018年11月

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
  • お問い合わせはこちら
Scutum開発者/エンジニアによる技術ブログ WAF Tech Blog

異常検知システム開発の難しさ

はじめに

「異常検知したい」と考えている人は多いと思います。もはや囲碁ですら機械が人間を上回る時代となったので、システムの故障を発見したりクレジットカード詐欺を見つけたりという異常検知システムも、データサイエンスを使えば人間以上に優秀なものを作れるのではないか?と考えるのも自然でしょう。

一方で、実際に異常検知システムの開発に乗り出してみたものの、意外と上手く完成まで辿りつけなかったり、せっかく作ったけれども結局誤検知だらけでお蔵入りしたり、というケースもあるのではないかと思います。この記事では実際に異常検知システムをゼロから開発してみた経験からいくつかの点について書いてみたいと思います。

この記事にはアルゴリズム的な、技術的な知見は含まれていません。「もし居酒屋で異常検知をネタに呑むとしたら、このへんで盛り上がるかな」的な記事として書いてみましたので、お時間あるときに気軽に読んでいただけたら幸いです。

みんな違ってみんな異常

「異常検知システムを作りました」「異常検知のアルゴリズムならコレがおすすめ」「異常検知してみたい」など異常検知の情報は溢れかえっています。実際には皆それぞれのシステムにおいての「正常」がそもそも違い、それら正常に対する「異常」があるため、異常検知は人それぞれで指している意味が異なっているケースが多くなっています。あまりにも広い範囲に適用される言葉となってしまっていると言えるでしょう。

そのため検索したり書籍を読んだりして入手した異常検知の情報が、自分がやりたい異常検知とまったくリンクしなかったりして時間を浪費することがあり得ます。

「異常検知システムを作ろう」という言葉は「機械学習を使って何かしよう」くらい範囲が広いと考えるようにしましょう。実際に自分がやりたい異常検知は、より具体的にはどのような処理なのか?というのを突き詰める作業、思考が非常に重要です。しかしここに対して(例えばフローチャート的に)ガイドしてくれる情報はあまり見かけません。

あくまで目的が「自社のシステムなどに異常検知機能(システム)を追加したい」ということであれば、異常検知という分野全体について詳しくなる必要はまったくないということを常に頭に入れておき、時間をムダにせず、効率的にプロトタイプがとりあえず動く状態まで持っていくことを最優先にすることをおすすめします。

異常検知システムにおいて何を異常とするか、という根本となる考え方だけでも色々なパターンがあります。下記にいくつかの例をあげます。

  • データをいくつかの既知のクラスへと分類する。そしてある特定のクラスのものを異常とする
  • あるメトリクスについて、正常な範囲外に変化したら異常とする
  • あるメトリクスについて、動きの傾向が変わったら異常とする
  • 今までに見たこともないような状況になったら異常とする
  • システムが障害を起こしたら(反応しなくなったら)異常とする

難しく考えたくなる

異常検知というと機械学習や数学的・人工知能的な技術を使ってすごい高性能のアレなんでしょ?みたいな暗黙の了解というか期待がありがちなため、難しく考えたくなることがあります(え?ない?)。

目的は異常検知をすることですので、できるだけ簡単に、小難しいアルゴリズムや機械学習を導入しなくても動くように考えるのを基本にするのが良いです。システムの異常を見つけたい場合に、単に閾値を設定するだけや、あるいは多少時刻に応じて閾値を変える程度でもそこそこ動く異常検知システムになる可能性があるのではないでしょうか。すぐに「時系列で異常検知するならこのアルゴリズムらしい...」とか「シグマがふたつ、シグマがみっつ...」とやらず、また簡単すぎる仕組みだからといって恥ずかしい等と思わず、まずは「これ、実はすごく簡単にできるのではないか?」という所から始めるのが肝心です。

期待しすぎる

前項に書いたように異常検知が簡単な場合もあり、その場合は難しく考え過ぎないようにシステムを完成させることが大前提です。とはいえやはり機械学習等、最近のテクノロジーを導入してはじめて可能になる異常検知システムもあります。この場合は逆に「実際には問題(異常検知)がけっこう難しいのに、機械学習やAIによって簡単に解決できると期待しすぎてしまう」ことに注意が必要です。これには下記の2パターンがあると思います。

  • scikit-learn等の機械学習のライブラリを使えば、自社で簡単に作れるはず
  • このSaaSサービスやソフトウェアには異常検知の機能もあるようだから、データをどんどん投げれば異常を検知してもらえるだろう

特に後者についてはサーバ管理系の、CPU使用率等のメトリクスをどんどんrsyslog等で送るサービス(基本的にはダッシュボード系のもの)に異常検知の機能を追加することが流行していますが、これは結構うまく動かないことが多いです。ある時間にウェブアクセスが急に増えたりする場合、それは計画通りのキャンペーン実施であったり、あるいはDDoSであったりします。前者は正常、後者は異常ですが、SaaSサービス側は前者のようなケースを正常と判定するのは難しいでしょう。

また、多くのユーザが同じような傾向のメトリクスを送ってきたとしても、あるユーザにとってそれは異常で、別のユーザにとっては正常だったりすることがあります。ある一人のユーザに特化して考えたとしても、少し複雑なシステムであればメトリクスから異常検知するのは難しいのに、どんどん状況が変化していくウェブの世界において多くの利用者に対して同時並行的に異常検知のアルゴリズムを提供しよう、というのは現実的には非常に難しいと考えられます。この辺りはVividCortexのBaron Shwarts氏の講演がとても参考になります。

アルゴリズム部分に注目しすぎる

異常検知の本などは大抵数式だらけで、中身の大部分はアルゴリズムの詳細な解説などが占めています。しかし実際の異常検知のシステム開発ではアルゴリズムの選定とそれを使った処理は非常に重要ではありますが全体に対する重みはわずかです。最も苦労するのは「何をやりたいか?」「どのようなデータが使えるか?」「どのようなインターフェースにするか?」「誰が使うか?」「どこでいつ動かすか?」というような異常検知システム開発そのものであり、これらの点で参考になる情報は非常に少ないというのが私の実感です。

極端な例で考えれば実際の異常検知の処理部分はライブラリを利用するだけで、ソースコード10行以下で済む可能性もあります。アルゴリズムの選択も、いくつか利用可能なものを簡単に切り替えてみて、期待通り動くものが見つかればそれを使うだけで済む場合もあります。この場合はアルゴリズムや数学の知識は殆ど必要ありません。異常検知というと「やっぱりあの最新のアルゴリズム使うの?」のようになりがちですが、実際には泥臭くキモになるのは普通のシステム開発みたいなポイントになるのではないかと思います。

例えば既存の自社のシステムに「検索機能を追加しよう」という場合を例に考えてみるとわかりやすいでしょう。おそらくやることはインターフェースを決めて、どこを検索対象とするかを決めて、どんなサードパーティの検索ライブラリを使うかを決めることだと思います。検索についての論文を片っ端から読み始めたり、「どのアルゴリズムで検索をするか、アルゴリズムの選定が一番重要だ」という人はあまりいないと思います。異常検知もこれと同様で、アルゴリズムはシステム全体の一部のパーツに過ぎません。

必要となる疑問

異常検知システム開発で本当に大変な部分は、下記のような疑問から浮かび上がってくるさまざまな点だと思います。

  • 本当にその異常検知システムは必要か
  • 誰が作りたがっているか
  • 誰が使いたがっているか
  • やろうとしている異常検知は簡単そうか、それとも難しそうか
  • ドメインの深い知識を必要とするか
  • 例えば、新しく入ってきた新人に教えた場合に、すぐにできるようになるようなことか
  • 今、自動で異常検知する仕組みがあるか。無い場合は、なぜ作っていないのか
  • 難しすぎて作っていない場合、人ならば異常を見つけることは簡単か。それとも人でも難しいのか
  • 毎回同じような異常か、それとも色々なパターンの異常があるのか
  • まったくの他人に対して自分たちがどのような異常を見つけたいと考えているかを説明できるか
  • 過去のデータは利用できるか
  • 過去のデータを将来の異常検知のためにそのまま使えるか
  • システムの仕様や利用状況は安定しているか、それともどんどん変化(進化)していくか
  • 過去の正常な状態のデータはあるか
  • 過去の異常な状態のデータはあるか
  • 機械学習が適しているか
  • 教師ありか、教師なしか
  • 不均衡データ(異常の例が極端に少ない)かどうか
  • 学習に利用可能なデータの量はどのくらいか
  • どのくらいのコンピュータリソースが利用可能か
  • どこで学習させて、どこにデプロイして、どこにインターフェースを置くか
  • システム開発に失敗した場合どうするか
  • いつまでに作るか
  • 対象となるのは時系列のデータか
  • 対象となるのは映像や画像のデータか
  • 似た事例があるか

システムの開発を進めていく中で方向性を見失いそうになることもあるかと思いますので、何度も振り返って上記の質問をしていくのが良いでしょう。

まとめ

今回は異常検知システムの開発について、情報収集から開発までの経験を通して感じたことを簡単にまとめてみました。ここで書いた「難しく考えたくなる」「期待しすぎる」「アルゴリズム部分に注目しすぎる」というのはまさに私自身がどっぷりとハマったポイント、いわばバイアス的な部分ですが、それはそれで意外にハマっている間は楽しいものだったりもします。手段が目的化しそうなので注意しないとまずいです。

この記事に見つけた異常についてはお気軽に@kinyukaまでお寄せください。