外れ値を見つける
このレッスンでできるようになること。記述統計と条件式で突出した売上日を見つけ、その理由を推測できるようになります。
平均から大きく離れた値を外れ値と呼びます。外れ値には2つの顔があります。1つは間違いです。単位を取り違えた入力、桁の打ち間違い、テストデータの混入。もう1つは事実です。セールの日、テレビで紹介された日、法人からのまとめ買い。どちらなのかを判断するのが分析者の仕事で、機械が決めることではありません。
見つけ方はいくつかありますが、まずは平均と標準偏差を使う方法を覚えます。標準偏差は、値が平均からどれくらいばらついているかを表す数字です。describe を呼べばまとめて出ます。
Python
daily = df.groupby("売上日")["金額"].sum().sort_index()
mean = daily.mean()
std = daily.std()
high = daily[daily > mean + 2 * std]平均から標準偏差2つ分より外側を外れ値とみなす、というのがよく使われる線引きです。この2という数字に絶対的な根拠はありません。分布の形によっては厳しすぎたり緩すぎたりします。だからこそ、なぜその線を引いたのかを説明できるようにしておきます。
注意すべき点があります。平均も標準偏差も、外れ値そのものに引っ張られます。極端な1日があると平均が上がり標準偏差も大きくなるので、その日自身が外れ値と判定されにくくなります。これを避けたいときは、中央値と四分位範囲を使う方法に切り替えます。中央値は極端な値に動かされないので、より頑丈な線引きになります。
見つけたあとが本番です。外れ値を機械的に消してはいけません。まず日付を見ます。年末やセールの日なら事実である可能性が高いです。金額の桁を見ます。他の日の10倍を超えているなら入力ミスを疑います。同じ日に同じ商品の行が大量にあるなら、まとめ買いか二重計上かを確かめます。二重計上は3章の drop_duplicates で落としたはずですが、日付だけが1日ずれている重複は残ります。
判断したら、レポートには対処と理由を書きます。「12月24日の売上は平均の3倍だったが、年末商戦によるもので実在の売上と判断し、集計に含めた」。この一文があるかどうかで、レポートの信頼度は大きく変わります。数字を出すことより、数字をどう扱ったかを説明することのほうが、実務では重く見られます。
要件
- 売上日ごとに 金額 を集計してから統計量を求める
- 平均は mean、標準偏差は std を使う
- 閾値は 平均 + k × 標準偏差 とする
- 閾値より大きい日だけを外れ値とする(閾値と等しい日は含めない)
- float はすべて round(..., 1) で丸めて返す
入出力例
detect_outliers("売上日,店舗,商品名,カテゴリ,数量,金額
2026-12-22,渋谷店,白磁のマグカップ,食器,5,10000
2026-12-23,横浜店,鉄のフライパン,調理器具,2,12000
2026-12-24,渋谷店,鋳物ホーロー鍋,調理器具,4,60000
2026-12-25,大宮店,積み重ね収納ボックス,収納,7,11000
2026-12-26,横浜店,布製収納バスケット,収納,6,9000
", 1.5) → {"mean":20400,"outlier_dates":["2026-12-24"],"ratio":2.9,"threshold":53647.9}
detect_outliers("売上日,店舗,商品名,カテゴリ,数量,金額
2026-05-01,渋谷店,白磁のマグカップ,食器,3,5000
2026-05-02,横浜店,白磁のマグカップ,食器,3,5200
2026-05-03,大宮店,布製収納バスケット,収納,3,4800
2026-05-04,渋谷店,木製カッティングボード,調理器具,1,5100
", 2) → {"mean":5025,"outlier_dates":[],"ratio":0,"threshold":5366.6}