
異常検知は「驚きを、早く・静かに・正しく知らせる」ための仕組みづくり。
本記事は、勤怠/売上データの監視を“現場で使える形”に落とし込むための設計と実装テンプレをまとめました。結論から言うと、SLOを先に決め、Rules→Stats→MLの三層で小さく始め、運用でノイズを徹底的に減らすのが最短ルートです。
この記事でわかること
- 勤怠/売上の監視でまず決めるべきSLOテンプレ
- Rules(確定的な異常)→Stats(ロバストZ/STL)→ML(IsolationForest/OneClassSVM)の三層設計
- 誤検知を抑える抑止窓・デダプ・Runbookの運用設計
- コピペで動くPython実装(5分粒度の時系列前処理〜検知)
筆者コメント(ふみと)
データ/マーケ領域で10年、勤怠やEC売上の監視を数十案件で伴走しました。高度なアルゴリズムより効いたのは集計粒度の統一、カレンダー抑止(祝日/連休/締め処理)、そしてアラートの単純化(1指標=1通知)。本記事ではその“現場の型”をテンプレ化しています。
監視の全体像:SLO → Rules/Stats/ML → 運用
Step1:SLO(何をどれだけ守るか)を先に決めます。次に、Step2:三層の検知で異常の取りこぼしと誤検知のバランスを取る。最後に、Step3:運用(抑止・デダプ・Runbook・通知窓口)でノイズを減らし“静かな監視”にします。
SLOテンプレ(すぐ使える例)
勤怠のSLO例
- 目的:不正/ミスやシフト欠員を30分以内に検知
- 指標:打刻の欠損率、日別総勤務時間、早出/遅刻/早退件数、深夜残業時間
- SLO:誤検知月3回以下、MTTD30分以下
- 除外:会社休日/部署休業日/システムメンテ時
売上(EC)のSLO例
- 目的:システム障害/在庫切れ/広告事故の急落を15分以内に検知
- 指標:5分売上、CVR、トラフィック、在庫回転
- SLO:Precision ≥ 0.8、Recall ≥ 0.6(主要障害を落とさない)
データ準備:粒度統一・欠損処理・カレンダー特徴
監視の8割は前処理で決まると言っても過言ではありません。まずは5分粒度に統一し、欠損や営業時間/祝日などの特徴量を付与します。
# 準備:5分粒度へのリサンプリング、祝日/営業時間フラグ
import pandas as pd
# df: DatetimeIndex、columns=\['sales','traffic','cvr'] 等
Five = df.resample('5T').sum(numeric\_only=True)
Five\['traffic'] = df\['traffic'].resample('5T').sum().fillna(0)
Five\['sales'] = df\['sales'].resample('5T').sum().fillna(0)
# カレンダー特徴(外部の社内CSVやAPIで統合)
Five\['dow'] = Five.index.dayofweek
Five\['hour'] = Five.index.hour
三層検知:Rules → Stats → ML
Rules(まず作る:確定的な異常)
「ゼロ売上が3連続」「勤怠CSV未着」「APIエラー率>5%」のような即断・説明可能なルールから着手します。
import pandas as pd
from pathlib import Path
def rule\_zero\_sales(df: pd.DataFrame, window=3):
z = (df\['sales'] == 0).astype(int)
streak = z.rolling(window).sum()
alert = streak >= window
return df\[alert]
def rule\_missing\_file(path: str):
p = Path(path)
return (not p.exists()) or (p.stat().st\_size == 0)
Stats(ロバストZ / STL)
外れ値に強いロバストZ(中央値・MAD)と、日内季節性を取り除くSTL分解で残差の外れを検知します。
import numpy as np
import pandas as pd
from statsmodels.tsa.seasonal import STL
def robust\_z(x: pd.Series):
med = np.median(x)
mad = np.median(np.abs(x - med)) or 1e-9
return 0.6745 \* (x - med) / mad
# ロバストZで急落のみ拾う例
z = robust\_z(Five\['sales'])
alerts\_z = Five\[z < -3.5]
# STL分解(5分×288=1日)
stl = STL(Five\['sales'], period=288)
res = stl.fit()
resid = res.resid
alerts\_stl = Five\[np.abs(robust\_z(resid)) > 3.0]
運用Tip
営業時間帯のみを判定対象にする/昼休み・閉店は抑止。しきい値はPrecision目標から逆算して決めます。
ML(IsolationForest / OneClassSVM)
多変量の相関を使って候補を拾い、Rules/Statsで再確認してから通知する二段構えが有効です。
from sklearn.ensemble import IsolationForest
from sklearn.svm import OneClassSVM
from sklearn.preprocessing import StandardScaler
feat = Five\[\['sales','traffic','cvr','hour','dow']].fillna(0)
X = StandardScaler().fit\_transform(feat)
# IsolationForest(軽量で堅牢)
iso = IsolationForest(n\_estimators=300, contamination=0.01, random\_state=42)
alerts\_iso = Five\[iso.fit\_predict(X) == -1]
# OneClassSVM(シャープだが調整が難しい)
oc = OneClassSVM(nu=0.01, kernel='rbf', gamma='scale')
alerts\_svm = Five\[oc.fit\_predict(X) == -1]
ユースケース:勤怠・売上での指標と検知
勤怠:未打刻/勤務時間逸脱/深夜残業の連続
未打刻はRulesで確定検知。勤務時間の逸脱は部署中央値との差をロバストZで評価します。
# attn: columns=['date','dept','work_hours', ...]
by_dept = attn.groupby(['date','dept'])['work_hours'].median().rename('dept_med')
X = attn.merge(by_dept, on=['date','dept'])
X['z'] = robust_z(X['work_hours'] - X['dept_med'])
alerts_attn = X[X['z'] > 3.5]
PII保護
氏名はハッシュ化、参照は最小権限、目的外の二次利用禁止。人事データの取り扱いは必ず社内規程に従ってください。
売上:ゼロ売上連続/CVR急落/トラフィック急落
CVR = sales / traffic(ゼロ割回避)の時系列で、移動平均からの偏差を監視します。
eps = 1e-9
Five['cvr'] = Five['sales'] / (Five['traffic'] + eps)
ma = Five['cvr'].rolling(288, min_periods=60).mean()
std = Five['cvr'].rolling(288, min_periods=60).std()
alerts_cvr = Five[(ma - Five['cvr']) > 3*std]
アラート運用:ノイズと疲弊を減らす設計
- サプレッション:昼休み/閉店/締め処理の抑止窓を設定
- デダプ:同一原因の連続通知は10〜30分で集約
- 重大度:Rules > Stats > ML、S1/S2/S3を明記
- 通知窓口:Slack
#ops-alert
や ops@ に一本化 - Runbook:手順書URL・当番・エスカレーションを本文に同梱
[ALERT][S1] ゼロ売上が3連続(EC)
- 時刻: 2025-09-05 10:15 JST
- 影響: 決済/カート障害の可能性
- 対応: 1) ステータスページ確認 2) エラーログ検索 3) 決済ベンダーへ連絡
- Runbook: https://internal/wiki/alerts/zero-sales
- 抑止: なし
検知のKPIとチューニング
Precision(誤検知の少なさ)、Recall(取りこぼしの少なさ)、F1、MTTD、Alert/minを追いかけます。過去インシデントのラベルでバックテストし、しきい値や抑止窓を同時最適化します。
import numpy as np
import pandas as pd
ths = np.linspace(2.0, 4.0, 9)
rows = \[]
for t in ths:
pred = (np.abs(robust\_z(resid)) > t)
\# y\_true は 0/1 のラベル(ここでは擬似コード)
P = (pred & (y\_true==1)).sum(); FP = (pred & (y\_true==0)).sum(); FN = ((\~pred) & (y\_true==1)).sum()
prec = P / (P+FP+1e-9); rec = P / (P+FN+1e-9)
rows.append({"t"\:t, "precision"\:prec, "recall"\:rec, "alerts"\:int(pred.sum())})
res = pd.DataFrame(rows)
最小実装→運用のロードマップ
- 監視ポリシー宣言:対象=勤怠/売上の時系列、方針=Rules→Stats→ML、抑止/デダプあり、SLO=Precision≥0.8・MTTD≤30分、体制=当番制度(平日9-18)
- スケジュール:5分バッチ(集計→Rules→Stats)/30分バッチ(MLスコア)/毎朝(前日サマリPDF)
- 可視化と共有:アラート件数・MTTD・Top原因・抑止状況のダッシュボード/週次レビューでルール更新
今日やること(60分)
- SLO/監視ポリシーを1ページにまとめて合意
- Rules(ゼロ売上連続/未打刻)を先に導入
- ロバストZ+STLで急落検知のプロトを作成(5分粒度)
- 抑止窓/デダプ/Runbookを整備し、週次レビュー開始
まとめ
設計が先、アルゴリズムは後。まずはSLOを明文化し、Rules→Stats→MLの順で最小構成を組む。運用で抑止とデダプを効かせ、Precision 0.8 を目標に静かな監視を実現しましょう。
伴走サポート
無料カウンセリング/体験で、監視対象の定義→三層検知→抑止/Runbook→自動化まで一気通貫で支援します。誤検知削減と検知速度のSLO達成を、現場起点で設計します。
TechAcademy データサイエンスコース(受講料:174,600円~ ※更に割引あり)

株式会社キカガク AI人材長期育成コース(受講料:237,600円~)

この記事から次に読むべきもの(内部リンク)
-
-
コピペで動く需要予測|ARIMA×LightGBMでベースライン→運用まで
現場でちゃんと当たる需要予測って、どこから始めればいい? ベースライン→検証→運用まで、一気通貫で進める“型”で解説します。 この記事は、ARIMAとLightGBMを使った需要予測ミニプロジェクトの ...
-
-
【保存版】データレポート納品の型:要件定義→ETL→検証→可視化→Excel/PDF→引き継ぎまで、失注しないワークフロー完全版
“いい分析”より“伝わる納品”。副業や実務で評価されるのは、意思決定に効く1枚と再現できるパッケージを期限通り出せること。 本記事は、未経験〜初学者が週10時間×2〜3週で、要件定義→データ受領→ET ...
-
-
“落ちない”社内自動化3選:再実行安全・ロック・JSONログで回す設計とテンプレ
社内の自動化、まず何から作ればいい? ちゃんと動き続けて、運用が楽になる設計が知りたい…! そんな悩みに対して、現場で短期に価値を出しやすい“3つの自動化”と、そのまま使える設計&コードの型をまとめま ...
-
-
自動化:スケジューリングと業務改善の型|「再実行安全×観測可能×静かに動く」を仕組みにする
夜中に動かしているPython、自動で止まってた…ログもなくて原因が追えない…。 「毎朝のレポート」や「在庫監視」を、壊れず静かに回したい…! 業務で落ちない自動化を作る鍵は、(1) 再実行安全(Id ...
-
-
【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得
リード(結論)基礎を終えたら次は実務の現場で頻出する処理を“型”で覚える段階です。本記事は、pandas 2.x を前提に、欠損・外れ値・結合・ウィンドウ関数・時系列・カテゴリ処理・集計の自動化・大規 ...
-
-
【保存版】scikit-learn基礎:回帰・分類・前処理・パイプライン・交差検証を“実務の型”で習得
機械学習で迷子になる最大の理由は、前処理→学習→評価→改善の順番が曖昧なまま個々のアルゴリズムに飛びつくこと。本記事は、未経験〜初学者が週10時間×2〜3週で到達できるscikit-learnの最短ル ...
-
-
【保存版】モデル評価:指標の選び方・交差検証・閾値最適化・ビジネス接続を“実務の型”で解説
精度が上がらない原因の多くは「評価設計の誤り」にあります。評価とは「何点取れたか」ではなく、意思決定に耐えるかを測る営み。この記事では、回帰/分類/ランキングの指標の選び方、交差検証の正しい使い分け、 ...
-
-
Python実務の型:例外処理と構造化ログでエラーに強いコードを書く
例外処理って、結局どこまでやれば“実務で困らない”の? ログも整えるのって大変そう…最低限の型、ください! この記事は、pythonbunseki.comの実務トーンで「防ぐ→気づく→復旧する」をコー ...
最近のコメント