Python Scikit-learn MinMaxScalerの基本!使い方をサンプルコードで徹底解説

Python

機械学習のモデルを構築する際、データの前処理はモデルの精度を大きく左右する非常に重要なステップです。特に、各特徴量(データセットの各列)のスケールがバラバラだと、アルゴリズムによっては学習がうまくいかないことがあります。

この記事では、そんなデータの前処理手法の一つである「正規化(Normalization)」を簡単に行える、Pythonの機械学習ライブラリScikit-learnMinMaxScalerに焦点を当てます。

この記事を最後まで読めば、以下のことができるようになります。

  • MinMaxScalerとは何か、なぜ必要なのかが分かる
  • MinMaxScalerの基本的な使い方をマスターできる
  • 初心者が混同しがちなfit_transform()transform()の違いを明確に理解できる
  • 実務でよく使うPandasデータフレームでの応用方法が分かる
  • スケーリングしたデータを元の値に戻す方法が分かる

サンプルコードを豊富に交えながら、初心者の方でもつまずかないように丁寧に解説していきますので、ぜひ一緒に手を動かしながら学んでいきましょう。

はじめに:MinMaxScalerとは?なぜデータの前処理に必要なのか

MinMaxScalerとは、データセットの各特徴量を、指定した範囲内(デフォルトでは0から1)に収まるように変換(スケーリング)するための機能です。 この処理は一般的に「正規化」と呼ばれます。

数式で表すと、各データxは以下の式で変換されます。

Xscaled​=Xmax​−Xmin​X−Xmin​​

これにより、元のデータセットで最小値だった値は0に、最大値だった値は1に変換され、その他の値はその間の数値に収まります。

では、なぜこのような処理が必要なのでしょうか。 それは、特徴量ごとのスケール(単位や大きさ)が異なると、モデルの学習に悪影響を与える可能性があるからです。

例えば、「年齢」(10〜80)と「年収」(300万〜2000万)という2つの特徴量があったとします。数値の範囲が全く異なるため、年収の方がモデルへの影響が不当に大きくなってしまう可能性があります。

MinMaxScalerを使って両方の特徴量を0〜1の範囲に揃えることで、モデルは各特徴量を公平に評価できるようになり、結果として予測精度の向上が期待できるのです。

MinMaxScalerの基本的な使い方【サンプルコード付き】

MinMaxScalerの基本的な使い方は、インスタンスを作成し、fit()で学習させ、transform()でデータを変換するという3ステップです。

まずは最もシンプルなNumPy配列を使った例で、一連の流れを見ていきましょう。

準備:ライブラリのインポートとサンプルデータの作成

最初に、必要なライブラリMinMaxScalerNumPyをインポートし、解説用のサンプルデータを作成します。

import numpy as np
from sklearn.preprocessing import MinMaxScaler

# サンプルデータを作成 (2次元配列)
# 年齢と年収を想定したデータ
data = np.array([[25, 400], 
                 [35, 600], 
                 [45, 800], 
                 [20, 350], 
                 [60, 1200]])

print("変換前のデータ:")
print(data)

この時点での出力は以下のようになります。

変換前のデータ:
[[  25  400]
 [  35  600]
 [  45  800]
 [  20  350]
 [  60 1200]]Code language: CSS (css)

MinMaxScalerのインスタンス化と学習

次に、MinMaxScalerのインスタンスを作成します。今回はデフォルトの0〜1の範囲にスケーリングします。そして、作成したdatafit()メソッドに渡して「学習」させます。

fit()は、データ変換に必要な各特徴量の最小値と最大値を計算し、記憶する処理です。

# MinMaxScalerのインスタンスを作成
scaler = MinMaxScaler()

# データの最小値と最大値を学習
scaler.fit(data)

# 学習した最小値と最大値を確認
print("各特徴量の最小値:", scaler.min_)
print("各特徴量の最大値:", scaler.scale_)

データの変換(スケーリング)

最後に、学習済みのscalerを使ってtransform()メソッドを呼び出し、データを実際に変換します。

# データを0-1の範囲に変換
scaled_data = scaler.transform(data)

print("\n変換後のデータ:")
print(scaled_data)

実行すると、すべての値が0から1の範囲に収まっていることが確認できます。

変換後のデータ:
[[0.125      0.05882353]
 [0.375      0.29411765]
 [0.625      0.52941176]
 [0.         0.        ]
 [1.         1.        ]]Code language: CSS (css)

1列目(年齢)を見ると、最小値だった200に、最大値だった601に変換されています。同様に2列目(年収)も、最小値の3500、最大値の12001に変換されているのが分かりますね。

fit_transform()とtransform()の使い分け

結論から言うと、fit_transform()は学習と変換を同時に行い、transform()は学習済みの情報で変換のみを行います。 この違いの理解は、機械学習モデルを正しく構築する上で非常に重要です。

機械学習では、データを「訓練データ(モデルの学習用)」と「テストデータ(モデルの評価用)」に分けて扱います。このとき、テストデータは訓練データと全く同じ基準で変換しなければなりません。

fit_transform(): 学習と変換を一度に行う

fit()transform()を別々に行うのは少し手間です。fit_transform()メソッドを使えば、この2つの処理を一度に実行できます。

訓練データに対しては、基本的にこのfit_transform()を使います。

from sklearn.model_selection import train_test_split

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(data, np.array([0, 1, 1, 0, 1]), test_size=0.3, random_state=42)

# --- 訓練データに対する処理 ---
# スケーラーをインスタンス化
scaler_train = MinMaxScaler()

# 訓練データの学習と変換を同時に行う
X_train_scaled = scaler_train.fit_transform(X_train)

print("変換前の訓練データ:")
print(X_train)
print("\nfit_transform後の訓練データ:")
print(X_train_scaled)

transform(): 学習済みモデルで新しいデータを変換する

一方、テストデータを変換する際は絶対にfit()fit_transform()を使ってはいけません。 なぜなら、テストデータの最小値・最大値で学習し直すと、訓練データとは異なる変換基準になってしまうからです。

テストデータは、あくまで訓練データで学習したscalerを使って、transform()で変換するだけ、と覚えてください。

# --- テストデータに対する処理 ---
# "訓練データで学習した"scalerを使ってテストデータを変換する
X_test_scaled = scaler_train.transform(X_test)

print("\n変換前のテストデータ:")
print(X_test)
print("\ntransform後のテストデータ:")
print(X_test_scaled)

これにより、訓練データとテストデータの両方が同じ基準でスケーリングされ、モデルを公平に評価することができます。

【実践】PandasデータフレームでMinMaxScalerを使う方法

Pandasのデータフレームでも基本的な使い方は同じですが、スケーリング後の返り値がNumPy配列になり、カラム名やインデックスが失われる点に注意が必要です。

実務ではNumPy配列よりもPandasデータフレームを扱うことの方が多いため、ここでの使い方をしっかりマスターしておきましょう。

Pandasデータフレームの準備

まず、Pandasをインポートしてサンプルデータフレームを作成します。

import pandas as pd

df = pd.DataFrame({
    'Age': [25, 35, 45, 20, 60],
    'Department': ['Sales', 'Marketing', 'IT', 'Sales', 'IT'],
    'Salary': [400, 600, 800, 350, 1200]
})

print("元のDataFrame:")
print(df)

データフレーム全体をスケーリングする

数値データが含まれる列全体をスケーリングしてみます。 MinMaxScalerは数値以外の列(この例では’Department’)を無視して処理してくれますが、fit_transformの返り値はNumPy配列になることに注意してください。

# 数値列だけを選択
numeric_cols = df.select_dtypes(include=np.number).columns

# スケーラーのインスタンス化
scaler_df = MinMaxScaler()

# fit_transformを適用し、結果を新しいDataFrameに格納
# カラム名とインデックスを再設定する
scaled_values = scaler_df.fit_transform(df[numeric_cols])

df_scaled = pd.DataFrame(scaled_values, columns=numeric_cols, index=df.index)

# 元のDataFrameの数値列を置き換える
df[numeric_cols] = df_scaled

print("\nスケーリング後のDataFrame:")
print(df)

実行結果

スケーリング後のDataFrame:
        Age Department    Salary
0  0.125000      Sales  0.058824
1  0.375000  Marketing  0.294118
2  0.625000         IT  0.529412
3  0.000000      Sales  0.000000
4  1.000000         IT  1.000000Code language: CSS (css)

このように、pd.DataFrame()を使ってカラム名とインデックスを再設定することで、データフレームの形式を維持できます。

特定の列だけをスケーリングする

特定の列、例えば'Salary'だけをスケーリングしたい場合もよくあります。その場合は、対象の列を選択してfit_transformを適用します。

列を選択する際は、df[['Salary']]のように角括弧を二重にするのがポイントです。これにより、データが2次元配列として扱われ、MinMaxScalerに入力できます。

# 元のデータを再作成
df = pd.DataFrame({
    'Age': [25, 35, 45, 20, 60],
    'Department': ['Sales', 'Marketing', 'IT', 'Sales', 'IT'],
    'Salary': [400, 600, 800, 350, 1200]
})


# 'Salary'列だけをスケーリング
scaler_salary = MinMaxScaler()

# fit_transformの結果を元の列に代入
df['Salary_scaled'] = scaler_salary.fit_transform(df[['Salary']])

print("\n特定の列だけをスケーリングしたDataFrame:")
print(df)

結果

特定の列だけをスケーリングしたDataFrame:
   Age Department  Salary  Salary_scaled
0   25      Sales     400       0.058824
1   35  Marketing     600       0.294118
2   45         IT     800       0.529412
3   20      Sales     350       0.000000
4   60         IT    1200       1.000000Code language: CSS (css)

元の列を残しつつ、新しい列としてスケーリング結果を追加することも簡単です。

スケーリングしたデータを元に戻す方法:inverse_transform

inverse_transform()メソッドを使えば、正規化したデータを元のスケールに戻すことができます。

これは、例えば機械学習モデルで予測した結果(0〜1の範囲)を、実際の単位(円や個数など)に戻して解釈したい場合などに非常に便利です。

inverse_transformは、学習(fit)に使用したのと同じscalerインスタンスに対して使う必要があります。

# 先ほど'Salary'をスケーリングしたscaler_salaryを使用
scaled_salary_data = df[['Salary_scaled']]

# inverse_transformで元のスケールに戻す
original_salary_data = scaler_salary.inverse_transform(scaled_salary_data)

print("\nスケーリングされたデータ:")
print(scaled_salary_data.values)
print("\n元のスケールに戻したデータ:")
print(original_salary_data)

結果

スケーリングされたデータ:
[[0.05882353]
 [0.29411765]
 [0.52941176]
 [0.        ]
 [1.        ]]

元のスケールに戻したデータ:
[[ 400.]
 [ 600.]
 [ 800.]
 [ 350.]
 [1200.]]Code language: CSS (css)

見事に元の年収データに戻っていることが確認できました。

まとめ:MinMaxScalerを使いこなして機械学習モデルの精度を向上させよう

今回は、Scikit-learnのMinMaxScalerについて、その基本から実践的な使い方までを解説しました。最後に、重要なポイントを振り返りましょう。

  • MinMaxScalerは、特徴量のスケールを0〜1の範囲に揃える「正規化」を行う。
  • スケールを揃えることで、機械学習モデルの精度向上が期待できる。
  • 基本的な流れはfit()で学習し、transform()で変換する。
  • 訓練データには学習と変換を同時に行うfit_transform()を使う。
  • テストデータには、訓練データで学習したスケーラーを使いtransform()のみを行う。
  • Pandasデータフレームで使うと返り値がNumPy配列になるため、カラム名などの再設定が必要。
  • inverse_transform()を使えば、スケーリングしたデータを元のスケールに戻せる

データの前処理は、機械学習プロジェクトの中でも地味な作業ですが、モデルの性能を最大限に引き出すためには欠かせない工程です。

この記事が、あなたのデータ分析・機械学習ライフの一助となれば幸いです。ぜひ、ご自身のデータセットでMinMaxScalerを試してみてください。

コメント

タイトルとURLをコピーしました