論文一覧に戻る 📚 用語解説(ジャストインタイム型データサイエンス教育)
外れ値
Outlier
他のデータから著しく離れた値。相関係数や平均を大きく歪めることがあり、必ず散布図で確認すべき。
データ前処理異常値outliers
📍 文脈💡 30秒結論📖 詳しく

📍 あなたが今見ているもの

論文中に 「外れ値」として登場する用語。

外れ値 とは:他のデータから著しく離れた値。相関係数や平均を大きく歪めることがあり、必ず散布図で確認すべき。

💡 30秒で分かる結論

📖 もっと詳しく

外れ値(outlier)は、 他のデータから著しく離れた値です。 47都道府県データなら、 東京(人口密度が突出)沖縄(独自の人口構成) がしばしば外れ値として浮上します。

外れ値の正体は3パターン:(i) 入力ミス・測定エラー(除外すべき)、 (ii) システム的なエラー(要修正)、 (iii) 本当に特異な実体(東京、 沖縄 etc.、 重要な情報源)。 (iii) を機械的に除外するのは分析の改ざんに近い禁じ手です。

影響:外れ値は平均・分散・相関係数・回帰係数を強く歪めます。 一方で中央値・順位相関は外れ値に影響されにくい(ロバスト統計量)。

検出と対処:(i) 散布図と箱ひげ図で必ず可視化、 (ii) Tukey の基準(Q1−1.5·IQR より下、 Q3+1.5·IQR より上)、 (iii) Spearman 順位相関で頑健性を確認、 (iv) 外れ値含む結果と除外した結果の両方を提示する。

🎨 直感で掴む — 外れ値とは「群れから離れた星」

SSDSE-B-2026 の 47 都道府県人口を縦軸にプロットすると、 46 県は約 55 万〜400 万人の帯にまとまり、 東京都だけが 1,392 万人と「群れから離れた星」のように夜空に浮きます。 これが外れ値の典型像。「群れの位置(中央値)」と「群れの広がり(IQR)」を物差しにし、 そこから 1.5 倍以上離れている星を外れ値とみなす、 というのが Tukey の定義です。 ヒストグラムでは群れが山に、 外れ値が右端の小さな突起になります。

大事なのは「離れている=排除」ではない、 という思考。 東京の人口は誤入力ではなく真実です。 集計に含めると平均人口が約 265 万人と膨らみますが、 中央値 190 万人なら東京がいても揺らぎません。 つまり「平均派(外れ値の影響を受ける)」と「中央値派(影響を受けない)」を使い分けるのが、 外れ値時代の分析家の作法です。

📐 定義・数式 — 3 つの外れ値基準

  1. z-score 基準(正規分布前提):$z_i = (x_i - \bar{x}) / s$ で $|z_i| > 3$ を外れ値とみなす。
  2. Tukey IQR 基準(分布フリー):$x_i < Q_1 - 1.5 \cdot \text{IQR}$ または $x_i > Q_3 + 1.5 \cdot \text{IQR}$。 ただし IQR $= Q_3 - Q_1$。
  3. 修正 z-score (MAD 基準・ロバスト):$z^*_i = 0.6745 \cdot (x_i - \tilde{x}) / \text{MAD}$、 $\text{MAD} = \text{median}(|x_i - \tilde{x}|)$。 $|z^*_i| > 3.5$ を外れ値。
  4. 多変量:Mahalanobis 距離:$d^2_i = (\mathbf{x}_i - \boldsymbol{\mu})^\top \Sigma^{-1} (\mathbf{x}_i - \boldsymbol{\mu})$。 $\chi^2_{p, 0.975}$ 超で外れ値。

SSDSE-B-2026 の人口データは右に強く歪むため、 1 と 2 は東京を確実に拾うが地方の異常検出には甘い。 3 は中央値・MAD ベースで歪みに頑健、 4 は複数指標を組み合わせる際の標準。

🔬 数式を言葉で読み解く — 記号 → 意味

記号意味SSDSE-B-2026 での具体例
$\bar{x}, s$標本平均と標本標準偏差A1101 の 47 県平均 ≈ 264 万人、 SD ≈ 300 万人
$\tilde{x}$中央値(外れ値に頑健)A1101 の中央値 ≈ 190 万人(岐阜・福島あたり)
$Q_1, Q_3, \text{IQR}$第 1 ・第 3 四分位とその差A1101 で IQR ≈ 200 万人。 1.5×IQR ≈ 300 万人
MAD中央絶対偏差(ロバスト SD 代替)A1101 の MAD ≈ 95 万人。 ×0.6745 で SD 相当に正規化
$\Sigma$共分散行列(多変量の広がり)食料費・教育費・住居費の (3,3) 行列

読み方:「中央 ($\tilde{x}, Q$) からどれだけ離れているか」を「広がり (IQR, MAD)」で割って、 規格化された距離で判断する、 が外れ値検出の本質です。

📖 包括的解説 — この概念を完全マスター

📍 学習の3ステップ

  1. 定義を理解する:この概念は何か? 数式や条件を確認
  2. 具体例を見る:実データ(SSDSE 等)で計算してみる
  3. 応用する:自分のデータに適用、 結果を解釈

🔧 Python実装パターン

🎯 目的:SSDSE-B-2026 を読み込み、 describe() で外れ値判定の基本指標(平均・SD・四分位)を一望し、 さらに sns.pairplot で食料費・教育費・住居費の三対角散布図を眺めて視覚的に異常県を見つける。
📥 入力data/raw/SSDSE-B-2026.csv (CP932 エンコード、 47 都道府県 × 複数年度)。 注目列:食料費・教育費・住居費(家計支出系)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 基本パターン
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns

# データ読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')

# 基本統計量
df.describe()

# 可視化
sns.pairplot(df[['食料費', '教育費', '住居費']])
plt.show()
📤 出力 df.describe() 食料費 教育費 住居費 count 47.00 47.00 47.00 mean 82340.5 12450.7 22890.1 std 12534.2 3245.6 7891.4 min 63200.0 7100.0 14500.0 25% 73900.0 10200.0 18700.0 50% 80600.0 12100.0 21400.0 75% 89100.0 13800.0 25600.0 max 128000.0 24800.0 58200.0 ← 東京は 4 大都市圏で右肩離れ
💬 解釈:3 つの家計支出すべてで max が 75% 点の 1.5×IQR 超え。 特に住居費は 58,200 円(東京)と 14,500 円(地方)の差が約 4 倍に達する。 pairplot で 3 変数の散布図を一覧すると、 「住居費だけ突出する県」「教育費 × 食料費の二次元で外れる県」が浮かび上がる。

📚 統計概念マップでの位置

このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 関連手法を辿って学習を進めましょう。

🎯 SSDSE-B-2026 で挑戦

統計データ活用コンペティションのSSDSE-B-2026データは、 47都道府県の社会経済データ。 この概念を使って以下のような分析ができます:

💡 よく使うコマンド集

機能 Python (pandas) Python (scipy)
要約統計df.describe()stats.describe()
平均df.mean()np.mean()
標準偏差df.std()np.std()
相関df.corr()stats.pearsonr()
t検定stats.ttest_ind()
回帰stats.linregress()
分布フィッティングstats.norm.fit()

🚧 一般的な落とし穴と対策

📊 結果報告の標準フォーマット

🌐 関連分野での応用

🎓 さらに学ぶための文献

🔗 統計用語ネットワーク

この概念は、 他の多くの統計概念と密接に関連しています。 ジャストインタイム型学習では、 必要に応じて関連用語へジャンプしながら全体像を構築します。

主要な関連概念のグループ

グループ 主要概念
記述統計平均、 中央値、 最頻値、 分散、 標準偏差、 共分散、 相関係数
可視化ヒストグラム、 散布図、 箱ひげ図、 ヒートマップ
推測統計標本平均、 標準誤差、 信頼区間、 p値、 有意水準
確率分布正規分布、 t分布、 χ²分布、 F分布、 二項分布
仮説検定t検定、 F検定、 χ²検定、 ノンパラ検定
回帰単回帰、 重回帰、 OLS、 Ridge、 LASSO
分類ロジスティック回帰、 決定木、 SVM、 k-NN
教師なし学習クラスタリング、 PCA、 因子分析
時系列ARIMA、 VAR、 指数平滑法、 自己相関
因果推論DiD、 IV、 傾向スコア、 交絡変数
前処理標準化、 正規化、 欠損値処理、 多重共線性対策
評価R²、 残差、 CV、 RMSE、 効果量

学習順序の推奨

  1. 記述統計(平均、 分散、 標準偏差)
  2. 可視化(ヒストグラム、 散布図)
  3. 確率分布(正規分布)
  4. 推測統計(標準誤差、 信頼区間、 p値)
  5. 仮説検定(t検定、 χ²検定)
  6. 相関と回帰(単回帰、 重回帰)
  7. 多変量解析(PCA、 クラスタリング)
  8. 機械学習(決定木、 RF、 NN)
  9. 時系列・因果推論(応用)

📝 実践練習 — SSDSE-B-2026 で挑戦

初級課題

  1. 東北6県の家計食料費の基本統計量を計算
  2. 食料費のヒストグラムを描く
  3. 食料費と教育費の散布図を描く
  4. 都道府県を「東日本/西日本」に分け、 平均を比較

中級課題

  1. 家計支出 5項目で相関行列を作成、 ヒートマップ可視化
  2. 食料費 → 教育費の単回帰を実行、 残差分析
  3. 家計5項目で PCA を実施、 バイプロット表示
  4. k-means (k=3) で都道府県をクラスタリング、 解釈

上級課題

  1. 地域別の家計パターンに有意差があるか ANOVA で検定
  2. 重回帰で教育費を予測、 多重共線性を VIF で確認
  3. Ridge/LASSO で正則化、 CV で α を最適化
  4. 階層クラスタリングと Ward 法で都道府県を分類、 デンドログラム作成

📚 統計学習の総合ガイド

🎯 学習目標

このページの概念をマスターすることで、 以下のスキルが身につきます:

📊 SSDSE-B-2026 データの構造

このコンペの主要データセット(SSDSE-B-2026)の構造:

🔍 主要な変数群

カテゴリ 変数例
人口総人口、 年齢別人口、 性別人口
人口動態出生数、 死亡数、 合計特殊出生率、 婚姻数
気候気温、 降水量、 降水日数
教育幼小中高校数、 教員数、 生徒数、 大学進学率
経済求職件数、 求人件数、 旅館数
医療病院数、 診療所数、 歯科診療所
家計消費支出、 食料費、 住居費、 教育費等の項目別

💡 ジャストインタイム型学習

このガイドは「必要なときに必要な知識」を提供する設計:

🛠️ Python データサイエンス環境

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 必須ライブラリのインストール
pip install pandas numpy scipy statsmodels scikit-learn matplotlib seaborn

# 標準的なインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error

# 日本語表示の設定(matplotlib)
plt.rcParams['font.family'] = 'Hiragino Sans'
plt.rcParams['axes.unicode_minus'] = False

# データ読み込み(SSDSE は cp932 エンコーディング)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
print(df.shape)
print(df.head())
print(df.describe())

🌟 効果的なEDAテンプレート

🎯 目的:SSDSE-B-2026 を渡すだけで「形状・型・欠損・基本統計・ヒストグラム・相関ヒートマップ・散布図行列」を一気に出す再利用可能な quick_eda 関数を定義。 外れ値検出の前段階としての EDA を高速化する。
📥 入力:DataFrame、 オプションで target 列名。 内部で数値列を自動抽出し、 5 列まで pairplot を生成。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def quick_eda(df, target=None):
    """探索的データ分析の基本テンプレート"""
    print(f"Shape: {df.shape}")
    print(f"\nColumn types:\n{df.dtypes}")
    print(f"\nMissing values:\n{df.isnull().sum()}")
    print(f"\nBasic stats:\n{df.describe()}")

    # 数値列の可視化
    numeric_cols = df.select_dtypes(include=[np.number]).columns
    df[numeric_cols].hist(bins=20, figsize=(15, 10))
    plt.tight_layout()
    plt.show()

    # 相関ヒートマップ
    if len(numeric_cols) > 1:
        plt.figure(figsize=(12, 10))
        sns.heatmap(df[numeric_cols].corr(), annot=True, fmt='.2f',
                    cmap='RdBu_r', center=0)
        plt.show()

    # ターゲットがあれば散布図行列
    if target and target in df.columns:
        sns.pairplot(df[numeric_cols[:5]], hue=target if df[target].dtype == 'O' else None)
        plt.show()
📤 出力 quick_eda(df, target='都道府県') Shape: (47, 50) Column types: 都道府県 object 食料費 int64 教育費 int64 住居費 int64 ... Missing values: 食料費 0 教育費 0 ... (ヒストグラム・相関ヒートマップ・散布図行列が表示)
💬 解釈:相関ヒートマップで「住居費 ⇄ 教育費 ⇄ 食料費」の関係を一望、 ヒストグラムで分布の歪み(右尾)を確認、 pairplot で外れ値の所属象限を視認できる。 外れ値検出の前に分布形を理解しておくと、 後で z / IQR / Mahalanobis のどれを使うべきか判断しやすい。

📈 報告書テンプレート

分析結果を報告する際の標準的な構成:

  1. 背景・目的:なぜこの分析が必要か
  2. データ:出所、 サンプルサイズ、 期間
  3. 方法:使用した統計手法、 仮定
  4. 結果:図表、 統計量、 検定結果
  5. 解釈:結果が何を意味するか
  6. 限界:分析の制約
  7. 結論:要点まとめ、 今後の課題

🗺️ 統計手法選択フローチャート

Q1: 何を知りたい?

Q2: データの種類は?

Q3: サンプルサイズは?

Q4: 仮定は?

📏 効果量の参照表

p値だけでなく効果量も併記するのが現代統計の標準。 主要な指標と Cohen の解釈基準:

統計量 効果量
2群平均差Cohen's d0.20.50.8
相関r0.10.30.5
線形回帰0.020.130.26
ANOVAη² (eta²)0.010.060.14
χ²Cramér's V0.10.30.5
ロジスティックOdds Ratio1.52.54.0

🗺️ 概念マップ — 3つの視点で体系を理解する

外れ値 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。

📍 体系階層のパス

🌐 体系階層に未登録

① 🔗 関係マップ — 「他の手法とどう繋がっているか」

中心の概念から放射状に、 前提・兄弟・発展形・応用先などの関係性を矢印で結びます。 横の繋がりを見るのに最適。 ノードをドラッグ、 ホイールでズーム、 クリックで遷移

凡例:現在の用語上位カテゴリ兄弟(並列)前提発展形応用先2階層先

② ⭕ 包含マップ — 「どのカテゴリに含まれているか」

大きな円が小さな円を包含する Circle Packing 図。 「外れ値」は緑色でハイライト

📍現在地:統計・データサイエンス

③ 🌳 ツリーマップ — 「面積で見るボリューム比較」

長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「外れ値」は緑色でハイライト

🎯 3つのマップの使い分け

マップ 分かること こんな時に見る
🔗 関係マップ手法間の横の関係(前提→発展→応用)「次に何を学べばよい?」 学習順序の判断
⭕ 包含マップ分類体系の入れ子構造(上位⊃下位)「この手法はどんなジャンルに属する?」
🌳 ツリーマップ分野の規模比較(面積=ボリューム)「データサイエンス全体の俯瞰像」

💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。

🔖 キーワード索引 — この用語を多角的に理解する

外れ値(outlier)を理解するための関連キーワードを、難易度・カテゴリで整理しました。学習順序の参考にしてください。

🟢 基礎キーワード(まず押さえる)

🟡 中級キーワード(応用で必要)

🔴 上級キーワード(研究・実務の先端)

🧮 SSDSE-B-2026 実値計算例 — 47 都道府県データで外れ値を炙り出す

ここでは合成データではなく、SSDSE-B-2026 のような公的統計を念頭に「人口」「人口密度」「県内総生産」など実データで外れ値を見つける手順を、具体的な数値で示します。

① 人口(2020 年国勢調査・47 都道府県)の外れ値判定

47 都道府県の人口(単位:万人、 概算値)をソートすると:

Tukey の基準で外れ値を計算:

# Q1 ≈ 78(25%点:佐賀のあたり)
# Q3 ≈ 200(75%点:京都のあたり)
# IQR = Q3 - Q1 = 122
# 上限 = Q3 + 1.5 × IQR = 200 + 183 = 383
# 下限 = Q1 - 1.5 × IQR = 78 - 183 = -105 → 0 以下なので意味なし

外れ値の判定:人口 > 383 万人の都道府県
 → 東京(1404)、 神奈川(924)、 大阪(884)、 愛知(755)、 埼玉(734)、 千葉(628)、 兵庫(547)、 北海道(522)、 福岡(513)
 → 9 都道府県が「外れ値」

解釈:都市圏 9 都道府県が統計的に「外れ値」と判定されますが、これらは除外すべきではない真の特異点です。この場合、対数変換 log₁₀(人口) を施せば多くの都道府県が中央に収まり、外れ値は東京のみ(log₁₀ 1404 ≈ 7.15、 全体平均 ≈ 6.0)に縮減されます。

② Z スコアによる「人口密度」の外れ値(東京の極端さ)

|Z|>3 の基準では、 東京・大阪が外れ値と判定されます。ただし、平均と標準偏差が東京自体に強く引きずられているため、 MAD ベースの修正 Z スコアで再計算すると東京の特異性がさらに鮮明になります。

③ 修正 Z スコア(MAD ベース)の例

1
2
3
4
5
6
7
8
9
# 人口密度 47 値の中央値 ≈ 240 人/km²(島根 県あたり)
# MAD = median(|xᵢ - 240|) ≈ 130
# 修正Z = 0.6745 × (xᵢ - 240) / 130

東京0.6745 × (6400 - 240) / 130  +31.9
大阪0.6745 × (4640 - 240) / 130  +22.8
神奈川0.6745 × (3820 - 240) / 130  +18.6

 修正Z >> 3.5 を遥かに超える強烈な外れ値が浮上

MAD ベースの基準は、平均と標準偏差が外れ値自体に引きずられる問題を回避できます。外れ値の特異性を強く検出したいときに有効です。

④ 相関係数への影響:外れ値除外前後の比較

仮想的に「人口密度 vs 1 人当たり県民所得」を取った場合:

このように、 1〜数個の外れ値が相関係数を 0.2〜0.3 ポイント動かすことは珍しくありません。 Spearman 順位相関を併記すれば、 順位ベースなのでこの種の歪みに頑健です。

⚠️ 外れ値の落とし穴 — 実務で必ず引っかかるポイント 7 選

① 「外れ値 = 除去すべき」と短絡してしまう

初学者が最も陥りやすい誤解です。外れ値には (i) 入力ミス、 (ii) 測定エラー、 (iii) 真に特異な現象、 の 3 種があり、 (iii) を機械的に除外することは 分析の改ざんに近い禁じ手 です。47 都道府県データで東京を除外すれば、 確かに数値は綺麗になりますが、 それは「日本」を分析していると言えるでしょうか。外れ値の正体を診断し、 含めた結果と除外した結果の両方を提示するのが正しい姿勢です。

② Tukey の基準(±1.5·IQR)を絶対視する

「Q1 − 1.5·IQR より下、 Q3 + 1.5·IQR より上」は教科書的な目安ですが、 正規分布なら片側 0.35% 程度しか外れ値が出ない設定で、 裾の重い分布(人口、 所得、 売上)では大量の「正常な外れ値」が誤検出されます。47 都道府県の人口で 9 個も外れ値が出るのはそのためです。分布の形を確認し、 対数変換やロバスト指標と組み合わせることが必須です。

③ 平均と標準偏差で外れ値を検出する循環参照

「|Z| > 3 を外れ値とする」とき、 平均と標準偏差そのものが外れ値の影響を受けています。たとえば東京を含む人口密度の平均は 660、 除外すると 540、 さらに大阪を除くと 450 と次々動きます。この循環を断ち切るのが 中央値と MAD です。修正 Z スコア(0.6745·(xᵢ − median)/MAD)は外れ値自身に汚染されない、 ロバストな検出基準です。

④ 多変量の外れ値を 1 変数ずつチェックして見落とす

各変数を単独で見ると正常範囲なのに、 組み合わせて見ると異常な点が存在します。 たとえば「身長 170cm、 体重 50kg」はそれぞれ普通でも、 組み合わせとして痩せ過ぎ気味。 多変量の外れ値検出には Mahalanobis 距離Isolation ForestLocal Outlier Factor など、 多変量空間での密度・距離を考慮する手法を使う必要があります。

⑤ レバレッジと外れ値を混同する

回帰分析では「Y 方向の外れ値(残差が大きい)」と「X 方向の外れ値(説明変数が極端)」は別物です。 後者をレバレッジと呼びます。 レバレッジが高くても残差が小さければ影響は小さく、 逆にレバレッジと残差の両方が大きい点が Cook の距離 で警告される「影響点(influential point)」です。 残差プロットだけでは見つかりません。

⑥ 「外れ値を除外して再分析」を繰り返す p-hacking

p 値が有意にならないと外れ値を 1 個除外、 まだなら 2 個目を除外、 ……という逐次的な外れ値削除は p-hacking の典型です。事前に「Tukey の基準 + IQR 1.5 倍」など除外ルールを宣言し、 結果が変わっても固守する。 もしくは外れ値を含む結果と除外した結果の両方を併記する。 こうした透明性が再現性のある分析の要です。

⑦ 時系列データの外れ値を独立サンプルとして扱う

時系列ではトレンド・季節性・自己相関を考慮せずに「平均 ± 3SD」を当てはめると、 トレンドの上昇局面が全部外れ値判定されたり、 季節ピークが見逃されたりします。 時系列の外れ値検出には STL 分解後の残差ARIMA の予測区間からの逸脱変化点検出(CUSUM、 PELT) など、 時間構造を扱う手法が必要です。

🐍 Python 実装のバリエーション — scipy / scikit-learn / statsmodels

外れ値検出には複数のライブラリが利用できます。 用途に応じて使い分けましょう。

① scipy.stats による Grubbs 検定・Z スコア

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
from scipy import stats

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig')
x = df['人口総数'].dropna()

# Z スコア(平均・標準偏差ベース)
z = stats.zscore(x)
outliers_z = x[abs(z) > 3]
print('Z スコア外れ値:', outliers_z.tolist())

# Grubbs 検定(最大外れ値を1つ検定)
# scipy には直接実装がないので手計算で
g = (x.max() - x.mean()) / x.std()
n = len(x)
t_crit = stats.t.ppf(1 - 0.05/(2*n), n-2)
g_crit = (n-1)/n**0.5 * (t_crit**2/(n-2+t_crit**2))**0.5
print(f'G統計量={g:.3f}, 棄却限界={g_crit:.3f}')
print('外れ値' if g > g_crit else '外れ値なし')

② scikit-learn の Isolation Forest(多変量・教師なし)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from sklearn.ensemble import IsolationForest
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig')
X = df[['人口総数', '人口密度', '県内総生産']].dropna()

# contamination は外れ値の想定割合
clf = IsolationForest(contamination=0.1, random_state=0)
clf.fit(X)
df_out = X.copy()
df_out['outlier'] = clf.predict(X)  # -1 = 外れ値、 1 = 正常
df_out['score']   = clf.decision_function(X)

print(df_out[df_out['outlier'] == -1].sort_values('score'))

③ scikit-learn の Local Outlier Factor(密度ベース)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from sklearn.neighbors import LocalOutlierFactor

lof = LocalOutlierFactor(n_neighbors=5, contamination=0.1)
labels = lof.fit_predict(X)
neg_score = -lof.negative_outlier_factor_  # 大きいほど外れ値らしい

result = X.copy()
result['LOF_label'] = labels
result['LOF_score'] = neg_score
print(result.sort_values('LOF_score', ascending=False).head(10))

④ statsmodels の影響量診断(回帰モデル用)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import statsmodels.api as sm

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig').dropna()
X = sm.add_constant(df[['高齢化率']])
y = df['死亡率']

model = sm.OLS(y, X).fit()
influence = model.get_influence()

# Cook の距離
cook_d = influence.cooks_distance[0]
# 標準化残差
std_resid = influence.resid_studentized_internal
# レバレッジ
leverage = influence.hat_matrix_diag

diag = pd.DataFrame({
    '都道府県': df['都道府県'].values if '都道府県' in df.columns else range(len(df)),
    'cook_d': cook_d,
    'std_resid': std_resid,
    'leverage': leverage,
})
print(diag.sort_values('cook_d', ascending=False).head(5))

# 警告閾値
n = len(df)
print(f'Cook閾値 4/n = {4/n:.4f}')
print(f'Leverage閾値 2p/n = {2*2/n:.4f}')

⑤ MAD ベースの修正 Z スコア(手実装・ロバスト版)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import numpy as np
import pandas as pd

def modified_zscore(x):
    med = np.median(x)
    mad = np.median(np.abs(x - med))
    return 0.6745 * (x - med) / mad if mad > 0 else np.zeros_like(x)

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig')
x = df['人口密度'].dropna().values
mz = modified_zscore(x)

names = df['都道府県'].dropna().values if '都道府県' in df.columns else np.arange(len(x))
result = pd.DataFrame({'都道府県': names, '人口密度': x, '修正Z': mz})
print(result[abs(result['修正Z']) > 3.5].sort_values('修正Z', key=abs, ascending=False))

⑥ One-Class SVM(半教師あり・滑らかな境界)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from sklearn.svm import OneClassSVM
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
Xs = scaler.fit_transform(X)

oc = OneClassSVM(gamma='auto', nu=0.1)
oc.fit(Xs)
labels = oc.predict(Xs)   # -1 = 外れ値
scores = oc.score_samples(Xs)

import pandas as pd
out = X.copy()
out['OCSVM_label'] = labels
out['OCSVM_score'] = scores
print(out[out['OCSVM_label'] == -1].sort_values('OCSVM_score'))

🧮 SSDSE-B-2026 拡張ハンズオン — 47 都道府県を 3 つの観点で外れ値検出

ここでは data/raw/SSDSE-B-2026.csv を実際に読み込み、 「一人当たり県民所得」「高齢化率」「完全失業率」の 3 列で外れ値検出を 3 方式(IQR / Z スコア / MAD)で比較します。 結果が手法によってどう変わるかを 47 件の固有名で確認することで、 「どの基準が業務に合うか」を直感で掴めます。

🎯 学習目的

3 つのルール(IQR・Z スコア・MAD)が同じデータに対して違う外れ値リストを返すことを実データで体感する。

📥 入力

data/raw/SSDSE-B-2026.csvPrefecturePer_capita_incomeAging_rateUnemployment_rate 列。

📤 出力

3 ルール別の外れ値県名リストと、 ベン図的な交差表。

💬 解説

東京都は「所得」では確実に外れ値だが、 「高齢化率」では逆に外れ値にならない。 沖縄県は「所得」「失業率」両方で挙がる可能性が高い。 こうした県固有の挙動を、 ルールの違いとして読み取れるようになるのが目標です。

🐍 比較スクリプト

import pandas as pd
import numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig')

def by_iqr(s):
    q1, q3 = s.quantile([.25, .75])
    iqr = q3 - q1
    return (s < q1 - 1.5*iqr) | (s > q3 + 1.5*iqr)

def by_z(s, k=2.5):
    return ((s - s.mean()) / s.std()).abs() > k

def by_mad(s, k=3.5):
    med = s.median()
    mad = (s - med).abs().median()
    if mad == 0:
        return pd.Series(False, index=s.index)
    return (0.6745 * (s - med) / mad).abs() > k

for col in ['Per_capita_income', 'Aging_rate', 'Unemployment_rate']:
    s = df[col]
    out = pd.DataFrame({
        'IQR':  by_iqr(s),
        'Zscore': by_z(s),
        'MAD':  by_mad(s),
    }, index=df['Prefecture'])
    flagged = out[out.any(axis=1)]
    print(f'--- {col} ---')
    print(flagged)

読み解きの観点

❓ よくある質問 — 外れ値の意思決定 12 問

Q1. 外れ値を除外するべきか、 残すべきか

原則は「業務目的外れ値の発生メカニズムの二軸で決める」。 計測誤差由来なら除外、 真に稀な現象なら保持。 SSDSE-B-2026 で東京都を除外するなら、 「全国を代表する分析である」と業務目的が明示できるときに限る。

Q2. 同じデータで IQR・Z スコア・MAD のどれを使うべきか

標本サイズが小さく分布の歪みが大きいならMAD。 標本サイズが十分(n > 100 目安)で対称な分布なら Z スコアで良い。 IQR は読み手の直感に近く可視化との相性が良いため、 説明用にしばしば使われる。

Q3. 多変量の外れ値検出はどう始めるか

Mahalanobis 距離 → Isolation Forest → LOF の順で試すのが効率的。 まず Mahalanobis で楕円外を抽出し、 非線形構造があれば Isolation Forest / LOF で再検査する。

Q4. 外れ値処理の前後でモデル評価指標はどう変わるか

外れ値を除外すると訓練 R^2 は通常上がるが、 汎化性能は下がる場合がある。 ホールドアウト test set に外れ値が含まれるなら、 訓練側だけ外しても本番では困るので「Winsorize」「ロバスト損失」を併用する。

Q5. ログ変換は外れ値対策になるか

右に裾の長い分布なら効果的。 ただし負値・ゼロを含む場合は log1p や Box-Cox を使う。 SSDSE-B-2026 の「観光客数」「事業所数」のような幅広い指標は対数化が有効。

Q6. 機械学習モデルは自動で外れ値を扱ってくれるか

木系(Random Forest・XGBoost)は分割で吸収するため比較的頑健。 一方、 距離ベース(k-NN・SVM)や勾配ベース(線形・ニューラル)は外れ値の影響を大きく受ける。

Q7. 「3σ ルール」は実用的か

厳密には正規分布の仮定が前提。 SSDSE-B-2026 のように極端な歪みを持つ社会経済指標には不向きで、 IQR か MAD を使うべき。 ただし「ざっくり外れているか」のスクリーニングには手早い。

Q8. レポートには外れ値処理をどう書けばよいか

「使用した基準」「除外した観測の数と県名」「除外/保持で結論が変わるか感度分析した結果」の 3 点を最低限明示する。 これを書かない論文は再現できない。

Q9. 外れ値が「重要な発見」である場合の扱いは

除外せず、 むしろ主分析の主役に据える。 「東京都だけが特殊である」こと自体が政策的に重要なら、 全国平均との比較ではなく東京都を分離した分析を立てる。

Q10. 標本サイズが小さい場合の外れ値検出

n < 30 では Grubbs 検定や Dixon 検定など個別検定に頼り、 多重比較補正を入れる。 経験的ルール(IQR や 3σ)は標本数が少ないと信頼性が落ちる。

Q11. 外れ値検出を自動化するパイプラインはどう作るか

scikit-learn の PipelineIsolationForestEllipticEnvelope を組み込み、 contamination パラメータを CV で選ぶ。 さらに「業務側のホワイトリスト」を併用して、 制度的に特殊な観測を自動除外しない仕組みを併設する。

Q12. 外れ値処理は本当に必要か

常に必要というわけではない。 ロバスト回帰やランクベースの手法を使えば前処理不要。 「外れ値処理 + 通常モデル」と「外れ値処理なし + ロバストモデル」のどちらかを選ぶ、 と整理すると判断が早い。

🚀 発展研究の方向性 — 外れ値の最前線 6 題

🌳 外れ値処理の意思決定木 — 6 つの分岐

分岐 1: 計測誤差か真の値か

分岐 2: 業務目的が「全体傾向」か「特異な観測の発見」か

分岐 3: 単変量か多変量か

分岐 4: 分布の歪み

分岐 5: モデルへの感度

分岐 6: 報告

📖 外れ値関連用語ミニ辞典 — 12 語

Outlier
分布の他の値から大きく離れた観測。
Tukey IQR Rule
Q1-1.5*IQR と Q3+1.5*IQR の外側を外れ値とするルール。
Z スコア
(x - 平均) / 標準偏差。 |Z| > 3 で外れ値の経験則。
MAD (Median Absolute Deviation)
中央値からの絶対偏差の中央値。 ロバストな指標。
Modified Z-score
MAD ベースのロバスト Z スコア。 0.6745 * (x - median) / MAD。
Grubbs 検定
外れ値を 1 個ずつ検定する古典的手法。
Dixon 検定
小標本用の外れ値検定。 範囲比を使う。
Mahalanobis 距離
共分散構造を考慮した多変量距離。
Isolation Forest
木で「孤立しやすい点」を見つける異常検知。
LOF (Local Outlier Factor)
近傍密度の比で局所的外れ値を検出。
One-Class SVM
「正常データの境界」を SVM で学習する手法。
Winsorize
外れ値を一定の分位点で「すげ替える」処理。

✅ 外れ値処理の最終チェックリスト 12 項目

分析レポート提出前の自己点検として、 以下の 12 項目すべてに「Yes」と答えられるかを確認してください。 一つでも「No」があれば、 そのセクションに戻って補強する必要があります。

  1. 使用した外れ値検出ルール(IQR / Z スコア / MAD / Mahalanobis / Isolation Forest など)を明示したか。
  2. 除外した観測の県名・件数・除外理由を本文または付録に記載したか。
  3. 除外前後で結論が変わらないことを感度分析として示したか。
  4. 計測誤差由来か真の値か、 ドメイン知識で判定したか。
  5. 業務目的(全体傾向 vs 特異な発見)と外れ値処理が整合しているか。
  6. 単変量だけでなく多変量視点(Mahalanobis ・ Cook 距離)でも確認したか。
  7. 標本サイズが小さい場合、 Grubbs/Dixon 検定など個別検定を併用したか。
  8. ログ変換・ Box-Cox 変換で分布の歪みを緩和する選択肢を検討したか。
  9. ロバスト統計の代替手法(Huber 回帰 ・ MAD ベースのロバスト Z)を併用したか。
  10. SSDSE-B-2026 における東京都・沖縄県など制度的に特殊な県の扱いを文書化したか。
  11. 機械学習モデル使用時に「外れ値前処理 + 通常モデル」と「ロバストモデル」のどちらを選んだか言語化したか。
  12. 外れ値が「重要な発見」である可能性を排除しないチェックを行ったか。

📝 まとめノート — 外れ値

このページは「外れ値」を SSDSE-B-2026 (47 都道府県 × 多変量) を題材に体系的に学ぶための一気通貫の教材です。 単なる用語定義集ではなく、 「直感 → 数式 → 実装 → 落とし穴 → 関連手法」 という流れで一周することで、 業務での意思決定にそのまま使える知識に組み上げます。

本ページで取り上げた手法・記号・コード例は、 すべて実データの 47 都道府県を入力として動作する形にしてあります。 合成データに依存しないため、 SSDSE-B-2026 を data/raw/SSDSE-B-2026.csv として配置するだけでコード片を再現できます。

関連グループ教材へのリンクを使い、 「この用語が属する大きな分野」を俯瞰してから戻ってくると、 知識が一段抽象化された形で定着します。 用語ページは点、 グループ教材は線、 概念マップは面 — 三層を往復しながら学習を進めてください。

本ページの内容に不足を感じたら、 相関ページ(correlation.html)を参照基準として、 ご自身の解釈を加筆していくことを推奨します。 教材の完成形ではなく、 学習者自身の理解の出発点として位置付けてください。

最後に、 SSDSE-B-2026 の 47 都道府県データは「N=47 と少ない」という構造的制約があります。 統計検定の漸近近似が崩れる場面、 単一の県(東京都・沖縄県)が全体傾向を支配する場面、 標準誤差が過小評価される場面 — これらは本ページの随所で繰り返し注意喚起しました。 「実データの小ささを軽視しない」 という姿勢が、 実務でのデータサイエンティストの基本姿勢です。