Python転職初心者向けエンジニアリングブログ

Pythonに魅了されたあなたへ。エンジニアリングの扉を開く転職初心者向けのブログへようこそ。このブログでは、Pythonの奥深さに迫りながら、エンジニアリングへの転職に役立つ情報を提供しています。未経験者から始めるPythonエンジニアリングの世界への一歩を踏み出すためのガイダンス、ベストプラクティス、そして成功事例など、初心者の方でもわかりやすいコンテンツをお届けします。

RNN(リカレントニューラルネットワーク)を使う際に重要なデータの「標準化」と「正規化」について

LYPプレミアム会員 python

こんにちは、システムエンジニアの皆さん!今日は、RNN(リカレントニューラルネットワーク)を使う際に重要なデータの「標準化」と「正規化」についてお話ししたいと思います。RNNは時系列データや自然言語処理などの分野で強力なモデルですが、その性能を最大限に引き出すためには、データの前処理が欠かせません。しかし、このデータ前処理の段階で「うまくできない」という悩みを持つ方も多いかと思います。

そこで今回は、RNNに用いるデータの標準化と正規化の違いや、具体的な実装方法、そしてうまくいかない時の解決策を、コードを交えて詳しく解説していきます。

標準化と正規化の違い

まずは、標準化と正規化の違いについて整理しておきましょう。

  • 標準化(Standardization)
    標準化は、データの平均を0、分散を1に調整する方法です。具体的には、各データポイントから平均値を引き、標準偏差で割ることで行います。これにより、データが「標準正規分布」に従うようになります。主に線形モデルやSVMで効果的に使われることが多いですが、RNNでも非常に役立ちます。

  • 正規化(Normalization)
    一方、正規化はデータの範囲を特定の区間(一般的には0~1)に収める方法です。これによって、スケールの異なるデータを同じ基準で扱えるようになります。主に画像処理やRNNなどの深層学習モデルに適しています。

どちらを使うべきか?

RNNを使う場合、データがどのような形で入力されるかによって選択肢が変わります。時系列データや自然言語データの場合は、正規化を行ってデータのスケールを揃えるのが一般的です。しかし、金融データやセンサーデータなど、値の変動が大きいデータでは標準化が有効な場合もあります。

実際のデータで標準化と正規化を試す

では、具体的にPythonを使って標準化と正規化を行う方法を見ていきましょう。まずは必要なライブラリをインストール・インポートします。

import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler

ここでは、NumPyを使って仮の時系列データを作成し、それを標準化・正規化します。

ステップ1: データの準備

まずは、仮の時系列データを作成しましょう。これは、ランダムな値で構成された2次元配列とします。

# 仮の時系列データを作成
data = np.random.rand(100, 5) * 100  # 100行5列のデータ
print("元のデータ:\n", data[:5])

ここでnp.random.rand(100, 5)は、100行5列のランダムなデータを生成し、値を100倍してスケールを大きくしています。

ステップ2: 標準化

次に、標準化を行います。StandardScalerを使ってデータを平均0、分散1に調整します。

# 標準化
scaler = StandardScaler()
standardized_data = scaler.fit_transform(data)
print("標準化されたデータ:\n", standardized_data[:5])

fit_transform()は、データに基づいてスケーリングを行い、標準化されたデータを返します。結果として、データの各列が平均0、標準偏差1に変換されます。

ステップ3: 正規化

続いて、MinMaxScalerを使ってデータを0~1の範囲に収める正規化を行います。

# 正規化
min_max_scaler = MinMaxScaler()
normalized_data = min_max_scaler.fit_transform(data)
print("正規化されたデータ:\n", normalized_data[:5])

MinMaxScalerを使用すると、データの最小値が0、最大値が1に収まるようにスケールされます。

うまくいかない場合の対策

「標準化や正規化を試してみたけれど、モデルの精度が向上しない」ということもあるかと思います。以下に、よくある問題とその解決策をいくつか紹介します。

問題1: 時系列データの異常な値(外れ値)が影響している

時系列データにはしばしば異常値(外れ値)が含まれています。この場合、標準化を行うと外れ値が強調されすぎてしまう可能性があります。対策として、異常値を除去するか、RobustScalerというスケーリング方法を使うのが効果的です。

from sklearn.preprocessing import RobustScaler

# 外れ値に強い標準化
robust_scaler = RobustScaler()
robust_scaled_data = robust_scaler.fit_transform(data)
print("RobustScalerによる標準化データ:\n", robust_scaled_data[:5])

RobustScalerは、外れ値に強く、データの中央値と四分位範囲を使ってスケーリングします。

問題2: データの分布が非対称

データの分布が大きく偏っている場合、標準化や正規化が期待通りに機能しないことがあります。この場合、対数変換や平方根変換を行ってデータの分布を対称に近づけることが有効です。

# データの対数変換
log_data = np.log1p(data)
print("対数変換後のデータ:\n", log_data[:5])

np.log1p()は、データのすべての要素に対して対数変換を行います。この変換は、ゼロに近い値や非常に大きな値を持つデータに対して効果的です。

サンプルコードの実行結果

ここまでのコードを実行すると、以下のような結果が得られます。

元のデータ:
 [[29.67307344 82.01230818  6.37986854 25.36212586 88.63278955]
 [64.89050976 64.34830662 48.63112128 55.57627579 15.04206213]
 [80.07465774 93.27066903 55.73854783 97.73758927 63.1841344 ]
 [90.56507019 57.4024168  64.93349131 10.0380677  73.76012687]
 [46.56869347 17.73377544 66.24749335  4.82336417 16.0917391 ]]

標準化されたデータ:
 [[-1.06130361  0.99806355 -1.4955048  -0.94402524  1.24080632]
 [ 0.14419418  0.26361478  0.08483749  0.16463052 -1.10412848]
 [ 0.79983548  1.3606081   0.33690163  1.65765672  0.40274331]
 [ 1.22788457  0.0299951   0.72416993 -1.46573229  0.76888319]
 [-0.42401791 -1.39598063  0.76234082 -1.67298908 -1.06317714]]

正規化されたデータ:
 [[0.29417401 0.81987238 0.06403782 0.25031382 0.88436657]
 [0.64727658 0.64145359 0.48287897 0.54873253 0.14578055]
 [0.79841478 0.93325461 0.55301493 0.96477548 0.62614872]
 [0.90404585 0.57286865 0.64602966 0.09582204 0.72956214]
 [0.46066836 0.16859108 0.66018618 0.04595042 0.

15635392]]

まとめ

標準化と正規化は、RNNなどの機械学習モデルにおいて非常に重要なステップです。データの特徴に応じて、どちらを使うべきか、そしてどのように処理すべきかを理解することで、モデルのパフォーマンスを大きく向上させることができます。

もしこれらの前処理がうまくいかない場合は、外れ値の処理や対数変換などの方法も検討してみてください。