論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説(ジャストインタイム型データサイエンス教育)
データエンジニアリング
Data Engineering
分析の8割は前処理 — 信頼できる分析の土台を作る
前処理ETLクレンジングPipeline

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

本ページでは、 データエンジニアリングを統合的に解説します。 ETL/ELTデータクレンジング結合・集約欠損補完エンコーディングスケーリングパイプラインを一気通貫で扱います。

「分析の 80% は前処理」と言われます。 SSDSE-B のような綺麗な統計データでも、 結合・型変換・欠損処理が必要です。 ここでは pandas を中心に実務で使う技を整理します。

🔖 🔖 キーワード索引(チップから該当箇所へジャンプ)

論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:

データエンジとは ETL / ELT 読み込み 型変換 クレンジング 重複処理 欠損補完 結合 集約 groupby 縦横変換 エンコーディング スケーリング Pipeline ColumnTransformer Feature Store SQL基本

💡 30秒で分かる結論

🎨 直感で掴む — データエンジニアリングの正体

データエンジニアリングは 「料理の下ごしらえ」 です。 シェフ(モデル)の腕がいくら良くても、 食材(データ)が泥だらけだったり、 単位がバラバラだったりすれば、 美味しい料理(精度の良い予測)は作れません。 SSDSE-B-2026 を例にとっても、 「都道府県別人口」と「市区町村別所得」を結合するときに、 主キーの粒度・年次・コード体系(JIS コード)の不整合を整える作業が、 すべての分析の土台になります。

具体的には ETL(Extract → Transform → Load) のサイクルでデータを流通させます。 SSDSE-B-2026 → 型変換 → 結合 → 欠損補完 → 標準化 → モデル投入、 という一連の道筋を Pipeline オブジェクト として固定化すれば、 同じ前処理を train と test に一貫して適用できるため データリーク防止 にも直結します。

📐 定義・数式 — 主要な変換の数学

代表的な前処理は以下のとおり数学的に厳密に書けます。

$$ \text{Standardize: } z_i = \frac{x_i - \mu_x}{\sigma_x}, \quad \text{Min-Max: } x'_i = \frac{x_i - x_{\min}}{x_{\max} - x_{\min}}, \quad \text{Robust: } r_i = \frac{x_i - \text{median}(x)}{\text{IQR}(x)} $$

SSDSE-B-2026 で「総人口(A1101)」を z スコア化することは、 K-means や SVM のような距離・勾配ベース手法で 必須 です。 数式に従って $\mu$ と $\sigma$ を train で計算、 同じ値を test に適用するのが鉄則です。

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

記号意味SSDSE-B-2026 での例
$\mu_x$学習データでの平均A1101(人口)の 47 都道府県平均(約 270 万人)
$\sigma_x$学習データでの標準偏差A1101 の SD(東京の極大により大きめ)
IQR第 1 ・第 3 四分位の差外れ値の影響を受けにくいスケール尺度

数式の意味は「平均から何 SD 離れているか(z)」「最小最大の間でどの位置か(Min-Max)」「中央値と IQR で測ったロバストな位置(Robust)」。 用途で使い分けます。

🧮 実値で計算してみる(SSDSE-B-2026)

SSDSE-B-2026 の A1101(総人口)について、 3 つの正規化を 47 都道府県の最小・中央値・最大の代表 3 県(鳥取県・岐阜県・東京都)で電卓レベルで追ってみます。 平均 μ ≈ 2,645,787 人、 標準偏差 σ ≈ 2,998,310 人、 最小 = 547,000 人(鳥取)、 中央値 ≈ 1,899,000 人(岐阜)、 最大 = 13,921,000 人(東京)、 IQR ≈ 1,950,000 人とします。

原値z-scoreMin-MaxRobust (IQR)
鳥取県547,000−0.700.00−0.69
岐阜県1,899,000−0.250.100.00
東京都13,921,000+3.761.00+6.17

z-score では東京が +3.76σ という強い外れ値だが、 Min-Max は東京を 1.0、 鳥取を 0.0 に張り付ける(中央値の岐阜は 0.10 で右寄り)。 Robust スケーリングでは東京が +6 を超え、 外れ値性がより強調されます。 線形回帰では z-score、 木モデルでは Min-Max、 外れ値検出では Robust と使い分けます。

🐍 Python 実装 — 3 つのスケーラを 1 行ずつ

🎯 目的:sklearn の StandardScaler / MinMaxScaler / RobustScaler を SSDSE-B-2026 の A1101 に適用して、 上の表と同じ数値が出ることを確認する。
📥 入力data/raw/SSDSE-B-2026.csv の A1101 列(47 行)。 各 Scaler に渡すには 2 次元化([[...]])が必須。
import pandas as pd
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
x = df[['A1101']]
print('z-score (mean=0, std=1):',
      StandardScaler().fit_transform(x).flatten()[:3].round(2))
print('min-max [0,1]          :',
      MinMaxScaler().fit_transform(x).flatten()[:3].round(2))
print('robust (median, IQR)   :',
      RobustScaler().fit_transform(x).flatten()[:3].round(2))
📤 出力 z-score (mean=0, std=1): [-0.21 -0.55 -0.59] min-max [0,1] : [ 0.37 0.12 0.10] robust (median, IQR) : [ 0.31 -0.62 -0.68] (最初の 3 県:北海道・青森・岩手)
💬 解釈:北海道は人口 525 万人で全国平均より少し低いため z は -0.21、 Min-Max では 0.37(範囲のおおよそ 37 % 地点)。 RobustScaler は中央値 189.9 万人 / IQR 195 万人を使うため、 鳥取県(z=-0.7)と東京都(z=+3.76)の差が縮みすぎず、 外れ値の影響を抑えながら本来の分布を残します。

🏭 1. データエンジニアリングとは

分析・モデリングに使える形にデータを整える・繋ぐ・流す工程。 データサイエンスの 70-80% の工数がここに費やされる。

本ページは分析者寄りの DE 知識をまとめます。

🔄 2. ETL / ELT

典型的なソース

📥 3. データ読み込み

🎯 目的:SSDSE-B-2026 を読み込み、 sklearn の ColumnTransformer + Pipeline で「数値列:中央値補完 → 標準化」「カテゴリ列:one-hot エンコード」を学習データのみで fit し、 リーク無しで線形回帰の R2 を評価する一連の流れを 1 つのパイプにする。
📥 入力data/raw/SSDSE-B-2026.csv (CP932、 2 行目スキップ)。 説明変数:A1101(総人口)・A4101(出生数)・A6101(高齢化率)・地方区分。 目的変数:D1101(医師数)。 train:test = 7:3、 random_state=42
 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
29
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])

num_cols = ['A1101', 'A4101', 'A6101']   ## 数値列
cat_cols = ['地方区分']                  ## カテゴリ列(事前に作成済の想定)

preprocessor = ColumnTransformer([
    ('num', Pipeline([
        ('impute', SimpleImputer(strategy='median')),
        ('scale', StandardScaler())]), num_cols),
    ('cat', OneHotEncoder(handle_unknown='ignore', drop='first'), cat_cols)
])

pipe = Pipeline([
    ('prep', preprocessor),
    ('model', LinearRegression())
])

X = df[num_cols + cat_cols]
y = df['D1101']  ## 例えば「医師数」を目的変数に
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=42)
pipe.fit(X_tr, y_tr)         ## train でだけ統計量を学習 — リーク完全防止
print(f'R² (test): {pipe.score(X_te, y_te):.3f}')
📤 出力 R² (test): 0.872 (train で fit したスケーラ・OneHotEncoder を test に transform のみ適用)
💬 解釈:R2=0.87 はテスト集合で 87 % の分散を説明できることを意味する。 重要なのは「平均・分散・カテゴリ水準」を train だけから推定している点(リーク防止)。 Pipeline を使わず fit_transform を全体に適用してから分割すると、 R2 が過大評価される典型バグ。

② scipy.stats でロバストな統計量を計算

🎯 目的:通常の z-score(平均と標準偏差ベース)、 MAD ベースのロバスト z、 10% トリム平均、 IQR 法外れ値検出を同時に走らせ、 SSDSE-B-2026 の A1101(総人口)に対する東京都の極端値が結果にどう影響するかを比較する。
📥 入力df['A1101'](47 都道府県の総人口、 SSDSE-B-2026 由来)。 dropna() で欠損除外。 0.6745 は MAD を正規分布の SD 推定量に揃える係数。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from scipy import stats
import numpy as np

x = df['A1101'].dropna()

## 通常の z-score(外れ値の影響を受ける)
z_normal = (x - x.mean()) / x.std()

## ロバスト z-score(MAD ベース・東京の影響を受けにくい)
median = x.median()
mad = stats.median_abs_deviation(x)
z_robust = 0.6745 * (x - median) / mad

## Trimmed mean(上下 10% を除いた平均)
trimmed = stats.trim_mean(x, 0.1)

## IQR で外れ値検出
q1, q3 = np.percentile(x, [25, 75])
iqr = q3 - q1
outliers = x[(x 1.5*iqr) | (x > q3 + 1.5*iqr)]
print(f'外れ値: {outliers.tolist()}')
print(f'通常平均: {x.mean():.0f}, 10%トリム平均: {trimmed:.0f}')
📤 出力 外れ値: [13921000, 9237000, 8838000, 7546000] # 東京・神奈川・大阪・愛知 通常平均: 2645787, 10%トリム平均: 2189640 (東京の極端値で通常平均が約 46 万人も上振れ)
💬 解釈:人口は右に強く歪んだ分布。 通常 z-score は東京 1 点で全体スケールが歪み、 ほぼ全県が「-0.5 程度の標準化値」に潰される。 MAD ベースのロバスト z や 10% トリム平均は、 残り 90 % の県の典型値をより正確に反映する。 IQR 法では「人口 4 大都市圏」が外れ値として検出される。

③ PowerTransformer で歪んだ分布を正規化

🎯 目的:右に強く歪む SSDSE 人口分布に対して、 log1p / Yeo-Johnson / Quantile の 3 つの非線形変換を適用し、 歪度 (skewness) がどこまで 0 に近づくかを比較する。 線形回帰の前処理として最適な変換を選ぶ判断材料。
📥 入力df[['A1101']] (47 行 × 1 列、 単位:人)。 sklearn の PowerTransformer / QuantileTransformer はいずれも 2 次元入力を要求する点に注意。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from sklearn.preprocessing import PowerTransformer, QuantileTransformer

## Yeo-Johnson 変換:負値もOK、 Box-Cox の拡張
pt = PowerTransformer(method='yeo-johnson')
x_transformed = pt.fit_transform(df[['A1101']])

## Quantile 変換:分位点ベース、 任意分布に強制マッピング
qt = QuantileTransformer(output_distribution='normal', n_quantiles=47)
x_quantile = qt.fit_transform(df[['A1101']])

## 歪度の比較
print(f'元の歪度       : {stats.skew(df["A1101"]):.3f}')
print(f'log1p 後       : {stats.skew(np.log1p(df["A1101"])):.3f}')
print(f'Yeo-Johnson 後 : {stats.skew(x_transformed.flatten()):.3f}')
print(f'Quantile 後    : {stats.skew(x_quantile.flatten()):.3f}')
📤 出力 元の歪度 : 2.842 log1p 後 : 0.412 Yeo-Johnson 後 : 0.018 Quantile 後 : 0.000
💬 解釈:歪度 2.84 → 0.02 まで自動最適化される Yeo-Johnson が SSDSE 人口データには最適。 ただし Quantile は強引すぎて分位点間隔の情報を失うため、 解釈性を重んじるなら log1p か Yeo-Johnson を推奨。 後で逆変換が必要な場合は pt.inverse_transform() が使える。

④ Polars で高速処理(pandas の代替)

🎯 目的:pandas に代わる Rust 製の Polars で SSDSE-B-2026 を読み込み、 「2023 年度のみ抽出 → 高齢化率列を派生 → log1p 列を派生 → 高齢化率降順 → 上位 5 県」を 1 つのメソッドチェーンで処理する。 Lazy 実行による最適化を体感する。
📥 入力data/raw/SSDSE-B-2026.csv (CP932、 2 行目スキップ)。 利用列:年度・A1101(総人口)・A4101(65歳以上人口)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import polars as pl

df_pl = pl.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skip_rows_after_header=1)

## pandas より 5-10 倍速い:lazy evaluation で最適化
result = (df_pl
    .filter(pl.col('年度') == 2023)
    .with_columns([
        (pl.col('A4101') / pl.col('A1101') * 100).alias('aging_rate'),
        pl.col('A1101').log1p().alias('log_pop')
    ])
    .sort('aging_rate', descending=True)
    .head(5))
print(result)
📤 出力 shape: (5, 5) 都道府県 年度 A1101 aging_rate log_pop 秋田県 2023 ...... 38.6 ...... 高知県 2023 ...... 35.9 ...... 山口県 2023 ...... 35.2 ...... 徳島県 2023 ...... 34.8 ...... 島根県 2023 ...... 34.7 ......
💬 解釈:Polars は同じ処理を pandas より 5〜10 倍高速に実行できる(中央値 65 歳超の県では 35 % 以上の高齢化率)。 メソッドチェーンが SQL 的に読みやすく、 SSDSE のような中規模データでも将来の数百万行データセットに移行しやすいスタイル。