はじめに
前回の統計学入門では、平均・標準偏差・相関係数・仮説検定といった基礎概念を整理した。
その中で「正規分布」「歪度」という言葉が登場したが、今回はデータの分布に絞って掘り下げていく。
なぜ分布を理解する必要があるのか
データサイエンスで扱う手法の多くは、データの分布について何らかの前提を持っている。
例えば、
- 線形回帰は残差が正規分布に従うことを前提としている
- 平均値は分布が対称に近い場合にのみ代表値として機能しやすい
- 外れ値の判定基準も、分布の形によって変わる
分布を把握せずに分析を進めると、手法の前提が満たされないまま誤った結論を導くリスクがある。
分布の確認はEDAの中でも特に重要な工程である。
1. 正規分布
概要
最も基本的かつ広く使われる分布。左右対称の釣り鐘型をしており、平均値・中央値・最頻値が一致するのが特徴。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
x = np.linspace(50, 250, 300)
y = norm.pdf(x, loc=150, scale=30) # 平均150、標準偏差30
plt.plot(x, y, color="steelblue")
plt.title("正規分布(平均150、標準偏差30)")
plt.xlabel("値")
plt.ylabel("確率密度")
plt.show()
68-95-99.7ルール
正規分布には以下の性質がある。
| 範囲 | データの割合 |
|---|---|
| 平均 ± 標準偏差1つ分 | 約68% |
| 平均 ± 標準偏差2つ分 | 約95% |
| 平均 ± 標準偏差3つ分 | 約99.7% |
例えば平均150・標準偏差30の売上データであれば、90〜210の範囲に約68%のデータが収まる計算になる。
外れ値の判定(平均±3σを超える値は外れ値候補)もこの性質を利用している。
正規性の確認方法
データが正規分布に近いかを確認する方法は主に2つある。
① ヒストグラムで目視確認
data = np.random.normal(loc=150, scale=30, size=500)
plt.hist(data, bins=30, color="steelblue", edgecolor="white", density=True)
# 正規分布の曲線を重ねる
x = np.linspace(data.min(), data.max(), 300)
plt.plot(x, norm.pdf(x, data.mean(), data.std()), color="red", linewidth=2)
plt.title("ヒストグラムと正規分布の比較")
plt.show()
② Q-Qプロット(Quantile-Quantile Plot)
データの分位点と正規分布の分位点を比較したグラフ。点が直線上に並んでいれば正規分布に近いと判断できる。
from scipy.stats import probplot
probplot(data, dist="norm", plot=plt)
plt.title("Q-Qプロット")
plt.show()
2. 一様分布
概要
すべての値が等しい確率で出現する分布。サイコロの目(1〜6が各1/6)が典型例。
data = np.random.uniform(low=0, high=100, size=1000)
plt.hist(data, bins=20, color="steelblue", edgecolor="white")
plt.title("一様分布")
plt.xlabel("値")
plt.ylabel("件数")
plt.show()
データサイエンスの現場では、乱数生成や初期値設定などで使われることが多い。
3. 二項分布
概要
「成功か失敗か」という2択の試行をn回繰り返したとき、成功回数がどう分布するかを表す。
例:クーポン送付100件のうち、開封率20%のとき何件開封されるか。
from scipy.stats import binom
n = 100 # 試行回数
p = 0.2 # 成功確率
x = np.arange(0, 41)
y = binom.pmf(x, n, p)
plt.bar(x, y, color="steelblue")
plt.title(f"二項分布(n={n}, p={p})")
plt.xlabel("開封数")
plt.ylabel("確率")
plt.show()
nが大きくなるにつれ、二項分布は正規分布に近づく性質がある。
4. ポアソン分布
概要
単位時間・単位面積あたりに発生するイベントの回数を表す分布。
「1時間あたりの来客数」「1日あたりの問い合わせ件数」など、まれに発生するイベントの頻度に適している。
from scipy.stats import poisson
lambda_ = 10 # 平均発生回数(例:1時間あたり平均10人来客)
x = np.arange(0, 25)
y = poisson.pmf(x, lambda_)
plt.bar(x, y, color="steelblue")
plt.title(f"ポアソン分布(λ={lambda_})")
plt.xlabel("来客数")
plt.ylabel("確率")
plt.show()
平均(λ)と分散が等しいのがポアソン分布の特徴である。
実データでの来客数の分布がポアソン分布に近ければ、「1時間に来客が20人を超える確率」といった計算が可能になる。
5. 対数正規分布
概要
データの対数を取ると正規分布になるような分布。右に裾が長い(正の歪度を持つ)形が特徴。
収入・株価・商品の売上金額など、ゼロ以上の値をとり、少数の大きな値が存在するデータによく見られる。
data = np.random.lognormal(mean=5, sigma=0.5, size=1000)
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].hist(data, bins=50, color="steelblue", edgecolor="white")
axes[0].set_title("対数正規分布(元データ)")
axes[0].set_xlabel("値")
axes[1].hist(np.log(data), bins=30, color="coral", edgecolor="white")
axes[1].set_title("対数変換後(正規分布に近づく)")
axes[1].set_xlabel("log(値)")
plt.tight_layout()
plt.show()
分布が大きく右に偏っている場合、対数変換を施すことで正規分布に近づけることができる。
これにより、正規分布を前提とした統計手法や機械学習モデルを適用しやすくなる。
6. 歪度と尖度
分布の形を数値で表す指標として、歪度に加えて尖度も押さえておくとよい。
歪度(Skewness):分布の左右の偏り
from scipy.stats import skew
print(f"歪度: {skew(data):.3f}")
| 値 | 分布の形 |
|---|---|
| 0に近い | 左右対称 |
| 正の値 | 右に裾が長い(高い値の外れ値が多い) |
| 負の値 | 左に裾が長い(低い値の外れ値が多い) |
尖度(Kurtosis):分布の尖り具合
from scipy.stats import kurtosis
print(f"尖度: {kurtosis(data):.3f}")
| 値 | 分布の形 |
|---|---|
| 0に近い | 正規分布と同程度の尖り |
| 正の値 | 尖りが強い(外れ値が多い傾向) |
| 負の値 | 平坦な分布 |
分布の選び方:実務での考え方
実際のデータがどの分布に近いかを判断する際の目安を整理する。
| データの特徴 | 近い分布 |
|---|---|
| 左右対称、釣り鐘型 | 正規分布 |
| 右に裾が長い(収入・売上など) | 対数正規分布 |
| すべての値が均等に出現する | 一様分布 |
| 成功/失敗の試行回数 | 二項分布 |
| 単位時間あたりのイベント数 | ポアソン分布 |
分布の特定は、ヒストグラムでの目視確認を起点として、歪度・尖度・Q-Qプロットを組み合わせながら判断するのが実際の流れである。
まとめ
| 分布 | 特徴 | 実務での例 |
|---|---|---|
| 正規分布 | 左右対称、釣り鐘型 | 身長・測定誤差など |
| 一様分布 | すべての値が等確率 | 乱数生成など |
| 二項分布 | 2択試行のn回の成功数 | 開封率・コンバージョン率など |
| ポアソン分布 | 単位時間のイベント発生数 | 来客数・問い合わせ件数など |
| 対数正規分布 | 右裾が長い | 収入・売上金額など |
分布を把握することは、EDAでの異常検知・前処理の方針決定・適切な統計手法の選択など、データサイエンスの各場面で判断の根拠になる。
前回整理した標準偏差や相関係数も、分布の形を理解した上で使うことでより正確な解釈が可能になる。
次回こそはpandasを使ったデータの加工・集計について整理していく予定。