日別のセッション数の表を AI に貼り、「おかしな日はあるか」と聞いているマーケターや事業担当の方向けの記事です。AI の異常検知をデータ分析に使う前に、AI が挙げた日が統計の基準でも外れているかを、公開データと SQL で確かめた結果を紹介します。読み終わると、根拠つきで外れた日を挙げてもらう頼み方と、その答えを検算する順番が分かります。
この記事で分かること
- 「おかしな日を挙げて」とだけ頼むと、AI が挙げた 10 日のうち 7 日は、どの統計の基準でも外れていなかったこと
- 基準を「全体の平均」から「同じ曜日どうし」に変えるだけで、外れた日そのものが入れ替わること
- AI に基準を言わせ、同じ基準を SQL で計算して突き合わせる、検算の順番とひな形
今回確かめたのはセッション数(サイトへの訪問のまとまりの数)だけです。売上と購入数の外れた日は計算していません。理由は「使うデータ」の節で説明します。
AI の異常検知とは:外れ値検出を表で頼むということ
異常検知(いつもと違うデータを見つけること)には、ふだんの範囲から飛び出た値を探す外れ値検出や、傾向が切り替わった時点を探す変化点検出などの種類があります。この記事で扱うのは、日別の表の中で「この日だけ飛び出ている」を探す外れ値検出です。
表を AI に貼って「おかしな日は?」と聞くと、AI はもっともらしい理由を添えて日付を挙げてくれます。ただ、AI がどんな物差しで「おかしい」と判断したのかは、頼み方によっては答えに書かれません。物差しが分からないと、挙がった日が本当に外れているのかを確かめられないため、まず物差しを 3 つ決めました。
「外れた日」の基準を 3 つ決める:標準偏差・四分位・曜日別
ここでは統計的手法(データの散らばりから「ふつうの範囲」を数字で決めるやり方)を 3 つ使います。機械学習のモデルは使いません。どれも SQL の関数だけで計算でき、読者が同じ結果を出せるためです。
| 基準 | ふつうの範囲の決め方 | 特徴 |
|---|---|---|
| (1) 標準偏差 | 全体の平均 ± 2 標準偏差 | 大きな値に引っ張られやすい |
| (2) 四分位 | Q1 − 1.5×IQR 〜 Q3 + 1.5×IQR | 極端な値に引っ張られにくい |
| (3) 曜日別 | 同じ曜日の平均 ± 2 標準偏差 | 週末の落ち込みを除ける |
標準偏差は、値が平均からどれだけ散らばっているかを表す数です。BigQuery の STDDEV は STDDEV_SAMP の別名で、標本標準偏差(データの件数から 1 を引いた数で割る計算)を返します(BigQuery の統計集計関数)。件数で割る母集団標準偏差が欲しいときは STDDEV_POP を使います。
四分位は、値を小さい順に並べて 4 等分する区切りです。下から 25% の位置を Q1、75% の位置を Q3 と呼び、その差を IQR(四分位範囲)と呼びます。
四分位を計算する関数には、近似の APPROX_QUANTILES もあります。この関数は厳密な値ではなく近似の値を返し、統計的な不確かさが入ると公式に書かれています(BigQuery の近似集計関数)。境目の日を判定するには近似のずれが邪魔になるため、今回は厳密な PERCENTILE_CONT で計算しました。
使うデータ:GA4 公開サンプルの日別の表 92 日分
使ったのは、BigQuery の公開データ ga4_obfuscated_sample_ecommerce です。Google Merchandise Store の 2020 年 11 月 1 日から 2021 年 1 月 31 日までの、3 か月分の GA4 イベントデータです(Google アナリティクス 4 の BigQuery サンプル データセット)。
このデータは実際のデータに似せて難読化(中身が分からないように値を加工すること)されています。公式の説明では、難読化によって内部の整合性が少し制限される可能性があり、GA4 のデモアカウントの数字とも比べられません。なので、ここで出る数字は「やり方を試すための数字」として読んでください。
筆者が実行した問い合わせでは、全体は 92 日・4,295,584 イベントでした。日付の列 event_date は、YYYYMMDD 形式の文字列です(BigQuery Export スキーマ)。そのため、PARSE_DATE で日付の型に直してから曜日を取り出します。
WITH daily AS (
SELECT PARSE_DATE('%Y%m%d', event_date) AS d,
COUNT(DISTINCT IF(event_name='session_start', CONCAT(user_pseudo_id, CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key='ga_session_id') AS STRING)), NULL)) AS sessions,
COUNTIF(event_name='purchase') AS purchases,
ROUND(SUM(IF(event_name='purchase', IFNULL(ecommerce.purchase_revenue_in_usd,0), 0)),2) AS revenue_usd
FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`
GROUP BY d
)
SELECT d, FORMAT_DATE('%a', d) AS dow, sessions, purchases, revenue_usd FROM daily ORDER BY d
この SQL は筆者が実行した原文です。セッション数は、session_start イベントのユーザー ID とセッション ID の組を重複なしで数えました。
売上の列 purchase_revenue_in_usd は、購入イベントにだけ入る米ドルの金額です(BigQuery Export スキーマ)。ところが今回の結果では、売上が 2021-01-26 から急に下がって 01-27 以降は 0 近くになり、購入数は残っていました。原因を確かめられなかったため、この記事はセッション数だけで検算します。
AI への頼み方 3 通りと、挙げられた日
92 日分の「日付・曜日・セッション数」の表を AI に渡し、頼み方だけを変えて 3 回答えさせました。使ったのは Claude Sonnet 5.5 で、各頼み方 1 回だけです。コード実行や電卓は使わせず、表を読んだ暗算で答えさせました。
答えたのは、この記事の調査を担当した AI 自身です。SQL の基準を計算する前に、同じ作業の中で表だけを見て答えたもので、頼み方ごとに新しい会話で聞いたわけではありません。
P1:「おかしな日を挙げて」だけ
次は、ある EC サイトの日別セッション数です(日付, 曜日, セッション数)。
おかしな日を挙げてください。(表を貼る)
AI は 10 日を挙げました。答えの一部を原文のまま載せます。
- 2020-12-08(7,522。表の中で最大で、前後の日より突出しています)
- 2020-12-25(2,623。クリスマスで低いです)
- 2020-11-08(2,132。表の中で最小です)
12 月上旬はセールなどの施策、年末年始は休日の影響が考えられます。
挙げた 10 日は、12-08・12-09・01-06・11-03・12-25・12-26・12-27・01-01・11-08・11-15 です。原因の説明(セール・クリスマス)は AI の推測で、公開データからは確かめられません。
P2:「基準と計算の途中を書いて」
次は、ある EC サイトの日別セッション数です(日付, 曜日, セッション数)。
外れた日を挙げてください。どんな基準で外れたと判断したのか、
平均などの計算の途中も書いてください。(表を貼る)
答えの一部を原文のまま載せます。
計算の途中: 92 日のセッション数の平均はおよそ 3,900、標準偏差はおよそ 1,050 です(暗算による概算です)。 範囲: 3,900 ± 2 × 1,050 = およそ 1,800〜6,000 です。 2021-01-06(5,951)は上限にわずかに届かないため、外れた日には含めません。
AI は「平均 ± 2 標準偏差」を自分で選び、12-08 と 12-09 の 2 日を挙げました。
P3:「同じ曜日どうしで比べて」
次は、ある EC サイトの日別セッション数です(日付, 曜日, セッション数)。
週末は平日より少ないので、同じ曜日どうしで比べて外れた日を挙げてください。
曜日ごとの平均と、外れたと判断した基準も書いてください。(表を貼る)
答えの一部を原文のまま載せます。
- 2020-12-07(月。5,409。月曜の平均 3,900 より 1,500 高く、標準偏差の 2 倍を超えます)
- 2020-12-25(金。2,623。金曜の平均 3,900 を大きく下回ります) 土曜と日曜は、低い日(2,132〜2,700 台)もすべて土日の中の通常の幅に収まるため、外れた日には含めません。
AI は 12-08・12-07・12-25・01-01 の 4 日を挙げました。
検算:SQL の基準で外れた日と何日一致したか
SQL で 3 つの基準を計算する
正解の側は、3 つの基準を SQL で計算しました。下の SQL は、筆者が実行した問い合わせの式(STDDEV_SAMP、PERCENTILE_CONT、曜日ごとの PARTITION BY)を、読者が貼って動かせる形に書き直したものです。書き直した全文も実行し、次の節の 4 日と z 値が同じになることを確かめました。
WITH daily AS (
SELECT PARSE_DATE('%Y%m%d', event_date) AS d,
COUNT(DISTINCT IF(event_name='session_start', CONCAT(user_pseudo_id, CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key='ga_session_id') AS STRING)), NULL)) AS sessions
FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`
GROUP BY d
),
s AS (
SELECT d, FORMAT_DATE('%a', d) AS dow, sessions,
AVG(sessions) OVER () AS m,
STDDEV_SAMP(sessions) OVER () AS sd,
PERCENTILE_CONT(sessions, 0.25) OVER () AS q1,
PERCENTILE_CONT(sessions, 0.75) OVER () AS q3,
AVG(sessions) OVER (PARTITION BY EXTRACT(DAYOFWEEK FROM d)) AS wm,
STDDEV_SAMP(sessions) OVER (PARTITION BY EXTRACT(DAYOFWEEK FROM d)) AS wsd
FROM daily
)
SELECT d, dow, sessions,
ABS(sessions - m) > 2 * sd AS c1_sd,
(sessions < q1 - 1.5 * (q3 - q1) OR sessions > q3 + 1.5 * (q3 - q1)) AS c2_iqr,
ABS(sessions - wm) > 2 * wsd AS c3_wk,
ROUND((sessions - m) / sd, 2) AS z_global,
ROUND((sessions - wm) / wsd, 2) AS z_wk
FROM s
WHERE ABS(sessions - m) > 2 * sd
OR sessions < q1 - 1.5 * (q3 - q1)
OR sessions > q3 + 1.5 * (q3 - q1)
OR ABS(sessions - wm) > 2 * wsd
ORDER BY d
z_global と z_wk は z 値(平均から標準偏差何個分離れているか)です。絶対値が 2 を超えると、基準 (1) や (3) で外れた日になります。
基準の境界値と、外れた日
境界値は次のとおりです。筆者は同じ日別の表を Node.js で計算し直し、すべての値が SQL の結果と一致することも確かめました。
| 基準 | 下限 | 上限 | 外れた日数 |
|---|---|---|---|
| (1) 平均 3,857.1 ± 2 × 999.7 | 1,857.7 | 5,856.6 | 3 日 |
| (2) Q1 3,200 / Q3 4,343.25 | 1,485.1 | 6,058.1 | 2 日 |
| (3) 曜日別(例: 月曜) | 2,598.5 | 5,282.0 | 2 日(全曜日の合計) |
図 1 の 92 日分の値は、前の節の SQL で再現できます。図 1 のとおり、外れた日はすべて上側でした。下限を下回った日はどの基準にもなく、92 日で最も少ない日は 2020-11-08 の 2,132 でした。
| 日付 | セッション数 | (1) | (2) | (3) | 全体の z | 曜日別の z |
|---|---|---|---|---|---|---|
| 12-07(月) | 5,409 | 外れない | 外れない | 外れた | 1.55 | 2.19 |
| 12-08(火) | 7,522 | 外れた | 外れた | 外れた | 3.67 | 2.69 |
| 12-09(水) | 6,207 | 外れた | 外れた | 外れない | 2.35 | 1.85 |
| 01-06(水) | 5,951 | 外れた | 外れない | 外れない | 2.09 | 1.57 |
(1)〜(3) は上の表の基準の番号です。12-09 は全体で比べると外れますが、水曜どうしで比べると外れません。12-07 は逆に、全体では外れず、月曜どうしで比べると外れます。
同じ表でも、基準を全体の平均から曜日別に変えるだけで、外れた日が入れ替わります。AI の答えを確かめるときは、AI がどの基準を使ったかを先に知る必要があります。
頼み方 3 × 基準 3 の突き合わせ
AI が挙げた日と、基準で外れた日を突き合わせました。適合率は「AI が挙げた日のうち、基準でも外れていた日の割合」、再現率は「基準で外れた日のうち、AI が挙げた日の割合」です。
| 頼み方 | 基準 | 適合率 | 再現率 |
|---|---|---|---|
| P1 おかしな日 | (1) 標準偏差 | 3/10 = 30% | 3/3 = 100% |
| P1 おかしな日 | (2) 四分位 | 2/10 = 20% | 2/2 = 100% |
| P1 おかしな日 | (3) 曜日別 | 1/10 = 10% | 1/2 = 50% |
| P2 基準と途中 | (1) 標準偏差 | 2/2 = 100% | 2/3 = 67% |
| P2 基準と途中 | (2) 四分位 | 2/2 = 100% | 2/2 = 100% |
| P2 基準と途中 | (3) 曜日別 | 1/2 = 50% | 1/2 = 50% |
| P3 同じ曜日 | (1) 標準偏差 | 1/4 = 25% | 1/3 = 33% |
| P3 同じ曜日 | (2) 四分位 | 1/4 = 25% | 1/2 = 50% |
| P3 同じ曜日 | (3) 曜日別 | 2/4 = 50% | 2/2 = 100% |
筆者が、筆者の実行した問い合わせの結果と AI の答えから計算しました。分母は 2〜10 日と小さいので、割合だけでなく分数で読んでください。
図 4 と上の表のとおり、全体の平均で比べた P2 は、全体の基準 (1)(2) との一致が多くなりました。曜日どうしで比べた P3 は、曜日別の基準 (3) との一致が多くなりました。比べ方の範囲(全体か、同じ曜日か)が同じ基準と、答えがそろう傾向が見られました(各 1 回の結果です)。
曜日別の基準で見ると、何が変わったか
図 2 の値は、上の 9 通りの表の「(3) 曜日別」の 3 行と同じです。図 2 のとおり、「同じ曜日どうしで」と頼むと、曜日別の基準で外れた 2 日(12-07・12-08)をどちらも拾えました。ただし適合率は P2 と同じ 50% で、上がったのは再現率だけです。
P3 が挙げた 12-25(2,623)と 01-01(2,289)は、金曜の下限 2,135.4 より上で、基準では外れていませんでした。
1 つのモデルで各 1 回だけ試した結果なので、「曜日で比べると精度が上がる」とまでは言えません。言えるのは、頼み方を変えると AI が採る基準が変わり、どの基準と一致するかも変わる、ということです。
暗算の丸めが、境目の日を動かした
P2 の AI は、平均を約 3,900、標準偏差を約 1,050 と概算し、上限を約 6,000 としました。実際の上限は 5,856.6 です。2021-01-06 の 5,951 は実際の上限を約 94 上回っていましたが、AI の概算の上限には届かず、外されました。
P2 が四分位の基準と 100% / 100% で一致したのは、偶然と考えられます。AI が名乗った基準は標準偏差で、丸めた上限 6,000 が、たまたま四分位の上限 6,058.1 に近かったためです。
つまずきやすい点:週末の落ち込みや祝日を異常と数える
「低い日」は、全体で見ても曜日で見ても外れていなかった
P1 が挙げた 10 日のうち、どの基準でも外れていない 7 日の内訳は、土日 4 日、金曜 2 日(12-25・01-01)、火曜 1 日(11-03)でした。低い側で挙げた 6 日の z 値は、全体で −1.21〜−1.73、曜日別で −0.50〜−1.82 で、どれも −2 に届きません(筆者が日別の表から計算)。
曜日ごとの平均は、火曜が 4,602.0 で最も高く、日曜が 2,857.6 で最も低い値でした。この差は、全体の標準偏差 999.7 の約 1.7 倍あります(筆者計算)。週末の少なさは毎週くり返す「ふつうの変動」なので、全体の平均と比べて「低い」と言うだけでは、外れた日の根拠になりません。
AI が祝日や週末を「おかしな日」に挙げたときは、同じ曜日の平均と標準偏差を出して、z 値が 2 を超えるかを確かめてください。今回は、AI が挙げた低い日のうち、この条件を満たす日は 1 日もありませんでした。
標本か母集団かで、境目の日が変わることがある
STDDEV は標本標準偏差を返し、STDDEV_POP は母集団標準偏差を返します(BigQuery の統計集計関数)。今回の 92 日では、母集団の標準偏差は 994.3 で、上限は 5,845.7 になりました(筆者計算)。外れた日は同じ 3 日で、結果は変わりませんでした。
ただし、日数が少ない表や境目ぎりぎりの日がある表では、どちらで割るかで判定が変わる可能性があります。AI に頼むときも、SQL を書くときも、どちらを使ったかを書いておくと検算が速くなります。
外れた理由は、データだけでは分からない
12 月上旬の急増について、AI は「セールなどの施策」と推測しました。しかし、公開データには施策の記録がないため、この推測は確かめられません。外れた日を見つけることと、その理由を説明することは、別の作業として扱ってください。
検算しやすい頼み方のひな形
ここまでの結果から、検算しやすい答えをもらうための頼み方をまとめます。ポイントは、AI に基準と境界値を数字で書かせることです。
次は、ある EC サイトの日別セッション数です(日付, 曜日, セッション数)。
外れた日を挙げてください。条件は次のとおりです。
1. 基準は「同じ曜日の平均 ± 2 標準偏差(標本標準偏差)」とする
2. 曜日ごとに、日数・平均・標準偏差・下限・上限を表で書く
3. 外れた日ごとに、その曜日の z 値を書く
4. 境界値の計算に自信がない日は「境目」と書いて分ける
5. 外れた理由の推測は書かない
(表を貼る)
AI が返した境界値の表は、上の SQL の s から曜日ごとの wm と wsd を取り出して、並べて比べます。曜日ごとの境界値が合えば、外れた日の判定もそろうはずです。
図 3 の順番で確かめると、AI の答えのどこがずれたかを切り分けられます。
- AI に表を貼り、外れた日と理由を挙げてもらう
- 基準と境界値を数字で書かせる
- 同じ基準を SQL で計算し、境界値と日付を比べる
- 曜日どうしの基準でも計算し直し、入れ替わる日を確かめる
AI に外れた日を頼むときは、基準と境界値を数字で書かせ、同じ基準を SQL で計算して突き合わせてください。基準が書かれていない答えは、正しいか間違いかを判定できないためです。
SQL そのものを AI に書かせる場合の検算は、AI に書かせた GA4 の BigQuery SQL を検算した記事 で扱っています。表の合計や割合を AI に計算させるときの検算は、集計表の計算を行数別に検算したプロンプト集 が参考になります。
今回の条件と、確かめていないこと
- AI は Claude Sonnet 5.5 の 1 モデルで、各頼み方 1 回だけです。他のモデルや、くり返したときのばらつきは確かめていません。
- 答えは、記事の調査を担当した AI が、同じ作業の中で表だけを見て作ったものです。頼み方ごとに新しい会話で聞いたわけではなく、答えた AI は頼み方を比べる狙いを知っていました。読者がチャットに表を貼って同じ頼み方をしても、同じ日が挙がるとは限りません。
- AI にはコード実行を許していません。コードを実行できる AI なら、P2 の丸めのずれは起きない可能性がありますが、試していません。
APPROX_QUANTILESの近似の誤差の大きさは、公式ページから数値で確認できませんでした。- 売上と購入数の外れた日は計算していません。
同じ日別の表を使って、AI の予測を実績で確かめた記録は、AI に来月のセッション数を予測させて実績で検算した記事 にまとめています。
まとめ
- 「おかしな日を挙げて」だけでは、AI が挙げた 10 日のうち 7 日がどの基準でも外れていませんでした。低い日として挙げた日は、z 値がどれも −2 に届きませんでした。
- 基準を全体から曜日別に変えると、外れた日が入れ替わります(12-09 と 12-07)。全体で比べた答えは全体の基準と、曜日で比べた答えは曜日別の基準と一致が多くなりました。
- 検算しやすいのは、基準と境界値を数字で書かせる頼み方です。同じ基準を SQL で計算して、境界値と日付を突き合わせてください。
次にやること
外れた日を毎週の数字の中でどう見せるかは、ダッシュボードの一覧で、公開データから作った例をご覧ください。外れた日を判定する SQL が基準どおりか、第三者の目で確かめたい場合は、BigQuery SQL レビューパックもご利用いただけます。
参考にした一次情報
- Google for Developers: Google アナリティクス 4 の BigQuery サンプル データセット(ウェブ e コマース)(2026-11-14 確認)
- Google アナリティクス ヘルプ: BigQuery Export スキーマ(2026-11-14 確認)
- Google Cloud: BigQuery の統計集計関数(STDDEV・STDDEV_SAMP・STDDEV_POP)(2026-11-14 確認)
- Google Cloud: BigQuery の近似集計関数(APPROX_QUANTILES)(2026-11-14 確認)