📚 背景知識(読んでから問題へ)
「データの代表値」には3種類あります。どれを使うかで、データの見え方がガラッと変わります。
- 平均(Mean): 全員を同じ高さにならしたときの値。外れ値(極端な値)に引っ張られやすい
- 中央値(Median): データを小さい順に並べたとき、ちょうど真ん中の値。外れ値に強い
- 最頻値(Mode): 最も多く出てくる値。カテゴリデータ(性別・血液型など)で特に有効
実生活の例: 年収データで「平均年収」が高く見えるのは、一部の超高収入者が引き上げているため。「中央値」のほうが「普通の人の年収」に近い。
📝 問題
以下のTitanicデータを分析してください。
import pandas as pd
import numpy as np
# Titanicデータの一部
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Hank', 'Ivy', 'Jack'],
'Pclass': [1, 3, 2, 1, 3, 3, 2, 1, 3, 2],
'Age': [29, 22, 35, 42, 18, 25, 33, 55, 20, np.nan],
'Fare': [211.3, 7.9, 26.0, 263.0, 7.9, 8.1, 13.0, 512.3, 7.8, 26.0],
'Survived': [1, 0, 1, 1, 0, 0, 1, 1, 0, 1]
}
df = pd.DataFrame(data)
以下の問いに答えてください:
Fare(運賃)の平均・中央値・最頻値を計算してください- 平均と中央値の差が大きい場合、それは何を意味しているか説明してください
Pclass(客室クラス: 1=一等, 2=二等, 3=三等)の最頻値を求め、このデータで最も多いクラスを答えてくださいAgeに欠損値(NaN)がありますが、平均で補完した場合と中央値で補完した場合、どちらが望ましいか、理由とともに答えてください
🔍 ヒント(段階的開示)
ヒント1(方向性)
pandasのSeriesには統計を計算するメソッドが揃っています。それぞれのメソッドを使い分けましょう。
ヒント2(アプローチ)
- 平均:
.mean() - 中央値:
.median() - 最頻値:
.mode()[0](リストで返るので[0]で最初の値を取る) - 欠損補完:
.fillna(値)
ヒント3(コード骨格)
# 1. Fareの統計
fare_mean = df['Fare'].___()
fare_median = df['Fare'].___()
fare_mode = df['Fare'].___()[0]
# 3. Pclassの最頻値
pclass_mode = df['Pclass'].___()[0]
# 4. Ageの補完
df['Age_mean_filled'] = df['Age'].fillna(df['Age'].___())
df['Age_median_filled'] = df['Age'].fillna(df['Age'].___())
✅ 模範解答
import pandas as pd
import numpy as np
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Hank', 'Ivy', 'Jack'],
'Pclass': [1, 3, 2, 1, 3, 3, 2, 1, 3, 2],
'Age': [29, 22, 35, 42, 18, 25, 33, 55, 20, np.nan],
'Fare': [211.3, 7.9, 26.0, 263.0, 7.9, 8.1, 13.0, 512.3, 7.8, 26.0],
'Survived': [1, 0, 1, 1, 0, 0, 1, 1, 0, 1]
}
df = pd.DataFrame(data)
# 1. Fareの統計
fare_mean = df['Fare'].mean() # 約 108.43
fare_median = df['Fare'].median() # 19.5
fare_mode = df['Fare'].mode()[0] # 7.9(最多登場)
print(f"Fare 平均: {fare_mean:.2f}")
print(f"Fare 中央値: {fare_median:.2f}")
print(f"Fare 最頻値: {fare_mode:.2f}")
# 3. Pclassの最頻値
pclass_mode = df['Pclass'].mode()[0]
print(f"\nPclass 最頻値: {pclass_mode} (三等客室が最多)")
# 4. Ageの補完
df['Age_mean_filled'] = df['Age'].fillna(df['Age'].mean())
df['Age_median_filled'] = df['Age'].fillna(df['Age'].median())
print(f"\nAge 平均補完: {df['Age_mean_filled'].values}")
print(f"Age 中央値補完: {df['Age_median_filled'].values}")
出力例:
▶ 出力を見る
Fare 平均: 108.43
Fare 中央値: 19.50
Fare 最頻値: 7.90
Pclass 最頻値: 3 (三等客室が最多)
Age 平均補完: [29. 22. 35. 42. 18. 25. 33. 55. 20. 28.56]
Age 中央値補完: [29. 22. 35. 42. 18. 25. 33. 55. 20. 27. ]🪜 Step-by-Step 解説
1
Fareの平均と中央値を比較する
fare_mean = df['Fare'].mean() # 108.43
fare_median = df['Fare'].median() # 19.50
平均108.43 vs 中央値19.50 — 大きな差があります。
なぜ差がでるか?
HankのFare=512.3(一等客の最高運賃)が平均を大きく引き上げているためです。
中央値は「512.3という外れ値」の影響を受けません。
→ 差が大きい = 外れ値(極端な値)が存在するサイン
2
最頻値でカテゴリを調べる
pclass_mode = df['Pclass'].mode()[0] # 3
mode()はリストを返すため[0]で最初の値を取ります。
(同率最多が複数ある場合に備えてリスト形式になっています)
3
欠損値補完の判断
df['Age_mean_filled'] = df['Age'].fillna(df['Age'].mean()) # 28.56で補完
df['Age_median_filled'] = df['Age'].fillna(df['Age'].median()) # 27.0で補完
どちらが望ましいか?
| 補完方法 | 値 | 特徴 |
|---|---|---|
| 平均補完 | 28.56 | 外れ値(高齢者・子供)に引っ張られる |
| 中央値補完 | 27.0 | 外れ値に強い、より「典型的な値」 |
Ageデータには外れ値(幼児や高齢者)が含まれやすいため、中央値補完が一般的に望ましい。
📐 数学・統計の補足(文系向け)
なぜ平均は外れ値に弱いのか?
たとえば [10, 10, 10, 10, 1000] というデータ:
- 平均 = (10×4 + 1000) ÷ 5 = 208 ← 実態とかけ離れている
- 中央値 = 10 ← 「だいたいこのくらい」という実感に近い
Kaggleのデータでも「価格」「年収」「アクセス数」などは外れ値が多く、中央値・対数変換が有効です。
🏆 Kaggleでの実践的な使い方
| 場面 | 使う代表値 |
|---|---|
| 欠損値の補完(数値データ) | 外れ値が少ない → 平均 / 多い → 中央値 |
| 欠損値の補完(カテゴリデータ) | 最頻値 |
| 分布の歪みチェック | 平均 > 中央値 → 右に歪んでいる(高額品など) |
| 特徴量の要約統計 | df.describe() で一括確認 |
実際のコンペでよく見るコード:
# 欠損補完のベストプラクティス
df['Age'].fillna(df['Age'].median(), inplace=True) # 数値→中央値
df['Embarked'].fillna(df['Embarked'].mode()[0], inplace=True) # カテゴリ→最頻値
⚠️ よくある誤解・ミス
| 誤解・ミス | なぜ起こるか | 正しい理解 |
|---|---|---|
mode()の結果を直接使う | mode()はSeriesを返す | mode()[0]でスカラー値を取得 |
| 常に平均で欠損補完する | 平均が「普通の値」と思い込む | 外れ値の有無を確認してから選ぶ |
| 平均≒中央値と思い込む | 正規分布を前提にしてしまう | 歪んだ分布では大きく異なる |
🚀 次のステップ
- 発展: 歪度(Skewness)を計算し、分布の形を定量化する(
df['Fare'].skew()) - 次回予告: テーマ2「分散・標準偏差・外れ値」— データのばらつきを数値で表す方法