0Pricing
Machine Learning Academy · レッスン

特徴量のスケーリング:StandardScalerとMinMaxScaler

訓練データにStandardScalerとMinMaxScalerを適合させ、テストデータを個別に変換して、テストデータで適合させるとデータリーケージが起きる理由を理解します。

「特徴量のスケーリング:StandardScalerとMinMaxScaler」はCoddyKit上の無料Machine Learning Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはMachine Learning Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Machine Learning Academyコースには全4レッスンが含まれています。

このレッスンの一部はまだ翻訳されておらず、英語で表示されています。

Why Feature Scaling Matters

Many machine learning algorithms are sensitive to the scale of input features. If one feature spans 0–1000 and another spans 0–1, distance-based models like KNN and SVM will be dominated by the larger-scale feature. Gradient descent algorithms also converge much faster when features share a similar scale. Tree-based models like Random Forests and XGBoost are scale-invariant and do not require scaling, but almost every other algorithm benefits from it.

import numpy as np

# Without scaling: 'income' dominates 'age'
X = np.array([
    [25, 50000],
    [35, 80000],
    [45, 120000]
])

# Distance between row 0 and row 1 (Euclidean)
dist = np.sqrt((25-35)**2 + (50000-80000)**2)
print('Distance dominated by income:', dist)
# age contributes 100, income contributes 900,000,000 to squared distance

StandardScaler: Z-Score Normalisation

StandardScaler transforms each feature to have zero mean and unit variance by applying the formula: z = (x - mean) / std. This is called standardisation or z-score normalisation. The resulting values are centred around 0 with no fixed range. StandardScaler is the default choice for most algorithms including logistic regression, SVMs, and neural networks, especially when the feature distribution is approximately Gaussian.

from sklearn.preprocessing import StandardScaler
import numpy as np

X = np.array([[25, 50000], [35, 80000], [45, 120000]], dtype=float)

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print('Scaled data:\n', X_scaled)
print('Mean per feature:', X_scaled.mean(axis=0))  # ~[0, 0]
print('Std per feature:', X_scaled.std(axis=0))    # ~[1, 1]

How StandardScaler Stores Statistics

After calling fit(), StandardScaler stores the training-set statistics in scaler.mean_ and scaler.scale_ (standard deviation). These same statistics are used when you call transform() on new data — meaning the test set is scaled using training set parameters, not its own. This is the correct behaviour: in production, you receive individual samples one at a time and must scale them using the statistics computed during training.

from sklearn.preprocessing import StandardScaler
import numpy as np

X_train = np.array([[1, 200], [2, 400], [3, 600]], dtype=float)
X_test  = np.array([[4, 800]], dtype=float)

scaler = StandardScaler()
scaler.fit(X_train)  # Learn mean and std from training data ONLY

print('Learned mean:', scaler.mean_)
print('Learned scale:', scaler.scale_)

X_train_s = scaler.transform(X_train)
X_test_s  = scaler.transform(X_test)  # Uses SAME training statistics
print('Test scaled:', X_test_s)

MinMaxScaler: Rescaling to a Fixed Range

MinMaxScaler compresses each feature to a specified range, typically [0, 1], using the formula: x_scaled = (x - x_min) / (x_max - x_min). Unlike StandardScaler, it preserves the relative shape of the distribution and handles non-Gaussian data well. It is sensitive to outliers: a single extreme value can squish all other values near zero or one. MinMaxScaler is popular for neural networks and image pixel values (scaled to [0, 1]).

from sklearn.preprocessing import MinMaxScaler
import numpy as np

X = np.array([[10], [20], [30], [40], [50]], dtype=float)

scaler = MinMaxScaler(feature_range=(0, 1))
X_scaled = scaler.fit_transform(X)

print('MinMax scaled:', X_scaled.flatten())
# [0.0, 0.25, 0.5, 0.75, 1.0]

# Custom range: scale to [-1, 1]
scaler2 = MinMaxScaler(feature_range=(-1, 1))
print('[-1,1] scaled:', scaler2.fit_transform(X).flatten())

RobustScaler: Handling Outliers

RobustScaler scales using the median and interquartile range (IQR) instead of mean and standard deviation. Because median and IQR are not influenced by extreme values, RobustScaler is a better choice when your data contains significant outliers. The formula is: x_scaled = (x - median) / IQR. Use RobustScaler when you cannot remove outliers and want them to have minimal influence on the scaled values passed to your model.

from sklearn.preprocessing import RobustScaler
import numpy as np

# Data with outlier at 1000
X = np.array([[1], [2], [3], [4], [1000]], dtype=float)

from sklearn.preprocessing import StandardScaler, RobustScaler

std_s = StandardScaler().fit_transform(X)
rob_s = RobustScaler().fit_transform(X)

print('StandardScaler (outlier squishes others):')
print(std_s.flatten())
print('RobustScaler (outlier isolated):')
print(rob_s.flatten())

Choosing the Right Scaler

Here is a quick decision guide: use StandardScaler when your data is roughly Gaussian and you have no extreme outliers — it is the safest default. Use MinMaxScaler when you need values in a fixed range, such as for image data or algorithms that require [0, 1] inputs. Use RobustScaler when outliers are present and meaningful (e.g., financial data with fraud spikes). For tree-based models (Random Forest, XGBoost, LightGBM), skip scaling entirely — it offers no benefit and adds unnecessary complexity.

from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

# Decision helper
def pick_scaler(has_outliers, needs_fixed_range, is_tree_model):
    if is_tree_model:
        return 'No scaling needed'
    elif has_outliers:
        return 'RobustScaler'
    elif needs_fixed_range:
        return 'MinMaxScaler'
    else:
        return 'StandardScaler'

print(pick_scaler(False, False, False))  # StandardScaler
print(pick_scaler(True, False, False))   # RobustScaler
print(pick_scaler(False, True, False))   # MinMaxScaler
print(pick_scaler(False, False, True))   # No scaling needed

Fitting on Test Data: The Leakage Trap

A common mistake is calling fit_transform() on the test set, which computes a new mean and standard deviation from test data. This is a form of data leakage because the scaler is influenced by test-set values. The correct pattern is: fit(X_train) → transform(X_train) → transform(X_test). Even a small accuracy improvement from this leak can lead to overconfident production deployments that fail on truly unseen data.

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import numpy as np

X = np.random.randn(100, 3)
y = (X[:, 0] > 0).astype(int)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

scaler = StandardScaler()

# CORRECT: fit on train, transform both
scaler.fit(X_train)
X_train_s = scaler.transform(X_train)
X_test_s  = scaler.transform(X_test)

# WRONG (leakage):
# scaler.fit_transform(X_test)  <- never do this

Scaling Inside a Pipeline

The cleanest way to avoid scaling leakage is to embed the scaler inside a scikit-learn Pipeline. When the pipeline is fitted with cross_val_score or GridSearchCV, each fold fits the scaler only on the training portion of that fold. The test fold is never touched during fitting. This is the production-ready pattern: preprocessing and modelling steps are bundled together, making deployment as simple as calling pipeline.predict(X_new).

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('clf', LogisticRegression(max_iter=200))
])

# Scaler fitted only on train fold in each CV iteration
scores = cross_val_score(pipe, X, y, cv=5)
print('CV accuracy:', scores.mean().round(3))

Inverse Transform: Back to Original Scale

After making predictions, you may need to convert predictions back to the original scale — for example, a house-price model trained on log-scaled prices must output prices in dollars. Both StandardScaler and MinMaxScaler provide inverse_transform() to reverse the scaling. Only inverse-transform the target variable when it was scaled before training. Features do not typically need to be inverse-transformed because they are consumed internally by the model.

from sklearn.preprocessing import StandardScaler
import numpy as np

y_train = np.array([100000, 200000, 300000, 400000], dtype=float).reshape(-1, 1)

target_scaler = StandardScaler()
y_scaled = target_scaler.fit_transform(y_train)
print('Scaled target:', y_scaled.flatten())

# After predicting in scaled space:
y_pred_scaled = np.array([[0.5]])
y_pred_original = target_scaler.inverse_transform(y_pred_scaled)
print('Prediction in original scale:', y_pred_original)

Scaling Sparse Data with MaxAbsScaler

Sparse matrices — common in text classification with TF-IDF vectors — should not be scaled with StandardScaler or MinMaxScaler because centering destroys sparsity by making most zeros non-zero, which defeats the purpose of sparse storage. MaxAbsScaler scales each feature by its maximum absolute value, mapping values to the range [-1, 1] without centering, and preserves the sparsity structure. Always use MaxAbsScaler when working with sparse feature matrices from vectorisers like TfidfVectorizer.

from sklearn.preprocessing import MaxAbsScaler
from scipy.sparse import csr_matrix
import numpy as np

# Simulated sparse TF-IDF matrix
X_sparse = csr_matrix(np.array([
    [0, 0.5, 0.3, 0],
    [0.8, 0, 0, 0.4],
    [0, 0.2, 0, 0.6]
]))

scaler = MaxAbsScaler()
X_scaled = scaler.fit_transform(X_sparse)
print('Scaled sparse matrix:\n', X_scaled.toarray())
# All values in [-1, 1], sparsity preserved

Comparing Scalers on Real Data

To see the practical effect of each scaler, compare their output distributions side by side. After scaling, StandardScaler output should be approximately N(0,1), MinMaxScaler output should span [0,1], and RobustScaler output should have median at 0 with IQR of 1. Plotting histograms before and after scaling confirms the transformation worked correctly. Good feature scaling is a prerequisite for reliable model training, not an optional add-on.

import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
import numpy as np

X = np.random.exponential(scale=100, size=(200, 1))  # Skewed data

scalers = {
    'StandardScaler': StandardScaler(),
    'MinMaxScaler': MinMaxScaler(),
    'RobustScaler': RobustScaler()
}

fig, axes = plt.subplots(1, 4, figsize=(16, 4))
axes[0].hist(X, bins=30); axes[0].set_title('Original')
for ax, (name, sc) in zip(axes[1:], scalers.items()):
    ax.hist(sc.fit_transform(X), bins=30)
    ax.set_title(name)
plt.tight_layout()
plt.show()

Quick Check

Test your understanding of Machine Learning with Python concepts from this lesson.

Lesson Recap

In this lesson you learned: why feature scaling is essential for distance-based and gradient-descent algorithms, how StandardScaler standardises to N(0,1) while MinMaxScaler compresses to [0,1], and the critical rule of fitting scalers only on training data to prevent leakage. Next up we explore encoding categorical variables with OrdinalEncoder and OneHotEncoder.

よくある質問

「特徴量のスケーリング:StandardScalerとMinMaxScaler」レッスンは無料ですか?

はい。「特徴量のスケーリング:StandardScalerとMinMaxScaler」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Machine Learning Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Machine Learning Academyコースには全4レッスンが含まれています。

「特徴量のスケーリング:StandardScalerとMinMaxScaler」で何を学びますか?

訓練データにStandardScalerとMinMaxScalerを適合させ、テストデータを個別に変換して、テストデータで適合させるとデータリーケージが起きる理由を理解します。 ブラウザで直接実行するハンズオンコードでMachine Learning Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Machine Learning Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのMachine Learning Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「特徴量のスケーリング:StandardScalerとMinMaxScaler」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このMachine Learning Academyレッスンでコードを書いて実行できますか?

はい。すべてのMachine Learning Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 欠損値への対処:削除、補完、フラグ付け
  2. 特徴量のスケーリング:StandardScalerとMinMaxScaler
  3. カテゴリ変数のエンコード:OrdinalEncoderとOneHotEncoder
  4. ColumnTransformerによる処理の組み合わせ
← Machine Learning Academyに戻る