Elastic StackのX-Packを試す(Machine Learning編)

elastic

おはようございます、藤本です。

現地時間 2017/05/04 に Elastic Stack 5.4.0 がリリースされ、X-Pack に Machine Learning という機能が追加されました。そういえば、リリース日の 5/4 とバージョン 5.4 って狙ったのかな。

今回はその Machine Learning を簡単に試してみました。

Machine Learning に関しては、ワークショップのレポートブログでも触れていますのでご参考にしてください。

X-Pack については以前、一通り触ってみたブログをエントリしました。X-Pack を試すシリーズのエントリは以下をご参照ください。

Machine Learning

Machine Learning は名前の通り、機械学習の機能となります。Elasticsearch にある時系列データからモデルを作成し、今あるデータの異常値の中から異常値を探したり、インデキシングされたデータを異常値として判定できます。今までも Kibana を利用することで Elasticsearch にあるデータを様々な形式で可視化でき、Elasticsearch の強力なクエリを利用することで様々な角度からデータを解析・分析できました。ただし、Kibana は今あるデータを可視化することしかできません。例えば、データの異常値を探し出したい場合、人が見て判断する必要があります。また異常値を人の判断で探し出すため、異常値をリアルタイムで検知することができません。Machine Learning を利用することでこれらの課題を解決することができます。

Elastic 社の公式ブログでいくつかのユースケースで分かりやすく紹介されていますのでそちらをご参照ください。

Elastic StackにMachine Learningが登場

試してみた

今回はまず Machine Learning の機能を学ぶために公式ブログで紹介されているデモを試してみました。

ニューヨーク市のタクシー乗降データでMachine Learningを体験する

環境

  • ノード
    • OS : Amazon Linux 2017.03
    • Elasticsearch : 5.4.3
    • Kibana : 5.4.3
    • Logstash : 5.4.3
    • X-Pack : 5.4.3

環境準備

YUM リポジトリから Elasticsearch、Kibana、Logstash をインストールします。

# echo "[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md" > /etc/yum.repos.d/elastic.repo

# yum install -y java-1.8.0 elasticsearch kibana logstash

Elasticsearch、Kibana に X-Pack をインストールします。

# /usr/share/elasticsearch/bin/elasticsearch-plugin install x-pack
# /usr/share/kibana/bin/kibana-plugin install x-pack

続いて、デモデータをインポートするために Logstash の Translate フィルタープラグインをインストールします。

# /usr/share/logstash/bin/logstash-plugin install logstash-filter-translate

Elasticsearch、Kibana のサービスを起動します。

# /etc/init.d/elasticsearch start
# /etc/init.d/kibana start

データの準備

データの準備は公式ブログの通りに実行しましょう。

Logstash の 5系を利用する場合、ブログにある Logstash の設定例に記載されている logstash-output-elasticsearchhost オプションは ```hosts```` オプションに変わっているのでご注意ください。

ちなみにデータ登録はめっちゃ時間かかります。私は AWS の i3.large 環境で試していたのですが、2時間以上かかりました。

# curl -s -u elastic:changeme localhost:9200/_cat/indices |grep nyc-taxi |awk '{SUM+=$7}END{print SUM}'
10102128

約 1,000万件のデータが入ります。

乗降数から異常値の検出

まずは時間単位のタクシーの乗車数からモデルを作成し、異常値を検出します。この章では 3種類ある Job の内の Single Metric Job の一つのユースケースとなります。Single Metric Job は一種類の Metric から生成する Job です。Job はモデル作成ルールの定義、モデルの作成、モデルからデータを解析する一連の流れだと理解すれば良いと思います。

Kibana へアクセスし、ログインします。X-Pack のデフォルト管理者ユーザーはelastic/changemeです。インデックスはデータの準備の通り登録します。

左メニューから Machine Learning を選択します。最初は Job は登録していませんので空です。「Create new job」をクリックします。

Kibana

「Create a single metric job」 を選択します。

Kibana_2

「From a New Search, Select Index」 に登録したインデックスパターンが表示されます。今回は nyc-taxi-* を登録しましたのでそれを選択します。

Kibana_3

ここではモデルを作成するためのルールを定義します。今回はタクシー乗車数からモデルを作成します。Aggregation は乗車数なので Count を指定します。Bucket span は今回は 30m(分)を指定しました。Bucket span は大きすぎるとデータが均されてしまい適切なモデルを作成することができません。逆に小さすぎるとデータ幅が小さくなり同じく適切なモデルを作成することができません。さじ加減は難しいです。時間はインデックスパターンで指定したタイムフィールドから Aggregation が実行されます。

設定したら、「Use full nyc-taxi-* data」をクリックします。

Kibana

インデックスのデータから Time picker が自動設定され、データがある範囲に絞ってグラフが描画されます。Name に任意のジョブ名を入力し、「Create Job」を選択します。

Kibana

モデルを生成し、モデルから導き出された期待するレンジがグラフに合わせて描画されます。

Kibana

どういうロジックなのか全然わからないけど、何かスゴイ!

もう少し結果を詳しく見てみましょう。「View Result」から詳細を確認できます。

丸印がついているところが異常値と判断されたものとなっています。色によって Severity(異常度)が表されていて、赤い丸印が一番予測値から外れています。下のグラフが Time picker のグラフとなっていて、上のグラフが拡大したものとなります。赤い丸印のところを中心に範囲を絞って拡大します。下のグラフの矢印で範囲を絞ることができます。

Kibana

拡大されました。どういう状態なのかカーソルを丸印に合わせると詳細が表示されます。下記のポイントでは期待値は 7,786.37件 〜 11,162.2件ですが、実際は 3,314件しか乗車数がありませんでした。

Kibana

これだけの操作で異常値を洗い出すことができました。単純な閾値設定では検知が難しいものを機械学習によって検知することができます。施策の効果測定や、障害調査などマーケティングから運用まで色々な用途で活用できそうです。

乗車数、支払金額を乗車地域による影響判断

続いて、複数の観点からモデルを作成してみましょう。複数の値を利用する場合、Multiple Metric Job を作成します。名前の通りですね。

「Create a new job」から「Create a multiple metric job」を選択します。

Kibana

インデックスは先ほどと同じく「nyc-taxi-*」を選択します。

Kibana

Job settings から設定を行います。Single Metric Job より設定項目が多いですね。

  • Fields : 先ほどの Count と同じようにモデルを作成するために集計するデータを指定します。今回は、合計乗車人数で passenger_countSum、最も大きい支払額でtotal_amountMaxを指定します。
  • Bucket span : 先ほど同様、30m(分)を指定します。
  • Key Fields : Single Metric Job にはなかった設定です。公式ブログでは異常の因子と書かれています。Terms Aggregation のことだと思うのですが、、、今回は乗車地域毎に集計したいので PULocationID_t.keyword を指定します。
  • Name : 任意の名前を指定します。

「Create Job」 を選択します。

Kibana

モデルを生成し、モデルから導き出された期待するレンジがグラフに合わせて描画されます。「View Results」をクリックして、詳細を確認してみましょう。

Kibana

Top Influencers に KeyFields で指定した乗車地域の異常値の集計結果が表示されています。Anomaly timelineに時間単位の異常値の集計結果が表示されています。

Kibana

11月4日に異常値があります(NVが赤くなってるので分かりますが!)。ここをクリックすることで 11月4日の異常値だけに絞って表示できます。

Kibana

絞られました。更に NV の赤いところをクリックしてみます。

Kibana

更に下のグラフで NV に絞って表示されました。赤い丸印にカーソルを合わせるとどう異常なのか確認することができます。モデルからの予測値では 202.826ドルぐらいなのが、実際は 3024.3ドルが発生しています。

Kibana

Discovery から実際のデータを確認してみると、5.2km しか走ってないのに 3,000ドルの料金が発生しています。こちらはシステムの異常の可能性が高いですね。

Kibana

まとめ

いかがでしたでしょうか?
まずは機械学習の知識ゼロから触ってみたので、ただただ何かスゴイという感想しかありません。次はドキュメントをちゃんと読んでみて、何かしら自分で実例を考えて試してみたブログをエントリしたいです。また今回は Single Metric Job、Multiple Metric Job を触ったので、Advanced Job も利用してみたいと思います。