LoginSignup
30
30

More than 5 years have passed since last update.

【翻訳】scikit-learn 0.18 User Guide 4.3. データ前処理

Last updated at Posted at 2016-12-22

http://scikit-learn.org/0.18/modules/preprocessing.html を google 翻訳した
scikit-learn 0.18 ユーザーガイド 4. データセット変換 より


4.3. データ前処理

sklearn.preprocessing パッケージは、いくつかの一般的なユーティリティ関数と、未処理の特徴ベクトルを下流の推定器に適した表現に変更するための変換クラスを提供します。

4.3.1. 標準化、平均除去と分散のスケーリング

データセットの 標準化 は、scikit-learnで実装された 多くの機械学習推定器の共通要件 です。個々の特徴量が標準的に正規分布しているデータのようには見えない場合、つまり、 ゼロ平均と単位分散 を持つガウス分布の場合、それらはひどく振舞う可能性があります。
実際には、分布の形状を無視し、各特徴量の平均値を取り除いて中心にデータを変換し、非定常特徴量を標準偏差で除算してスケーリングします。
たとえば、学習アルゴリズムの目的関数(Support Vector MachinesのRBFカーネルや線形モデルのl1およびl2正規化器など)で使用される多くの要素では、すべての特徴量がゼロに中心を置き、同じ順序で分散を持つと仮定します。ある特徴量の分散が他の特徴量のオーダーよりも大きい場合、目的関数を支配する可能性があり、推定器が他の特徴量から期待通りに正しく学習できなくなる可能性があります。
scale 関数は、単一の配列のようなデータセットに対してこの操作を迅速かつ簡単に実行する方法を提供します。

>>> from sklearn import preprocessing
>>> import numpy as np
>>> X = np.array([[ 1., -1.,  2.],
...               [ 2.,  0.,  0.],
...               [ 0.,  1., -1.]])
>>> X_scaled = preprocessing.scale(X)

>>> X_scaled                                          
array([[ 0.  ..., -1.22...,  1.33...],
       [ 1.22...,  0.  ..., -0.26...],
       [-1.22...,  1.22..., -1.06...]])

スケーリングされたデータの平均と単位分散はゼロです。

>>>
>>> X_scaled.mean(axis=0)
array([ 0.,  0.,  0.])

>>> X_scaled.std(axis=0)
array([ 1.,  1.,  1.])

さらに、 preprocessing モジュールは、Transformer APIを実装したユーティリティクラス StandardScaler を提供し、トレーニングセットの平均および標準偏差を計算し、後で同じ変換をテストセットに再適用できるようにします。 したがって、このクラスは、sklearn.pipeline.Pipeline の初期段階での使用に適しています。

スケーラインスタンスは、新しいデータに使用して、トレーニングセットと同じように変換することができます。

with_mean = False または with_std = False のいずれかを StandardScaler のコンストラクタに渡すことによって、センタリングまたはスケーリングを無効にすることができます。

4.3.1.1. 範囲への特徴量のスケーリング

別の標準化は、与えられた最小値と最大値との間で、しばしばゼロと1との間にあるように、または各特徴の最大絶対値が単位サイズにスケーリングされるようにするスケーリング機能である。これは、それぞれ MinMaxScaler または MaxAbsScaler を使用して実現できます。
このスケーリングを使用する動機には、特徴量の非常に小さい標準偏差への頑強さと疎なデータのゼロエントリの保持が含まれます。
玩具のデータ行列を [0, 1] の範囲にスケールする例を次に示します。

>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5       ,  0.        ,  1.        ],
       [ 1.        ,  0.5       ,  0.33333333],
       [ 0.        ,  1.        ,  0.        ]])

フィッティングコール中に見えないいくつかの新しいテストデータにトランスの同じインスタンスを適用することができます。訓練データで実行される変換と一致するように、同じスケーリングとシフト操作が適用されます。

>>> X_test = np.array([[ -3., -1.,  4.]])
>>> X_test_minmax = min_max_scaler.transform(X_test)
>>> X_test_minmax
array([[-1.5       ,  0.        ,  1.66666667]])

スケーラーの属性を見ることで、トレーニングデータで学習された変換の正確な性質を見つけることができます。

>>> min_max_scaler.scale_                             
array([ 0.5       ,  0.5       ,  0.33...])

>>> min_max_scaler.min_                               
array([ 0.        ,  0.5       ,  0.33...])

MinMaxScaler に明示的な feature_range =(min, max) が与えられている場合、完全な公式は次のようになります。

X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))

X_scaled = X_std / (max - min) + min

MaxAbsScaler は非常によく似た働きをしますが、トレーニングデータが [-1, 1] の範囲内にあるように、各特徴の最大値を分割してスケーリングします。それはすでにゼロまたは疎なデータの中心にあるデータを意味します。
このスケーラーで前の例のデータを使用する方法は次のとおりです。

>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> max_abs_scaler = preprocessing.MaxAbsScaler()
>>> X_train_maxabs = max_abs_scaler.fit_transform(X_train)
>>> X_train_maxabs                # doctest +NORMALIZE_WHITESPACE^
array([[ 0.5, -1. ,  1. ],
       [ 1. ,  0. ,  0. ],
       [ 0. ,  1. , -0.5]])
>>> X_test = np.array([[ -3., -1.,  4.]])
>>> X_test_maxabs = max_abs_scaler.transform(X_test)
>>> X_test_maxabs                 
array([[-1.5, -1. ,  2. ]])
>>> max_abs_scaler.scale_         
array([ 2.,  1.,  2.])

scale と同様に、モジュールは、オブジェクトを作成したくない場合に便利な関数 minmax_scalemaxabs_scale を提供します。

4.3.1.2. 疎なデータのスケーリング

疎なデータをセンタリングすると、データのスパースネス構造が破壊されるため、よいことはめったにありません。しかし、特徴量が異なるスケールにある場合もあります。
MaxAbsScalermaxabs_scale は、疎なデータをスケーリングするために特別に設計されたもので、これは推奨される方法です。しかし、 scaleStandardScaler は、 with_mean = False が明示的にコンストラクタに渡されている限り、 scipy.sparse 行列を入力として受け入れることができます。そうしないと、静かにセンタリングして疎行列が展開され、意図せずに過剰な量のメモリを割り当ててクラッシュさせるため、ValueErrorが発生します。 RobustScaler は入力を疎行列にすることはできませんが、transformメソッドは疎行列で使用できます。

スケーラは、Compressed Sparse RowsとCompressed Sparse Columnsの両方の形式を受け付けます(scipy.sparse.csr_matrix および scipy.sparse.csc_matrix を参照)。他の疎行列入力は csr行列に変換 されます。不必要なメモリコピーを避けるため、上流のCSRまたはCSC表現を選択することを推奨します。
最後に、中心のデータが十分に小さいと予想される場合、スパース行列の toarray メソッドを使用して入力を配列に明示的に変換することも別のオプションです。

4.3.1.3. 異常値を含むデータのスケーリング

データに多数の異常値が含まれている場合、データの平均と分散を使用したスケーリングはうまく機能しない可能性があります。このような場合は、代わりに代わりに robust_scaleRobustScaler を使用することができます。彼らはあなたのデータの中心と範囲に対してより堅牢な推定器を使用します。

  • 参考文献:
  • スケーリングとホワイトニング
    • 下流のモデルは、特徴量の線形独立性をさらに前提とすることができるので、特徴量を独立して中心化およびスケールするだけでは不十分であることがあります。
    • この問題に対処するには、sklearn.decomposition.PCA または sklearn.decomposition.RandomizedPCAwhiten = True を使用して、特徴値間の線形相関をさらに削除します。
  • 回帰における目標変数のスケーリング
    • scale と StandardScaler は1次元配列ですぐに使用できます。これは、回帰に使用されるターゲット/応答変数のスケーリングに非常に役立ちます。

4.3.1.4. センタリングカーネル行列

関数 $phi$ で定義された特徴空間でドット積を計算するカーネル $K$ のカーネル行列がある場合、KernelCenterer はカーネル行列を変換して、 $phi$ によって定義された特徴空間内の内積を含み、その後にその空間内の平均を除去するように変換できます。

4.3.2. 正規化

正規化 は、 個々のサンプルを単位標準を持つようにスケーリングする プロセスです。このプロセスは、ドットプロダクトやその他のカーネルなどの2次形式を使用して、サンプルのペアの類似性を定量化する場合に役立ちます。
この仮定は、テキスト分類およびクラスタリングの文脈でしばしば使用される ベクトル空間モデル の基礎である。
関数 normalize は、 l1 または l2 のノルムを使用して、単一の配列のようなデータセットに対してこの操作を迅速かつ簡単に実行する方法を提供します。

>>> X = [[ 1., -1.,  2.],
...      [ 2.,  0.,  0.],
...      [ 0.,  1., -1.]]
>>> X_normalized = preprocessing.normalize(X, norm='l2')

>>> X_normalized                                      
array([[ 0.40..., -0.40...,  0.81...],
       [ 1.  ...,  0.  ...,  0.  ...],
       [ 0.  ...,  0.70..., -0.70...]])

preprocessing モジュールはさらに、Transformer APIを使用して同じ操作を実装するユーティリティクラス Normalizer を提供します( fit メソッドがこの場合役に立たなくても、この操作はサンプルを独立して処理するため、ステートレスです)。
したがって、このクラスは、 sklearn.pipeline.Pipeline の初期段階での使用に適しています。

>>> normalizer = preprocessing.Normalizer().fit(X)  # fit does nothing
>>> normalizer
Normalizer(copy=True, norm='l2')

ノーマライザインスタンスは、サンプルベクトルで任意のトランスフォーマとして使用できます。

>>> normalizer.transform(X)                            
array([[ 0.40..., -0.40...,  0.81...],
       [ 1.  ...,  0.  ...,  0.  ...],
       [ 0.  ...,  0.70..., -0.70...]])

>>> normalizer.transform([[-1.,  1., 0.]])             
array([[-0.70...,  0.70...,  0.  ...]])
  • スパース入力
    • normalizeおよびNormalizerは、入力として scipy.sparse から密行列と疎行列の両方を受け入れます。
    • スパース入力の場合、データは効率的なCythonルーチンに送られる前に、圧縮された疎行表現(scipy.sparse.csr_matrixを参照)に変換されます。不必要なメモリコピーを避けるため、上流のCSR表現を選択することを推奨します。

4.3.3. 二値化

4.3.3.1. 特徴二値化

特徴二値化は、数値特徴量をしきい値処理してブール値を得るプロセスです。これは、入力データが多変量ベルヌーイ分布 に従って分布していることを前提とする下流の確率的推定量に有用である。たとえば、これはsklearn.neural_network.BernoulliRBM の場合です。
また、正規化されたカウント(用語頻度など)やTF-IDF値付きフィーチャが実際には多少良く機能する場合でも、バイナリ特徴値を使用することは(確率論的推論を単純化するために)、テキスト処理コミュニティでは一般的です。
正規化されたカウントまたはTF-IDF評価された特徴がしばしば実際にはわずかに良好に機能する場合であっても、バイナリ特徴値を使用すること
Normalizer に関しては、ユーティリティクラス Binarizersklearn.pipeline.Pipeline の初期段階で使用されることを意図しています。 fit メソッドは、各サンプルが他のサンプルとは独立して処理されるため、何もしません。

>>> X = [[ 1., -1.,  2.],
...      [ 2.,  0.,  0.],
...      [ 0.,  1., -1.]]

>>> binarizer = preprocessing.Binarizer().fit(X)  # fit does nothing
>>> binarizer
Binarizer(copy=True, threshold=0.0)

>>> binarizer.transform(X)
array([[ 1.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])

Binarizerのしきい値を調整することができます。

>>> binarizer = preprocessing.Binarizer(threshold=1.1)
>>> binarizer.transform(X)
array([[ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  0.,  0.]])

StandardScalerクラスとNormalizerクラスに関して、preprocessing モジュールは、変換APIが必要でないときに使用されるコンパニオン関数の binarize を提供します。

  • スパース入力
    • binarizeとBinarizerは、入力としてscipy.sparseから密行列と疎行列の両方を受け入れます。
    • スパース入力の場合、データは 圧縮スパース行表現 に変換されます(scipy.sparse.csr_matrixを参照)。不必要なメモリコピーを避けるため、上流のCSR表現を選択することを推奨します。

4.3.4. カテゴリの特徴量をエンコードする

多くの場合、特徴量は連続的な値ではなく、カテゴリに分類されます。たとえば、["male", "female"], ["from Europe", "from US", "from Asia"], ["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"] このような特徴は、整数として効率的にコード化することができる。例えば、["male", "from US", "uses Internet Explorer"][0,1,3] ["female", "from Asia", "uses Chrome"][1、2、1] となります。
そのような整数表現は、連続的な入力を期待し、カテゴリが順序付けられていると解釈するので、scikit-learn推定器で直接使用することはできません(しばしば望ましくないブラウザのセットが任意に注文されました)。
カテゴリ特徴量をscikit-learn推定器で使用できる特徴量に変換する1つの方法は、OneHotEncoder で実装されている 1対K または1ホットエンコーディングを使用することです。この推定器は、m 個の可能な値を有する各カテゴリ特徴をm個のバイナリ特徴に変換し、1つのみアクティブとする。
上記の例を続ける:

>>> enc = preprocessing.OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
>>> enc.transform([[0, 1, 3]]).toarray()
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.]])

デフォルトでは、各特徴が取ることができる値の数は、データセットから自動的に推測されます。パラメータn_values を使用してこれを明示的に指定することができます。データセットには2つの性別、3つの可能な大陸、4つのWebブラウザがあります。次に、見積もりに合って、データポイントを変換します。その結果、最初の2つの数字は性別を、3番目の数字は大陸に、最後の4つはウェブブラウザにエンコードします。
トレーニングデータにカテゴリの特徴がない可能性がある場合は、明示的にn_valuesを設定する必要があることに注意してください。例えば、

>>> enc = preprocessing.OneHotEncoder(n_values=[2, 3, 4])
>>> # 第2および第3のフィーチャのカテゴリ値が欠落していることに注意してください
>>> enc.fit([[1, 2, 3], [0, 2, 0]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values=[2, 3, 4], sparse=True)
>>> enc.transform([[1, 0, 0]]).toarray()
array([[ 0.,  1.,  1.,  0.,  0.,  1.,  0.,  0.,  0.]])

dictsからのフィーチャーのロード」を参照してください。

4.3.5. 欠損値の補完

さまざまな理由から、多くの現実世界のデータセットには欠けている値が含まれており、空白、NaNなどのプレースホルダとしてエンコードされることがよくあります。しかし、そのようなデータセットは、配列内のすべての値が数値であり、すべてが意味を持ち、保持していることを前提とするscikit-learn見積もりとは互換性がありません。不完全なデータセットを使用する基本的な戦略は、欠損値を含む行全体および/または列を破棄することです。しかし、これはデータを失うことになります(不完全であっても)。より良い戦略は欠損値を代入すること、すなわちデータの既知の部分からそれらを推測することである。
Imputer クラスは、欠損値がある行または列の平均値、中央値または最も頻繁な値を使用して、欠損値を代入する基本的な方法を提供します。このクラスでは、異なる欠損値のエンコードも可能です。
次のスニペットは、欠損値を含む列(軸0)の平均値を使用して、 np.nan としてエンコードされた欠損値を置き換える方法を示しています。

>>> import numpy as np
>>> from sklearn.preprocessing import Imputer
>>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
>>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
>>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
>>> print(imp.transform(X))                           
[[ 4.          2.        ]
 [ 6.          3.666...]
 [ 7.          6.        ]]

Imputerクラスでは、スパース行列もサポートされています。

>>> import scipy.sparse as sp
>>> X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
>>> imp = Imputer(missing_values=0, strategy='mean', axis=0)
>>> imp.fit(X)
Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0)
>>> X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
>>> print(imp.transform(X_test))                      
[[ 4.          2.        ]
 [ 6.          3.666...]
 [ 7.          6.        ]]

ここでは、欠損値は0でエンコードされているため、暗黙的に行列に格納されていることに注意してください。したがって、この形式は、観測値より多くの欠損値がある場合に適しています。
代用をサポートする複合推定器を構築する方法として、Imputerをパイプラインで使用できます。推定器を作成する前に欠損値を入力する を参照してください

4.3.6. 多項式特徴量の生成

入力データの非線形の特徴を考慮して、モデルに複雑さを加えることはしばしば役に立ちます。 シンプルで一般的な使用方法は、多項式特徴量であり、特徴量の高次および相互作用の項を得ることができます。 PolynomialFeatures に実装されています:

>>> import numpy as np
>>> from sklearn.preprocessing import PolynomialFeatures
>>> X = np.arange(6).reshape(3, 2)
>>> X                                                 
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> poly = PolynomialFeatures(2)
>>> poly.fit_transform(X)                             
array([[  1.,   0.,   1.,   0.,   0.,   1.],
       [  1.,   2.,   3.,   4.,   6.,   9.],
       [  1.,   4.,   5.,  16.,  20.,  25.]])

Xの機能は$(X_1,X_2)$から$(1、X_1, X_2, X_1 ^ 2, X_1X_2, X_2 ^ 2)$に変換されました。
特徴間の相互作用タームのみが必要な場合、interact_only = Trueの設定で取得できます。

>>> X = np.arange(9).reshape(3, 3)
>>> X                                                 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> poly = PolynomialFeatures(degree=3, interaction_only=True)
>>> poly.fit_transform(X)                             
array([[   1.,    0.,    1.,    2.,    0.,    0.,    2.,    0.],
       [   1.,    3.,    4.,    5.,   12.,   15.,   20.,   60.],
       [   1.,    6.,    7.,    8.,   42.,   48.,   56.,  336.]])

Xの機能は$(X_1, X_2, X_3)$ から $(1, X_1, X_2, X_3, X_1X_2, X_1X_3, X_2X_3, X_1X_2X_3)$に変換されました。
多項式関数は、多項式カーネル関数 を使用するとき、カーネル方法(例えば、sklearn.svm.SVCsklearn.decomposition.KernelPCA)において暗黙的に使用されることに留意されたい。
作成された多項式特徴量を使用したリッジ回帰の多項式補間を参照してください。

4.3.7. カスタムトランス

多くの場合、既存のPython関数をトランスフォーマーに変換して、データのクリーニングや処理を支援したいと思うでしょう。 FunctionTransformerを使用して任意の関数からトランスフォーマーを実装できます。 たとえば、パイプラインでログ変換を適用するトランスフォーマーを構築するには、次のようにします。

>>> import numpy as np
>>> from sklearn.preprocessing import FunctionTransformer
>>> transformer = FunctionTransformer(np.log1p)
>>> X = np.array([[0, 1], [2, 3]])
>>> transformer.transform(X)
array([[ 0.        ,  0.69314718],
       [ 1.09861229,  1.38629436]])

FunctionTransformerを使用してカスタムフィーチャを選択する方法の完全なコード例については、「FunctionTransformerを使用したカラムの選択」を参照してください。


scikit-learn 0.18 ユーザーガイド 4. データセット変換 より

©2010 - 2016、scikit-learn developers(BSDライセンス)。

30
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
30