// PART 02 · ARTICLE 03 / 07
DATA-PREP SCALING L2

外れ値・カテゴリ変数・標準化

— 数値を機械学習に渡せる形に整える

10 min read· L2· 2026.05.20 update· by Editor

臨床データは、そのまま機械学習に渡せる形ではありません。 FIM、歩行速度、握力、施設 ID、疾患名、薬剤名には、 外れ値、表記揺れ、単位差、尺度差が含まれます。 これらを機械的に処理すると、 臨床的に重要な症例を失うことがあります。 一方で、放置するとモデルが不安定になります。

// CONTEXT

この記事では、外れ値の見つけ方、カテゴリ変数のエンコード、 標準化の使い分けを整理します。 基本は、数値を整える前に臨床的意味を確認することです。 そのうえで、Scaler や Encoder を Pipeline に入れます。 基本用語は 02·01 説明変数と目的変数、 実装上の注意は 09·02 データリーケージとは何かも参照してください。

// 01 · LEARN OUTCOMESこの記事でわかること

  • 外れ値を統計的基準と臨床的基準で確認できます。
  • One-Hot、Ordinal、Target、Frequency Encoding の違いを説明できます。
  • StandardScaler、MinMaxScaler、RobustScaler などを使い分けられます。
  • Scaler と Encoder を Pipeline 内で fit する理由を説明できます。

// 02 · CONCLUSION最初に結論

// 03 · FIGURE前処理で数値を整える流れ

// SCALER COMPARISON Standard (x - μ) / σ before 0 100 after -3 0 +3 平均 0、分散 1 線形・正則化向き 外れ値に弱い MinMax (x - xmin) / (xmax - xmin) before 18 126 after 0 1 範囲 [0, 1] 範囲固定が望ましいとき 外れ値に弱い Robust (x - median) / IQR before 外れ値 after 0 中央値・IQR ベース 外れ値に頑健 分布が歪むデータ向き Quantile → normal 分布へ変換 before (右に裾) after (正規分布風) 分位点で変換 分布の形を変える 解釈性に注意 スケーラーはモデルに合わせて選ぶ。外れ値に弱いか頑健か、分布の形を変えるかが選択軸。
図1: 標準化手法の比較。StandardScaler、MinMaxScaler、RobustScaler、QuantileTransformer の前後分布を並べ、外れ値の影響と分布の変化を示す。

標準化とは、変数の尺度をそろえる操作です。 年齢は 0〜100 程度、FIM 合計点は 18〜126、 歩行速度は 0〜2 m/s 程度です。 そのまま距離ベースのモデルに入れると、 尺度の大きい変数が強く効くことがあります。

ただし、標準化は数値を見やすくする操作ではありません。 モデルが扱いやすい表現に変える操作です。 外れ値を含む変数に StandardScaler を使うと、 平均と標準偏差が外れ値に引っ張られます。 その場合、RobustScaler などを検討します。

// CATEGORICAL ENCODING DECISION TREE カテゴリ変数 どうエンコードする? 順序がある? YES Ordinal Encoding 自立 / 監視 / 軽介助 … 段階間距離は等距とは限らない NO カテゴリ数は? 少 (<20) One-Hot Encoding 性別 / 病型 / 退院先 handle_unknown="ignore" 多 (≥20) Frequency or Target 施設 ID / 薬剤名 Target: fold 内 fit 必須 薬効分類への集約も検討 エンコード後の列数とリーケージリスクをセットで確認する。Target Encoding は out-of-fold 計算が前提。
図2: カテゴリエンコードのデシジョンツリー。順序がない少数カテゴリは One-Hot、順序があるカテゴリは Ordinal、高カードカテゴリは Frequency / Target Encoding を候補とする。ただし Target Encoding は fold 内で計算する。

カテゴリ変数では、まず順序の有無を確認します。 性別、疾患名、施設 ID には自然な順序がありません。 介助量の段階や重症度分類には順序があります。 順序のないカテゴリを 0, 1, 2 と置くと、 モデルが架空の大小関係を学ぶ場合があります。

// 04 · CLINICALリハ研究で起きやすい前処理の場面

// CASE 1 · 入院時 FIM 合計点が 7 点未満

FIM 合計点は 18〜126 点の範囲です。 そのため、7 点未満の値は通常の範囲外です。 まず入力ミス、合計方法、欠損コードを確認します。 ただし、低値だから機械的に削除するのではありません。 評価尺度の定義とデータ辞書を照合します。

// CASE 2 · 多施設データの施設 ID

施設 ID は、回復期病棟の方針、測定機器、 患者背景の違いを含むことがあります。 One-Hot Encoding では列数が増えます。 Target Encoding は列数を抑えられますが、 目的変数の情報を使うためリーケージに注意します。 fold 内で fit する設計が前提になります。

// CASE 3 · 歩行速度に 5 m/s が紛れる

歩行速度 5 m/s は、臨床データでは異常に高い値です。 単位の誤り、センサー異常、切り出しミスを確認します。 明らかな機器エラーなら除外候補になります。 一方で、上限値に丸める Winsorize も選択肢です。 どの扱いにしたかを Methods に残します。

// CASE 4 · 薬剤名フリーテキスト

電子カルテの薬剤名は表記揺れが起きます。 同じ薬剤でも、略称、商品名、一般名が混在します。 まず辞書で正規化します。 その後、出現頻度を使う Frequency Encoding や、 薬効分類への集約を検討します。

// 05 · THEORY外れ値・エンコード・標準化の考え方

外れ値検出には、統計的な基準があります。 箱ひげ図、Z-score、IQR、Mahalanobis 距離などです。 ただし、外れ値検出は診断ではありません[1]。 「見つける」ことと「除外する」ことは分けます。

Z-score は、平均から何標準偏差離れているかを見ます。 分布が大きく歪む変数では、過度に反応することがあります。 IQR は四分位範囲を用いるため、 外れ値の影響を受けにくい方法です。 Mahalanobis 距離は、多変量の外れ方を見ます。

Z-score:
  z = (x - mean) / sd

IQR rule:
  lower = Q1 - 1.5 * IQR
  upper = Q3 + 1.5 * IQR
  IQR   = Q3 - Q1

Mahalanobis distance:
  D2 = (x - mean_vector)' S_inverse (x - mean_vector)

外れ値への対応には、複数の選択肢があります。 明らかな入力ミスなら修正または除外を検討します。 臨床的にあり得る極端値なら残します。 分布の歪みが問題なら log 変換や平方根変換を使います。 上下限に丸める Winsorize も選択肢です。

カテゴリ変数は、数値への置き換えが必要です。 One-Hot Encoding は、カテゴリごとに 0/1 列を作ります。 順序のない少数カテゴリで扱いやすい方法です。 ただし、施設 ID のようにカテゴリ数が多いと、 列数が増え、過学習しやすくなります。

Ordinal Encoding は、順序のあるカテゴリに向きます。 たとえば「自立、監視、軽介助、中等度介助」などです。 ただし、段階間の距離が等しいとは限りません。 数値化した後も、臨床的な意味を確認します。

Target Encoding:
  encoded(category c) = mean(y | category = c)

Smoothed Target Encoding:
  encoded(c) = (n_c * mean_c + alpha * global_mean) / (n_c + alpha)

Leakage risk:
  If mean_c is calculated using the validation fold,
  information from y_validation enters X_validation.

Target Encoding は、カテゴリごとの目的変数平均を使います[5]。 施設 ID のような高カードカテゴリで便利です。 しかし、目的変数を使うため注意が必要です。 validation fold の y を使って変換すると、 評価データの答えを前処理に混ぜることになります。

標準化では、代表的に以下を使います。 StandardScaler は平均 0、標準偏差 1 に変換します。 MinMaxScaler は範囲を 0〜1 にそろえます。 RobustScaler は中央値と IQR を使います。 QuantileTransformer は分布の形を変えます。 PowerTransformer は歪んだ分布を緩和します。

StandardScaler:
  z = (x - mu) / sigma

MinMaxScaler:
  x_scaled = (x - x_min) / (x_max - x_min)

RobustScaler:
  x_scaled = (x - median) / IQR

標準化の選択では、分布の形も見ます。 FIM 合計点のように上限と下限が決まる尺度と、 訓練量のように右に裾を引く尺度では、 同じ変換が合うとは限りません。 PowerTransformer や QuantileTransformer は、 分布を大きく変えるため、解釈性も確認します。 変換後の係数や重要度を、元の単位に戻して説明できるかも大切です。

どのモデルで標準化が重要かも整理します。 線形回帰、ロジスティック回帰、kNN、SVM、 ニューラルネットワークでは尺度の影響が出ます。 特に正則化を使う線形モデルでは、 標準化しないと係数の比較が難しくなります。

一方で、Random Forest や勾配ブースティングなどの木系モデルは、 分割のしきい値で学習します。 そのため、単調な尺度変換の影響は小さいことが多いです。 ただし、前処理の一貫性や他モデルとの比較のため、 Pipeline の中で設計を明示しておくことは有用です。

// 06 · IMPLEMENTATIONPipeline で安全に前処理する

実装では、前処理を pandas で全データに当ててから train / test に分ける流れを避けます。 scaler、imputer、encoder は、 すべて Pipeline の中で fit します。 これにより、交差検証の各 fold でも、 train fold 内だけで前処理が学習されます。

# 教育用の仮想データ example_rehab_dataset.csv を想定します。
# 実データでは、個人情報保護、倫理審査、施設ルール、
# データ利用規約を確認したうえで解析環境に置いてください。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler, RobustScaler, QuantileTransformer

# 1. データ読み込み
df = pd.read_csv("example_rehab_dataset.csv")

# 2. 予測時点を確認して列を選ぶ
# 例: 入院時に歩行自立を予測する設定
# 退院時 FIM や退院後追跡データは説明変数から外します。
target = "walk_independent_discharge"
numeric_cols = [
    "age", "fim_total_admission", "sias_lower_admission",
    "grip_strength_admission", "gait_speed_admission",
]
categorical_cols = ["sex", "stroke_type", "facility_id"]
X = df[numeric_cols + categorical_cols].copy()
y = df[target].astype(int)

# 3. 全体像の確認は記述統計に留める
print(df[numeric_cols].describe())
print(df[categorical_cols].nunique())
print(df.isna().mean().sort_values(ascending=False).head(10))

# 4. 外れ値候補を臨床的範囲で確認する
clinical_flags = pd.DataFrame(index=df.index)
clinical_flags["fim_range_error"] = ~df["fim_total_admission"].between(18, 126)
clinical_flags["gait_speed_high"] = df["gait_speed_admission"] > 3.0
clinical_flags["age_high"] = df["age"] > 105
print(clinical_flags.sum())

# 5. 箱ひげ図は探索用に使う
for col in numeric_cols:
    ax = df.boxplot(column=col)
    ax.set_title(col)
    plt.savefig(f"boxplot_{col}.png", dpi=150, bbox_inches="tight")
    plt.close()

# 6. NG 例: 全データで scaler を fit してから split しない
# scaler = StandardScaler()
# X_scaled = scaler.fit_transform(X[numeric_cols])  # validation 情報が混入
# X_train, X_test, y_train, y_test = train_test_split(X_scaled, y)

# 7. カテゴリ列は One-Hot Encoding にする
categorical_onehot = Pipeline(steps=[
    ("imputer", SimpleImputer(strategy="most_frequent")),
    ("onehot", OneHotEncoder(handle_unknown="ignore")),
])

# 8. 数値 scaler を差し替えながら比較する関数
def build_pipe(scaler):
    numeric_pipe = Pipeline(steps=[
        ("imputer", SimpleImputer(strategy="median")),
        ("scaler", scaler),
    ])
    preprocess = ColumnTransformer(transformers=[
        ("num", numeric_pipe, numeric_cols),
        ("cat", categorical_onehot, categorical_cols),
    ])
    pipe = Pipeline(steps=[
        ("preprocess", preprocess),
        ("model", LogisticRegression(max_iter=2000, class_weight="balanced")),
    ])
    return pipe

# 9. train / test 分割後、fit は train 側だけで行う
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)
pipe_standard = build_pipe(StandardScaler())
pipe_standard.fit(X_train, y_train)
prob = pipe_standard.predict_proba(X_test)[:, 1]
print("test_auc", roc_auc_score(y_test, prob))

# 10. CV では fold ごとに preprocess が fit される
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(pipe_standard, X, y, cv=cv, scoring="roc_auc")
print("standard_cv_auc_mean", scores.mean())
print("standard_cv_auc_sd", scores.std())

# 11. RobustScaler と QuantileTransformer を同じ構造で比較する
scaler_candidates = {
    "standard": StandardScaler(),
    "robust": RobustScaler(),
    "quantile_normal": QuantileTransformer(
        output_distribution="normal", random_state=42
    ),
}
for name, scaler in scaler_candidates.items():
    candidate_pipe = build_pipe(scaler)
    auc = cross_val_score(candidate_pipe, X, y, cv=cv, scoring="roc_auc")
    print(name, auc.mean(), auc.std())

# 12. Target Encoding を使う場合の注意
# 目的変数を使う変換は、validation fold の y を使わない設計にします。
# 専用ライブラリを使う場合も、CV 内 fit になっているか確認します。

# 13. 同一患者の複数評価がある場合
# patient_id が複数行に出る設計では、GroupKFold を検討します。
# 同じ患者が train と validation に分かれないようにします。

この例では、数値列とカテゴリ列を分けています。 数値列には中央値補完と標準化を行います。 カテゴリ列には最頻値補完と One-Hot Encoding を行います。 どちらも ColumnTransformer に入れてから、 LogisticRegression と Pipeline でつないでいます。

RobustScaler や QuantileTransformer の比較も、 同じ Pipeline 構造で行います。 重要なのは、scaler だけを先に全データで fit しないことです[3]。 外れ値処理、カテゴリ変換、標準化は、 モデル評価と一体で設計します。

Target Encoding や Frequency Encoding は、 高カードカテゴリを扱うときの候補になります。 ただし、薬剤名や施設 ID は、 患者背景や診療体制を強く反映します。 そのため、単なる圧縮手法として扱わず、 何を表す変数なのかを Methods で説明します。 多施設研究では、施設を調整因子として扱うのか、 外部妥当性を確認する単位として扱うのかも整理します。

// 07 · MYTHSよくある誤解

誤解 1:外れ値は全部除外した方がよい
外れ値には、入力ミスと臨床的に重要な極端例があります。 脳卒中の重症例、超高齢者、重度低 FIM 例は、 研究対象として重要な場合があります。 除外は、定義と理由を記録してから検討します。
誤解 2:Target Encoding はリーケージしない
Target Encoding は目的変数を使います。 validation fold の y を使ってカテゴリ平均を計算すると、 評価データの答えを説明変数に混ぜることになります。 out-of-fold で計算する設計が必要です。
誤解 3:すべての変数で標準化が必要
標準化の必要性はモデルに依存します。 線形モデル、kNN、SVM、NN では重要です。 Random Forest や勾配ブースティングでは、 多くの場合、標準化の影響は限定的です。
誤解 4:One-Hot Encoding ならカテゴリ変数は安全
カテゴリ数が多いと列数が増えます。 多施設データや薬剤名では、次元増加により 過学習しやすくなることがあります。 Frequency Encoding や集約カテゴリも候補になります。

// 08 · WRITING論文 Methods で書くこと

前処理は、論文では短く書かれがちです。 しかし、外れ値、カテゴリ変数、標準化は、 性能評価と再現性に直結します。 TRIPOD+AI でも、データ処理と予測モデルの再現性は 重要な報告項目として扱われます[6]

  • 外れ値の定義を記載します。例: IQR、臨床的範囲、単位確認。
  • 除外、Winsorize、変換、外れ値フラグの扱いを記載します。
  • カテゴリ変数のエンコード方法を記載します。
  • 高カードカテゴリの扱いを記載します。
  • 標準化の方法と対象モデルを記載します。
  • Scaler / Encoder を train fold 内で fit したことを記載します。
  • 感度分析を行った場合は、その条件を記載します。

査読では、外れ値の扱いがよく問われます。 特に、除外後に性能が改善した場合は注意が必要です。 入力ミスを除いたのか、重症例を除いたのかで、 研究の意味が変わります。 除外例の数と理由を示すと、解釈しやすくなります。

Target Encoding を使った場合は、 out-of-fold で算出したことを明記します。 全データでカテゴリ平均を計算すると、 データリーケージを疑われます。 詳細は 09·02 データリーケージとは何かと、 02·06 データリーケージを防ぐ前処理で扱います。

標準化の有無も、モデルごとに説明します。 線形回帰ロジスティック回帰では、 正則化や係数解釈に関係します。 k近傍法では、 距離計算そのものに影響します。

// 09 · CHECKLIST前処理前の確認リスト

  • 01各数値列について、単位と臨床的にあり得る範囲を確認した。
  • 02箱ひげ図、ヒストグラム、IQR で外れ値候補を確認した。
  • 03外れ値を入力ミス、測定誤差、臨床的極端例に分けて記録した。
  • 04カテゴリ変数について、順序の有無を確認した。
  • 05高カードカテゴリの列数増加を確認した。
  • 06Target Encoding を使う場合、fold 内 fit の設計にした。
  • 07モデルに応じて、標準化の必要性を確認した。
  • 08Scaler と Encoder を Pipeline / ColumnTransformer に入れた。

// 10 · QUIZ理解度チェック

  1. Q1FIM 合計点に 7 点という値がありました。最初に行うこととして適切なのはどれですか。
    • 低値なので除外する
    • 外れ値として平均値に置き換える
    • 尺度の範囲、入力ミス、欠損コードを確認する
    • 標準化すれば問題ない
    SHOW ANSWER
    C. 外れ値候補は、まず定義と臨床的意味を確認します。
  2. Q2Target Encoding で最も注意する点はどれですか。
    • カテゴリ数が 2 つだと使えない
    • 目的変数を使うため、fold 内で計算する
    • 数値列にしか使えない
    • 木系モデルでは必ず必要になる
    SHOW ANSWER
    B. validation の y を変換に使うとリーケージします。
  3. Q3StandardScaler が特に重要になりやすいモデルはどれですか。
    • kNN
    • Random Forest
    • 決定木単体
    • ルールベース分類
    SHOW ANSWER
    A. kNN は距離に基づくため、尺度差の影響を受けます。
  4. Q4歩行速度 5 m/s が見つかった場合の説明として適切なのはどれですか。
    • 外れ値なので理由に関係なく削除する
    • まず単位、測定機器、切り出し方法を確認する
    • 平均値で補完する
    • One-Hot Encoding する
    SHOW ANSWER
    B. 外れ値候補は、機器エラーか臨床的値かを分けて考えます。

// REF参考文献

  1. Kuhn M, Johnson K. Feature Engineering and Selection: A Practical Approach for Predictive Models. CRC Press, 2019.
  2. Harrell FE Jr. Regression Modeling Strategies. 2nd ed. Springer, 2015.
  3. Pedregosa F, Varoquaux G, Gramfort A, Michel V, Thirion B, Grisel O, et al. Scikit-learn: Machine learning in Python. Journal of Machine Learning Research 2011;12:2825-2830.
  4. Hastie T, Tibshirani R, Friedman J. The Elements of Statistical Learning. 2nd ed. Springer, 2009.
  5. Micci-Barreca D. A preprocessing scheme for high-cardinality categorical attributes in classification and prediction problems. ACM SIGKDD Explorations Newsletter 2001;3(1):27-32.
  6. Collins GS, Moons KGM, Dhiman P, Riley RD, Beam AL, Van Calster B, et al. TRIPOD+AI statement: updated guidance for reporting clinical prediction models that use regression or machine learning methods. BMJ 2024;385:e078378.