mcpField
E
elasticsearch-anomaly-detection-explainer

elasticsearch-anomaly-detection-explainer

github.com/elasticデータ・データベース6021.1k 回インストール今日更新
リポジトリ

elasticsearch-anomaly-detection-explainer について

elasticsearch-anomaly-detection-explainerは、Elasticsearch ML異常検知の利用者向け解釈スキルです。ジョブ設定と異常レコードを調べ、スコア、モデルの挙動、再正規化、関連する背景情報を説明します。

主な機能

  1. 01MLジョブ設定と統計情報の取得
  2. 02初期スコアと現在のスコア差の説明
  3. 03actualとtypicalによる異常方向の解釈
  4. 04スコア要因と影響エンティティの確認
  5. 05モデル境界とログカテゴリの取得

活用シーン

  1. 01特定の異常レコードのスコア説明
  2. 02予想外に低いまたは高いスコアの調査
  3. 03ジョブ全体のスコア再正規化の測定
  4. 04異常の影響要因やモデル境界の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/elastic/agent-skills --skill elasticsearch-anomaly-detection-explainer

インストール後、Claude Code で/elasticsearch-anomaly-detection-explainerを入力して読み込まれたか確認します。

同梱ファイルreferences/explainer-reference.md

詳細

異常検知スコアの解説

異常スコアやモデルの動作を説明し、結果がそのように見える理由を解説します。ジョブ設定には ML REST API を使用し、 結果の取得には .ml-anomalies-* に対する標準の _search API を使用します。ES|QL は使わず、Elastic Serverless と完全に互換性があります。ジョブのライフサイクル(作成、開始、停止)には、elasticsearch-anomaly-detection スキルを使用してください。

環境設定

このスキルでは、Elasticsearch の操作に elastic CLI を使用します。 elastic CLI がインストールされていない場合は、何に必要なのかをユーザーに伝えてください。認証情報を推測したり、HTTP API を直接呼び出したり、ほかの回避策を試したりしないでください。

このスキルでは、HTTP 省略形式(例:GET /、GET /_cat/indices、GET /{index}/_mapping、 GET /{index}/_settings/index.mode、POST /_query)で操作を参照します。このドキュメントの最後にある 操作の表で、各省略形式に対応する elastic CLI コマンドを確認できます。HTTP API を直接呼び出すのではなく、必ず CLI を使用してください。

前提条件: ML 異常検知をセルフマネージドクラスターで使用するには、Platinum 相当のライセンスが必要です。Serverless プロジェクトには ML が含まれています。呼び出し元には、ジョブ設定と異常結果を読み取るための monitor_ml 権限が必要です。

Serverless に関する注意: Elastic Serverless では、_ml/.../results/* REST エンドポイントは HTTP 410 を返します。結果のクエリには、常に POST /.ml-anomalies-*/_search を使用してください。この方法は、このスキルが実行されるすべての環境で完全にサポートされています。

プロセス

  1. データを取得するか、ユーザーが提供した内容を解釈するかを判断します。 ユーザーのプロンプトに異常レコード(またはジョブ設定)が含まれている場合は、以下のドメイン知識を使ってそのまま解釈します。すでに提示されているフィールドを再取得するために API を呼び出さないでください。ジョブ ID、時間範囲、またはレコードが不足している場合は、クラスターから取得します。

    判断基準:レコードに record_score、 initial_record_score、actual、typical、function が含まれている場合は、判断のみに基づく説明に進みます。それ以外の場合は、説明の前に不足している情報を取得します。

  2. クラスターに接続するときは、接続を確認します。 GET / を呼び出します。呼び出しに失敗した場合は、処理を中止して接続エラーを提示してください。エンドポイントや認証情報を推測しないでください。

  3. ジョブ ID を特定し、設定を読み込みます。 ジョブ ID が不明な場合は、GET /_ml/anomaly_detectors を呼び出して候補を一覧表示します。GET /_ml/anomaly_detectors/{job_id} を呼び出して、完全な analysis_config(bucket_span、detectors、 custom_rules、use_null、model_plot_config)を取得し、GET /_ml/anomaly_detectors/{job_id}/_stats を呼び出して、state、 model_size_stats.memory_status、データ件数を取得します。

    判断基準:スコアを解釈する前に、検知器の関数と方向がユーザーの質問に合っていることを確認してください。low_count ジョブが減少を検知するのは正常ですが、high_count ジョブは減少を検知しません。

  4. 時間範囲内の異常レコードを取得します。 result_type: record、ジョブ ID、タイムスタンプの範囲、必要に応じて record_score フィルターを指定して、POST /.ml-anomalies-*/_search を呼び出します。initial_record_score、record_score、actual、 typical、function、multi_bucket_impact、anomaly_score_explanation を読み取ります。

    initial_record_score と record_score の両方を必ず表示してください。 両者の差が再正規化の経緯を示します。

  5. 原因を推測する前に、スコアのパターンを分類します。

    • initial_record_score >> record_score — 再正規化です。 後から発生した、より極端な異常によって、このレコードのスコアが下方修正されています。これは想定どおりの健全なモデルの動作であり、モデルの故障や検知を疑う理由にはなりません。アラートの重大度には initial_record_score を使用し、両方のスコアを示して、その差を明確に説明します。
    • initial_record_score == record_score — 検知以降、再正規化は行われていません。
    • actual << typical で、low_count、count、または low_mean がある場合 — 欠落/減少の異常です。 高スコアは妥当なもので、ジョブが停止、パイプラインの停滞、またはサービス障害を検知しています。これは誤検知ではありません。 スコアの調整ではなく、インシデントの調査を推奨します。
    • actual >> typical で、high_count または high_mean がある場合 — スパイク異常です。single_bucket_impact で確認します。

    レコードに存在する anomaly_score_explanation の要因のみを挙げます。 high_variance_penalty が false の場合、分散を原因にしてはいけません。要因がない場合は、返されていないことを記載し、作り上げてはいけません。

  6. ジョブ全体の再正規化を定量化します(任意)。 POST /.ml-anomalies-*/_search を再実行し、対象の時間範囲のレコードを timestamp の昇順で並べます。レコードごとに score_drift = initial_record_score − record_score を計算し、|score_drift| ≥ 20 で絞り込みます。大きな負のドリフト(initial >> record)は、後からより極端な異常が出現したことで再正規化されたことを示します。

  7. ユーザーが「何が原因ですか?」や「なぜこれほど低い/高いのですか?」と尋ねた場合は、コンテキストを追加します。

    • モデルの境界 — model_plot_config.enabled が true の場合、同じジョブと時間範囲を対象に、result_type: model_plot を指定して POST /.ml-anomalies-*/_search を呼び出します。actual を model_lower/model_upper と比較します。
    • インフルエンサー — バケットの時間範囲を対象に、result_type: influencer を指定して POST /.ml-anomalies-*/_search を呼び出し、influencer_score の降順で並べます。
    • カテゴリ化ジョブ — result_type: category_definition を指定して POST /.ml-anomalies-*/_search を呼び出し、学習済みのログパターン(category_id ごとの terms、regex、examples)を一覧表示します。

    集計、ジョブ横断のクエリ、バケットレベルの結果、またはスコアと時間以外のカスタムフィルターについては、references/explainer-reference.md を参照してください。

よくある複数ステップのワークフロー

タスク手順(順番どおり)
特定の異常を説明するジョブ設定 → レコード(ジョブ+正確な時刻)→ initial_record_score と record_score、およびスコア要因を提示します。
スコアが低いのはなぜですか?ジョブ設定 → レコード → 再正規化の確認 → モデルプロット(有効な場合)→ スコア要因を説明します。
スコアが高いのはなぜですか?ジョブ設定 → レコード → 関数の方向、不十分な履歴、use_null、カーディナリティを確認します。
再正規化のドリフトレコード(timestamp で並べ替え)→ score_drift を計算 → initial >> record のレコードを一覧表示します。
どのエンティティが寄与しましたか?インフルエンサー(ジョブ+時間範囲)→ influencer_score で並べ替えます。
モデルの境界を可視化するモデルプロット(ジョブ+時間範囲)→ model_lower/model_upper と actual を比較します。
カテゴリ化ジョブのパターンcategory_definition(job_id)→ カテゴリごとの terms、regex、examples。

重要な原則

  • まずレコードを取得してください(または、ユーザーが提供したレコードを使用してください)。initial_record_score、 record_score、actual、typical、function がない状態でスコアを説明してはいけません。
  • 再正規化は正常な動作です。 initial_record_score >> record_score の場合、後からより極端な異常が発生して このスコアが下がったことを示します。これは想定された動作であり、モデルの不具合ではありません。
  • 方向が重要です。 low_count は値が低下したときに反応し、high_count は急上昇したときに反応します。交通量の 停止で low_count のスコアが高い場合は、誤検知ではなく正しい検知です。
  • 推測する前に要因を説明してください。 レコードから anomaly_score_explanation を確認してください。含まれていて 関連性のある要因のみ取り上げてください。
  • ジョブ設定は不可欠です。 bucket_span、検出関数、custom_rules、use_null、メモリの状態はすべてスコアに 影響します。スコアに違和感がある場合は、ジョブ設定を調べてください。
  • 最も視覚的に説明できるのはモデルプロットです。 有効になっている場合は、モデルの範囲を表示して、実際の値が 予測範囲のどこに位置するかを示してください。
  • ジョブの健全性(「ドキュメントが不足している」「メモリ制限」「データフィードが実行されていない」)については、 elasticsearch-anomaly-detection スキルを使用してください。

ドメイン知識

スコアの種類
用語意味
record_score単一の異常レコードに対する正規化済みの 0~100 のスコア。再正規化によって更新されます。75 超は重大です。
initial_record_score再正規化前、検出時に割り当てられたスコアです。アラートにはこの値を使用してください。
anomaly_scoreジョブ内のすべての検出器を集約した、バケットレベルの重大度です。
influencer_scoreバケット内の特定のエンティティ(ホスト、ユーザー、サービス)がどれほど異常かを示します。高いほど原因である可能性が高くなります。
multi_bucket_impact0~5 の値で、複数のバケットにわたって持続する動作がスコアをどれほど引き上げたかを示します。≥3 は動作の変化を示します。
anomaly_score_explanation の要因

各レコードの anomaly_score_explanation フィールドでは、スコアが要素ごとに分解されています。

要因方向意味
anomaly_length上昇異常が継続した連続バケット数です。長いほどスコアが高くなります。
single_bucket_impact上昇この単一バケットの極端さです。確率が低いほど影響度が高くなります。
multi_bucket_impact上昇複数のバケットにわたって持続するパターンの寄与です。
anomaly_characteristics_impact上昇異常が平均値のシフトか分散の変化かを示します。
high_variance_penalty低下ノイズの多いデータやトレーニング初期には信頼区間が広がり、スコアが下がります。
incomplete_bucket_penalty低下バケット内のデータが想定より少なかったことを示します(データの遅延、イベントの疎らさ)。
スコアが予想外に低くなる理由
  • high_variance_penalty: 指標の過去の変動が大きく、信頼区間が広いため、急上昇が吸収されます。
  • 再正規化: 後からより極端な異常が発生し、このスコアが下がりました(initial_record_score >> record_score)。
  • トレーニング履歴が不十分: 週ごとの季節性には 3 週間以上、検出対象の期間には完全な周期が 2 回以上必要です。
  • bucket_span が大きすぎる: 短時間の急上昇が平滑化されます。高頻度のイベントには、より小さな bucket_span を使用してください。
  • 検出関数の不一致: mean と high_mean、count と high_count のような違いです。反応する方向は一方だけです。
  • incomplete_bucket_penalty: バケットに取り込まれたデータが想定より少なかったことを示します(取り込みの遅延または欠落)。
  • custom_rules: 検出器のフィルターによって異常が抑制されている可能性があります。
スコアが予想外に高くなる理由
  • 履歴が不十分: モデルがまだ通常のパターンを学習していないため、初期の異常は信頼性が低くなります。
  • モデルの分割が細かすぎる: カーディナリティの高い partition_field または by_field によって、エンティティごとのポイントが非常に少なくなり、確率の信頼性が低くなります。
  • use_null: use_null: true の場合、欠落したエンティティによって「null」異常が発生しますが、意味があるとは限りません。
  • 不在/減少の検出: low_count または low_mean では、actual << typical によって正当に高いスコアが生成されます。これは誤検知ではなく、実際のインシデントとして扱ってください。
モデルの動作に関する概念
概念意味
actual観測値です。typical はモデルが予測した値です。方向が重要です。
不在異常count、low_count、または low_mean での actual << typical は、停止、パイプラインの中断、サービス障害を示します。
by_fieldエンティティごとの独立したベースライン(例:ホストごと)です。各エンティティをそれぞれの履歴と比較します。
over_field母集団の分析です。エンティティを自身の履歴ではなく、同じバケット内のピアグループと比較します。
partition_fieldパーティションごとにスコアの正規化を分けた、完全に独立したサブモデルです。
モデルプロットとカテゴリ
  • モデルプロット: 各時点でモデルが学習した上限と下限を示します。actual が範囲内なら異常ではありません。範囲外の場合、スコアは境界からの距離に応じて決まります。ジョブで model_plot_config が有効な場合にのみ利用できます。result_type: model_plot を指定して POST /.ml-anomalies-*/_search でクエリします。
  • カテゴリ: categorization_field_name を持つジョブでは、result_type: category_definition をクエリすると、ログメッセージのパターン(各 category_id の用語、正規表現、例)を表示できます。異常レコードでは by_field_value = <category_id> が使用されます。

スコアのトラブルシューティング手順

  1. ジョブを一覧表示する — ジョブ ID が不明な場合は、GET /_ml/anomaly_detectors を呼び出します。
  2. ジョブの設定と統計情報を取得する — GET /_ml/anomaly_detectors/{job_id} と GET /_ml/anomaly_detectors/{job_id}/_stats を呼び出します。bucket_span、検出関数、custom_rules、use_null、 ジョブの状態(opened/closed/failed)、model_size_stats.memory_status を確認します。
  3. レコードを取得する — result_type: record、ジョブ ID、時間範囲、およびオプションの最小 record_score を指定して、 POST /.ml-anomalies-*/_search を呼び出します。initial_record_score、record_score、actual、typical、function、 multi_bucket_impact、anomaly_score_explanation を確認します。
  4. 再正規化を確認する — initial_record_score と record_score を比較します。初期値がレコードスコアを大幅に上回る場合は、タイムスタンプ順にレコードを再クエリし、score_drift を計算してジョブ全体の再正規化を定量化します。
  5. モデル境界を可視化する — model_plot_config が有効な場合は、result_type: model_plot をクエリし、実際の値が model_lower と model_upper に対してどの位置にあったかを示します。
  6. インフルエンサー — 異常バケットの時間範囲について result_type: influencer をクエリし、influencer_score の降順に並べます。
  7. 要因を説明する — レコードの anomaly_score_explanation から、該当する存在する要因をそれぞれ説明します。 high_variance_penalty、incomplete_bucket_penalty、anomaly_length、single_bucket_impact、 multi_bucket_impact が対象です。レコードに存在しない要因には言及しないでください。

例

  • 「急上昇が大きく見えるのに、異常スコアが 15 なのはなぜですか?」→ 再正規化を確認してください。initial_record_score(約 92)>> record_score(約 15)です。急上昇は実際に発生していましたが、現在のスコアは再スケーリングされて低くなっています。アラートには初期スコアを使用してください。
  • 「トラフィックが止まったのに、HIGH スコアが出ました。誤検知ですか?」→ いいえ。actual が typical を大きく下回る low_count は、正当な不在検知です。障害を調査してください。
  • 「昨夜、ジョブ X の異常に最も寄与したエンティティはどれですか?」→ 該当する時間範囲のインフルエンサーをクエリしてください。
  • 「このジョブのモデル境界を表示してください。」→ model_plot_config が有効な場合は、モデルプロットをクエリしてください。
  • 「スコアが大幅に下方へ再正規化されたレコードを一覧表示してください。」→ タイムスタンプ順にレコードを並べ、initial_record_score − record_score が大きいものを絞り込んでください。

ガイドライン

  • API またはユーザー提供のレコードに含まれる情報のみを報告してください。スコア、タイムスタンプ、エンティティ値、説明要因を捏造しないでください。
  • レコードについて説明する際は、必ず initial_record_score と record_score の両方を示し、再正規化が発生したかどうかを明示してください。
  • スコア要因がレコードにない場合は、それについて断定せず、そのフィールドが返されなかったことを記載してください。
  • レコード内のフラグが false または存在しない場合は、低スコアの原因を high_variance_penalty または incomplete_bucket_penalty にしないでください。
  • 調査(「原因は何ですか?」「どのサービスに責任がありますか?」)では、インフルエンサーをクエリするか、references/explainer-reference.md を参照してジョブ間検索を組み立ててください。
  • ジョブの健全性を確認するには、elasticsearch-anomaly-detection スキルを使用してください。

操作

HTTP API(省略形)elastic CLI コマンド
GET /elastic es info
GET /_ml/anomaly_detectorselastic es ml get-jobs
GET /_ml/anomaly_detectors/{job_id}elastic es ml get-jobs --job-id '<job_id>'
GET /_ml/anomaly_detectors/{job_id}/_statselastic es ml get-job-stats --job-id '<job_id>'
POST /.ml-anomalies-*/_searchelastic es search --index '.ml-anomalies-*' --input-file '<search-body.json>'

各 result_type(record、influencer、model_plot、category_definition)のクエリ本文の形式は、 references/explainer-reference.md に記載されています。

コメント