信号分類の問題に取り組んでいて、最初にデータセットマトリックスをスケーリングしたいのですが、データは3D形式(バッチ、長さ、チャネル)です。
Scikit-learnスタンダードスケーラーを使用しようとしました:
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
しかし、私はこのエラーメッセージを持っています:
Dim 3の配列が見つかりました。StandardScalerは<= 2である必要があります
1つの解決策は、複数の2Dマトリックスの各チャネルでマトリックスを分割し、それらを個別にスケーリングしてから3D形式に戻すことだと思いますが、もっと良い解決策があるかどうか疑問に思います。
どうもありがとうございました。
各チャンネルにスケーラーを取り付けて保存する必要があります
from sklearn.preprocessing import StandardScaler
scalers = {}
for i in range(X_train.shape[1]):
scalers[i] = StandardScaler()
X_train[:, i, :] = scalers[i].fit_transform(X_train[:, i, :])
for i in range(X_test.shape[1]):
X_test[:, i, :] = scalers[i].transform(X_test[:, i, :])
StandardScaler
のように各機能を異なる方法でスケーリングする場合は、次のように使用できます。
import numpy as np
from sklearn.base import TransformerMixin
from sklearn.preprocessing import StandardScaler
class NDStandardScaler(TransformerMixin):
def __init__(self, **kwargs):
self._scaler = StandardScaler(copy=True, **kwargs)
self._orig_shape = None
def fit(self, X, **kwargs):
X = np.array(X)
# Save the original shape to reshape the flattened X later
# back to its original shape
if len(X.shape) > 1:
self._orig_shape = X.shape[1:]
X = self._flatten(X)
self._scaler.fit(X, **kwargs)
return self
def transform(self, X, **kwargs):
X = np.array(X)
X = self._flatten(X)
X = self._scaler.transform(X, **kwargs)
X = self._reshape(X)
return X
def _flatten(self, X):
# Reshape X to <= 2 dimensions
if len(X.shape) > 2:
n_dims = np.prod(self._orig_shape)
X = X.reshape(-1, n_dims)
return X
def _reshape(self, X):
# Reshape X back to it's original shape
if len(X.shape) >= 2:
X = X.reshape(-1, *self._orig_shape)
return X
SklearnのStandardScaler
に渡す前に、入力の特徴を単純化します。次に、それらを元に戻します。使い方はStandardScaler
と同じです:
data = [[[0, 1], [2, 3]], [[1, 5], [2, 9]]]
scaler = NDStandardScaler()
print(scaler.fit_transform(data))
プリント
[[[-1. -1.]
[ 0. -1.]]
[[ 1. 1.]
[ 0. 1.]]]
引数with_mean
およびwith_std
はStandardScaler
に直接渡されるため、期待どおりに動作します。 copy=False
は、整形が行われないため機能しません。 2次元入力の場合、NDStandardScaler
はStandardScaler
のように機能します。
data = [[0, 0], [0, 0], [1, 1], [1, 1]]
scaler = NDStandardScaler()
scaler.fit(data)
print(scaler.transform(data))
print(scaler.transform([[2, 2]]))
プリント
[[-1. -1.]
[-1. -1.]
[ 1. 1.]
[ 1. 1.]]
[[3. 3.]]
StandardScaler
のsklearnの例のように。
3行のコードで...
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train.reshape(-1, X_train.shape[-1])).reshape(X_train.shape)
X_test = scaler.transform(X_test.reshape(-1, X_test.shape[-1])).reshape(X_test.shape)
s0, s1, s2 = y_train.shape[0], y_train.shape[1], y_train.shape[2]
y_train = y_train.reshape(s0 * s1, s2)
y_train = minMaxScaler.fit_transform(y_train)
y_train = y_train.reshape(s0, s1, s2)
s0, s1, s2 = y_test.shape[0], y_test.shape[1], y_test.shape[2]
y_test = y_test.reshape(s0 * s1, s2)
y_test = minMaxScaler.transform(y_test)
y_test = y_test.reshape(s0, s1, s2)
データをそのように再形成するだけです。ゼロを埋め込む場合も同様に使用します。
s0, s1, s2 = x_train.shape[0], x_train.shape[1], x_train.shape[2]
x_train = x_train.reshape(s0 * s1, s2)
minMaxScaler.fit(x_train[0::s1])
x_train = minMaxScaler.transform(x_train)
x_train = x_train.reshape(s0, s1, s2)
s0, s1, s2 = x_test.shape[0], x_test.shape[1], x_test.shape[2]
x_test = x_test.reshape(s0 * s1, s2)
x_test = minMaxScaler.transform(x_test)
x_test = x_test.reshape(s0, s1, s2)