Azure Stream Analyticsでビルトインされた異常検知モデルを動かしてみる

#はじめに
Stream Analyticsの異常検知がなかなかよさそうなので試してみた


##Stream Analyticsの異常検知とは
閾値を設けずに今までの傾向からみて急に上がったり下がったり（Spike / Dip）、長期的な傾きが急に変わったり（ChangePoint）を検出してくれる機能
裏側では機械学習モデルが働いている

##SpikeAndDip
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0bbc5043-e720-3be3-6602-86950cd258cb.png)

##ChangePoint
レベルの変化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/55699156-479d-3a7e-d789-0d22fa954670.png)

傾向の変化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d8d16465-4768-e785-33dc-5bacfb9887c5.png)


#参照
詳しくはこちら
https://docs.microsoft.com/ja-jp/azure/stream-analytics/stream-analytics-machine-learning-anomaly-detection

関数の説明も
https://docs.microsoft.com/en-us/stream-analytics-query/anomalydetection-spikeanddip-azure-stream-analytics
https://docs.microsoft.com/en-us/stream-analytics-query/anomalydetection-changepoint-azure-stream-analytics

##今回動かしてみるもの
Device Simulater
https://github.com/Azure/azure-stream-analytics/tree/master/Samples/DeviceSimulator

##


#動かしてみる
gitからコードをダウンロードしてVisual Studioで開いてみる
DeviceSimulator.csproj　を開くよ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/401f96cd-f5a7-9162-53c0-7cbfd70eecb1.png)


依存関係に問題があるんで「依存関係」を右クリック→「NuGetパッケージの管理」から同名のものを一つずつインストールします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d2806838-3f8c-54bf-cbc2-7ac1d1e97a52.png)

更新とかすればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/e0d9e5f1-e654-e4bc-3e37-5db814e3482e.png)

３つのパッケージを更新したらDevice Simulatorが使えます
すごいぞ~扱いやすいぞ~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/e44b301d-09cd-6e3d-ae54-de8dac3b7932.png)

IoT Hub Configを埋めてあげたら準備OK

Stream Analytics Jobのクエリはこう書いた
公式のドキュメント内のSQLをくっつけてます。
ChangePointは学習期間を短めにしている

```SQL
WITH AnomalyDetectionStep AS
(
    SELECT
        EVENTENQUEUEDUTCTIME AS time,
        CAST(temperature AS float) AS temp,
        AnomalyDetection_SpikeAndDip(CAST(temperature AS float), 95, 120, 'spikesanddips')
            OVER(LIMIT DURATION(second, 120)) AS SpikeAndDipScores
    FROM anomalyiot
),AnomalyDetectionStep2 AS
(
    SELECT
        EVENTENQUEUEDUTCTIME AS time,
        CAST(temperature AS float) AS temp,
        AnomalyDetection_ChangePoint(CAST(temperature AS float), 80, 120) 
       -- OVER(LIMIT DURATION(minute, 20)) AS ChangePointScores
        OVER(LIMIT DURATION(second, 120)) AS ChangePointScores
    FROM anomalyiot
)
SELECT
    time,
    temp,
    CAST(GetRecordPropertyValue(SpikeAndDipScores, 'Score') AS float) AS
    SpikeAndDipScore,
    CAST(GetRecordPropertyValue(SpikeAndDipScores, 'IsAnomaly') AS bigint) AS
    IsSpikeAndDipAnomaly
INTO anomalyspikedippbi
FROM AnomalyDetectionStep;
SELECT
    time,
    temp,
    CAST(GetRecordPropertyValue(ChangePointScores, 'Score') AS float) AS
    ChangePointScore,
    CAST(GetRecordPropertyValue(ChangePointScores, 'IsAnomaly') AS bigint) AS
    IsChangePointAnomaly
INTO anomalychangepbi
FROM AnomalyDetectionStep2
```
Power BIで出力を確認してみる
temp=気温
出力値は下記のようになってます。
SpikeAndDipScore=スコア
IsSpikeAndDipAnomaly=検知フラグ

ChangePointScore=スコア
IsChangePointAnomaly=検知フラグ

まずはSpike。感知が早い
Scoreの読み方はわからないけど、0ほど異常？
とりあえず使えそう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/625e5375-b65a-3dff-62e2-29fa72733e51.png)

対してChangePoint。傾向を見ているので、変わった瞬間ではない
公式でもChangePointは長期的な変化傾向の異常を検知すると書いてある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/75cb5449-01fe-2e0b-8cc4-e49569becd46.png)

それにしてもScoreは一体・・・
>イベントがどれだけ異常であるかを示す、計算されたMartingaleスコア（float）。このスコアは、異常値とともに指数関数的に増加します。

とあるけどなんか逆な気がする。これうまく動いているのかな？動画のおじさんはSpikeAndDipしかやってなかったからChangePointは正解がわかりませんがなんとなく検知できてるのでよし！


アルゴリズムはそれぞれ
SpikeAndDip 適応カーネル密度推定アルゴリズム
ChangePoint 交換可能性マルチンゲールアルゴリズム
を使っているらしいけどぶっちゃけわけわかめ。

このあたりは割り切ってツールとして使うべきなんでしょう。
独自のモデル、アルゴリズムを使いたいなら推論環境作って連携すればいいと思うけど、それをやらなくてもこのように異常検知の仕組みができるのは素敵だと思う

おしまい