📚 背景知識(読んでから問題へ)
ブロードキャストとは?
「形の違う配列同士を自動的に合わせて計算する仕組み」です。
スーパーのレシート(複数の金額)に消費税率(1つの数)を掛けるとき、税率を同じ数だけ用意する必要はありませんよね。numpy も同じことを自動でやります。
a shape (2, 3)
+
b shape (3,)
→
result shape (2, 3)
ブロードキャストのルール
末尾の次元から順番に比較して、サイズが同じか、どちらかが 1 であれば OK。
✓ OK
(3, 4) + (4,)末尾の 4 が一致
✓ OK
(3, 4) + (1, 4)1 は引き伸ばされる
✗ NG
(3, 4) + (3,)末尾が 4 vs 3 で不一致
ユニバーサル関数(ufunc)一覧
| 関数 | 意味 | 使用例 | 結果 |
|---|---|---|---|
np.sqrt() | 平方根 | np.sqrt(4) | 2.0 |
np.abs() | 絶対値 | np.abs(-5) | 5 |
np.exp() | 指数関数 e^x | np.exp(1) | 2.718… |
np.log() | 自然対数 | np.log(1) | 0.0 |
np.sum() | 合計 | np.sum([1,2,3]) | 6 |
np.mean() | 平均 | np.mean([1,2,3]) | 2.0 |
np.std() | 標準偏差 | np.std([1,2,3]) | 0.816… |
np.max() / np.min() | 最大・最小 | np.max([3,1,4]) | 4 |
📝 問題
次のコードを 実行前に 予測して、理由を言葉で説明してください。
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]]) # shape: (2, 3)
b = np.array([10, 20, 30]) # shape: (3,)
result = a + b
resultの shape は何になる?resultの中身(値)は何になる?- なぜそうなるのか、言葉で説明する
以下のデータを 標準化(Zスコア化) してください。
標準化とは「平均を引いて、標準偏差で割る」処理です。Kaggleの特徴量エンジニアリングで最頻出の前処理の1つ。
import numpy as np
data = np.array([150, 160, 170, 180, 190]) # 身長データ(cm)
# TODO: dataを標準化して z_scores に格納する
# ヒント: np.mean(), np.std() を使う
z_scores = ???
print(z_scores)
💡
期待される出力の特徴: 平均が(ほぼ)0 になり、各値が平均から「標準偏差の何個分」ずれているかを表す。
🔍 ヒント(段階的開示)
ヒント1 — 方向性
問1:
問2: 数式を思い出してください。標準化 =
b の shape (3,) が a の shape (2, 3) の
各行に対して適用されます。「各行に同じ操作をする」イメージで考えてみましょう。問2: 数式を思い出してください。標準化 =
(値 - 平均) ÷ 標準偏差。numpyでは - と / を使うだけです。
ヒント2 — アプローチ
問1:
問2:
b = [10, 20, 30] が a の各行 [1,2,3]、[4,5,6] にそれぞれ足されます。問2:
- 平均:
mean = np.mean(data) - 標準偏差:
std = np.std(data) - 標準化:
z_scores = (data - mean) / std
ヒント3 — コード骨格(ほぼ答え)
問1の答え:
# shape は (2, 3) になる
# [[1+10, 2+20, 3+30], → [[11, 22, 33],
# [4+10, 5+20, 6+30]] [14, 25, 36]]
問2の骨格:
mean = np.mean(data)
std = np.std(data)
z_scores = (data - mean) / std
✅ 模範解答
問1 — ブロードキャスト
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([10, 20, 30])
result = a + b
print("shape:", result.shape)
print(result)
▶ 出力を見る
shape: (2, 3)
[[11 22 33]
[14 25 36]]
📐
理由:
b の shape (3,) は a の shape (2, 3) の末尾次元と一致するため、ブロードキャストが適用されます。b が2行分にコピーされ(引き伸ばされ)、各行との足し算が行われます。問2 — 標準化(Zスコア)
import numpy as np
data = np.array([150, 160, 170, 180, 190])
mean = np.mean(data) # 170.0
std = np.std(data) # 14.142...
z_scores = (data - mean) / std
print("平均:", mean)
print("標準偏差:", std)
print("Zスコア:", z_scores)
print("確認 - Zスコアの平均(≈0):", np.mean(z_scores))
▶ 出力を見る
平均: 170.0
標準偏差: 14.142135623730951
Zスコア: [-1.41421356 -0.70710678 0. 0.70710678 1.41421356]
確認 - Zスコアの平均(≈0): 0.0
Zスコア ビジュアライゼーション
🪜 Step-by-Step 解説
1
ブロードキャストの仕組みを理解する
「引き伸ばす」といっても実際にはメモリをコピーしないため、非常に効率的。大量データを扱うKaggleではループより何十倍も速くなります。
b = [10, 20, 30] が内部的には [[10, 20, 30], [10, 20, 30]] に引き伸ばされてから a と足し算されます。「引き伸ばす」といっても実際にはメモリをコピーしないため、非常に効率的。大量データを扱うKaggleではループより何十倍も速くなります。
2
標準化の数学的意味を理解する
平均 = 170.0(全員の平均身長)、標準偏差 ≈ 14.14(平均からの典型的なズレ)
data = [150, 160, 170, 180, 190] の場合:平均 = 170.0(全員の平均身長)、標準偏差 ≈ 14.14(平均からの典型的なズレ)
(data - mean) で「平均からどれだけズレているか」を計算し、/ std で「標準偏差の何個分か」に換算します。
3
標準化の中にもブロードキャストが使われている!
# data は shape (5,) の配列
# mean は スカラー(単一の数値)
# → スカラーが自動的に shape (5,) に引き伸ばされる
diff = data - mean # [-20, -10, 0, 10, 20] ← ブロードキャスト!
z = diff / std # [-1.41, -0.71, 0, 0.71, 1.41] ← ブロードキャスト!
📐 数学・統計の補足(文系向け)
Zスコアとは
🎯
「自分は平均から標準偏差の何個分 離れているか」 を表す数値です。
| Zスコア | 意味 | 偏差値換算 |
|---|---|---|
0 | ちょうど平均 | 50 |
+1 | 平均より「典型的なズレ1個分」上 | 60 |
-1 | 平均より「典型的なズレ1個分」下 | 40 |
+2 | 平均より「典型的なズレ2個分」上(上位約2.3%) | 70 |
偏差値 = Zスコア × 10 + 50
なぜKaggleで標準化が必要か
機械学習モデル(特に距離を使うもの: KNN, SVM, 線形回帰など)は値の「スケール」に敏感です。標準化すれば両方が「平均0、標準偏差1」のスケールに統一されます。
🏆 Kaggleでの実践的な使い方
特徴量の標準化(前処理の基本)
import numpy as np
import pandas as pd
# Titanicのage列を標準化する例
df = pd.DataFrame({'age': [22, 38, 26, 35, float('nan')]})
# 欠損値を除いて計算
mean_age = np.mean(df['age'].dropna())
std_age = np.std(df['age'].dropna())
# 欠損値はそのままにして標準化
df['age_scaled'] = (df['age'] - mean_age) / std_age
print(df)
ブロードキャストを使った複数列の一括処理
# 複数の特徴量を一括で標準化(Kaggleでよく使うパターン)
X = np.array([[150, 60], # [身長, 体重]
[160, 55],
[170, 70],
[180, 80]])
means = np.mean(X, axis=0) # 各列の平均 → shape (2,)
stds = np.std(X, axis=0) # 各列の標準偏差 → shape (2,)
X_scaled = (X - means) / stds # ブロードキャストで一括標準化!
print(X_scaled)
🔧
実際のコンペでは
sklearn.preprocessing.StandardScaler を使うことが多いですが、その内部でもこれと同じ計算をしています。numpyで理解しておくとカスタム処理が書けるようになります。⚠️ よくある誤解・ミス
| 誤解・ミス | なぜ起こるか | 正しい理解 |
|---|---|---|
np.std() の ddof を気にしなくて良い? |
サンプル標準偏差(ddof=1)と母標準偏差(ddof=0)がある | Kaggleの前処理では ddof=0(デフォルト)でOK。統計的推定が目的なら ddof=1 |
| ブロードキャストでエラーが出た | shapeが合わない | エラーメッセージのshapeを確認し、末尾次元から一致するか確認する |
| 標準化すると元の値に戻せない? | 変換は可逆と知らない | original = z_scores * std + mean で元に戻せる(逆変換) |
np.mean() と .mean() は同じ? |
どちらも使われるので混乱 | arr.mean() と np.mean(arr) は基本的に同じ。pandas DataFrameでは .mean() が便利 |
🚀 次のステップ
- 発展:
axisパラメータを使った行方向・列方向の集計(np.sum(X, axis=0)vsaxis=1) - 次回予告: pandas入門(DataFrame・Series)— Kaggleでのデータ操作の主役