ビニング、離散化、線形モデル、決定木
Overview
最良のデータ表現方法は、利用する機械学習のモデルにも依存します。非常によく使われるモデルを例にすると、線形モデルと決定木ベースのモデル(決定木、勾配ブースティング木、ランダムフォレスト)は、特徴量の表現に関しては非常に異なる特性を持ちます。
Coding
wave回帰データセット(特徴量が1つ)を用いて線形回帰モデルと決定木回帰モデルを比較する
code: Python
import matplotlib.pyplot as plt
import mglearn
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
X, y = mglearn.datasets.make_wave(n_samples=100)
line = np.linspace(-3, 3, 1000, endpoint=False).reshape(-1, 1)
reg = DecisionTreeRegressor(min_samples_split=3).fit(X, y)
plt.plot(line, reg.predict(line), label='decision tree')
reg = LinearRegression().fit(X, y)
plt.plot(line, reg.predict(line), label='linear regression')
plt.plot(X:, 0, y, 'o', c='k') plt.ylabel('Regression output')
plt.xlabel('Input feature')
plt.legend(loc='best')
plt.show()
https://gyazo.com/d8dfd3b3efc165702597eedd95fbc2dd
当然、特徴量は1つなので線形モデルは1本の直線になり、決定木モデルははるかに複雑なモデルを構築することができます。
線形モデルを連続データに対してより強力にする方法の1つとして特徴量のビニング(binning)もしくは離散化(discretization)があります。これらは特徴量を複数の特徴量で分割する方法です。
code: Python
# 10のビンで区切る
bins = np.linspace(-3, 3, 11)
print('bins: {}'.format(bins))
# 個々のデータポイントがどのビンに入るのか記録する
which_bin = np.digitize(X, bins=bins)
print('Data points:\n', X:5) print('Bin membership for data points:\n', which_bin:5) --------------------------------------------------------------------------
Data points:
Bin membership for data points:
--------------------------------------------------------------------------
この離散値特徴量をワンホットエンコーディングに変換する必要があります。
code: Python
from sklearn.preprocessing import OneHotEncoder
# OneHotEncoderで変換する
encoder = OneHotEncoder(sparse=False)
# encoder.fitでwhich_binに現れる整数値のバリエーションを確認
encoder.fit(which_bin)
# transformでワンホットエンコーディングを行う
X_binned = encoder.transform(which_bin)
# 10ビンを指定したので、変換されたデータセットX_binnedには10個の特徴量ができている
print('X_binned.shape: {}'.format(X_binned.shape))
--------------------------------------------------------------------------
X_binned.shape: (100, 10)
--------------------------------------------------------------------------
再度、線形回帰モデルと決定木モデルをこのワンホットエンコーディングデータに対して作り直してみます。
code: Python
line_binned = encoder.transform(np.digitize(line, bins=bins))
reg = DecisionTreeRegressor(min_samples_split=3).fit(X_binned, y)
plt.plot(line, reg.predict(line_binned), label='decision tree binned')
reg = LinearRegression().fit(X_binned, y)
plt.plot(line, reg.predict(line_binned), label='linear regression binned')
plt.plot(X:, 0, y, 'o', c='k') plt.vlines(bins, -3, 3, linewidth=1, alpha=.2)
plt.ylabel('Regression output')
plt.xlabel('Input feature')
plt.legend(loc='best')
plt.show()
https://gyazo.com/ba64c27d1e06dcc4cbbab1e8bf30c9a6
2つのモデルが完全に同じ予測をしています。ビンごとに特徴量が一定になっているためです。ビニングは、線形モデルには効果が絶大なことがわかります。