sklearn-fab¶
データ準備¶
まず、学習用のデータを確認します。
本ノートブックでは、中古車の販売価格を示すデータを使用します。
データの詳細については、以下をご覧ください。
[1]:
import pandas as pd
train_data = pd.read_csv('../data/train_data.csv')
train_data.head()
[1]:
price | symboling | normalized-losses | num-of-doors | wheel-base | length | width | height | |
---|---|---|---|---|---|---|---|---|
0 | 12964 | 3 | 145.0 | two | 95.9 | 173.2 | 66.3 | 50.2 |
1 | 10198 | 0 | 89.0 | four | 97.0 | 173.5 | 65.4 | 53.0 |
2 | 11245 | 0 | 115.0 | four | 98.8 | 177.8 | 66.5 | 55.5 |
3 | 14399 | 0 | 108.0 | four | 100.4 | 184.6 | 66.5 | 56.1 |
4 | 25552 | -1 | 93.0 | four | 110.0 | 190.9 | 70.3 | 56.5 |
上記のデータについて、以下の前処理を実施します。
num-of-doorsはカテゴリ変数のため、二値展開
num-of-doorsを除く変数は数値データであるため、標準化
二値展開¶
[2]:
def binary_expand(data):
binary_data = pd.get_dummies(data.select_dtypes(include=[object]))
numerical_data = data.select_dtypes(exclude=[object])
data = numerical_data.join(binary_data)
return data
train_data = binary_expand(train_data)
train_data.head()
[2]:
price | symboling | normalized-losses | wheel-base | length | width | height | num-of-doors_four | num-of-doors_two | |
---|---|---|---|---|---|---|---|---|---|
0 | 12964 | 3 | 145.0 | 95.9 | 173.2 | 66.3 | 50.2 | 0 | 1 |
1 | 10198 | 0 | 89.0 | 97.0 | 173.5 | 65.4 | 53.0 | 1 | 0 |
2 | 11245 | 0 | 115.0 | 98.8 | 177.8 | 66.5 | 55.5 | 1 | 0 |
3 | 14399 | 0 | 108.0 | 100.4 | 184.6 | 66.5 | 56.1 | 1 | 0 |
4 | 25552 | -1 | 93.0 | 110.0 | 190.9 | 70.3 | 56.5 | 1 | 0 |
標準化¶
[3]:
from sklearn.preprocessing import StandardScaler
std_list = ['price', 'symboling', 'normalized-losses', 'wheel-base', 'length', 'width', 'height']
scaler = StandardScaler()
train_data.loc[:, std_list] = pd.DataFrame(scaler.fit_transform(train_data.loc[:, std_list]),
columns=train_data.loc[:, std_list].columns.values)
train_data.head()
[3]:
price | symboling | normalized-losses | wheel-base | length | width | height | num-of-doors_four | num-of-doors_two | |
---|---|---|---|---|---|---|---|---|---|
0 | 0.284679 | 1.811656 | 0.618145 | -0.436458 | 0.083628 | 0.350742 | -1.512881 | 0 | 1 |
1 | -0.203075 | -0.625845 | -0.924055 | -0.221660 | 0.110246 | -0.109542 | -0.336858 | 1 | 0 |
2 | -0.018448 | -0.625845 | -0.208033 | 0.129829 | 0.491759 | 0.453028 | 0.713163 | 1 | 0 |
3 | 0.537726 | -0.625845 | -0.400808 | 0.442264 | 1.095083 | 0.453028 | 0.965168 | 1 | 0 |
4 | 2.504436 | -1.438345 | -0.813897 | 2.316871 | 1.654045 | 2.396452 | 1.133171 | 1 | 0 |
次に、予測用データを読み込み、学習用データと同様に前処理を実施します。
[4]:
predict_data = pd.read_csv('../data/predict_data.csv')
predict_data = binary_expand(predict_data)
predict_data.loc[:, std_list] = pd.DataFrame(scaler.transform(predict_data.loc[:, std_list]),
columns=predict_data.loc[:, std_list].columns.values)
predict_data.head()
[4]:
price | symboling | normalized-losses | wheel-base | length | width | height | num-of-doors_four | num-of-doors_two | |
---|---|---|---|---|---|---|---|---|---|
0 | -0.883744 | 0.186655 | -0.979133 | -0.475513 | -1.202871 | -1.030111 | 0.293154 | 0 | 1 |
1 | 1.199174 | 1.811656 | 0.755842 | 0.188411 | 1.272531 | 0.453028 | 0.965168 | 0 | 1 |
2 | 1.114355 | 0.999156 | 0.315213 | 0.051721 | 0.349801 | -0.007257 | -0.336858 | 0 | 1 |
3 | 0.035159 | 0.999156 | 0.315213 | 0.051721 | 0.349801 | -0.007257 | -0.756866 | 0 | 1 |
4 | 3.685556 | -0.625845 | 0.618145 | 2.902686 | 2.425944 | 2.038453 | -0.420860 | 1 | 0 |
学習用および予測用の説明変数をそれぞれX_train, X_predict、目的変数をそれぞれy_train, y_predictとして定義しておきます。
[5]:
X_train = train_data.iloc[:, 1:]
y_train = train_data.iloc[:, 0]
X_predict = predict_data.iloc[:, 1:]
y_predict = predict_data.iloc[:, 0]
分析手順の設計¶
目的変数priceは連続値であるため、回帰用のestimatorである「SklearnFABBernGateLinearRegressor」を選択します。
学習を行う際に、以下のパラメーターを指定します。
random_seed
estimatorで使用される乱数シードです。
tree_depth
門木の深さを設定するパラメーターです。
shrink_threshold
門木の枝刈りの閾値を設定するパラメーターです。
random_seed, tree_depth, shrink_thresholdの詳細は、「sklearn-fab Reference v1.1.0」をご覧ください。
[6]:
from sklearn_fab import SklearnFABBernGateLinearRegressor
random_seed = 0
tree_depth = 3
shrink_threshold = 2.0
estimatorインスタンスを作成します。
[7]:
estimator = SklearnFABBernGateLinearRegressor(random_seed=random_seed,
tree_depth=tree_depth,
shrink_threshold=shrink_threshold)
学習、予測¶
学習を実行します。
[8]:
estimator.fit(X_train, y_train)
[8]:
SklearnFABBernGateLinearRegressor(base_model_dict=None,
comp_backward_step=False,
comp_bias_max_scale=0.75,
comp_bias_min_scale=0.25,
comp_foba_skip='power_of_two',
comp_foba_skip_max_interval=25,
comp_l2_regularize=0.0, comp_opt_mode='opt',
comp_two_stage_opt=False,
comp_variance_max_scale=0.25,
comp_variance_min_scale=0.1,
comp_weights_max_scale=0.5,
comp_we...
gate_opt_mode='opt',
max_comp_foba_iterations=100,
max_comp_relevant_features=100,
max_fab_iterations=100,
num_acceleration_steps=0, num_threads_comps=1,
num_threads_gate_features=1,
num_threads_gates=1, projection_estep=False,
random_seed=0, repeat_until_convergence=False,
shrink_threshold=2.0, start_from_mstep=False,
tree_depth=3,
with_comp_scaled_l0_regularize=True)
予測を実行します。
[9]:
predict_value = estimator.predict(X_predict)
モデルバリデーション¶
予測精度の確認¶
作成したモデルを評価するため、予測精度を確認します。
評価指標として、RMSEを選定します。
[10]:
from sklearn.metrics import mean_squared_error
test_rmse = mean_squared_error(y_predict, predict_value, squared=False)
test_rmse
[10]:
0.6509250433352727
門木の可視化¶
モデルがもつ門木を可視化します。
[11]:
from IPython.display import display, Image
from sklearn_fab.utils import export_gate_tree_dot
dot = export_gate_tree_dot(estimator, X=X_train)
display(Image(dot.create_png()))

予測式の可視化¶
モデルがもつ予測式情報にアクセスし、可視化します。
[12]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 可視化のために、DataFrame形式で予測式を表現
columns = np.append(estimator.feature_names_, ['bias', 'variance'])
prediction_formulas = [np.append(comp.weights, [comp.bias, comp.variance])
for comp in estimator.comps_]
pf_df = pd.DataFrame(prediction_formulas, columns=columns,
index=['component #' + str(i) for i in estimator.comp_ids_])
# 係数が0ではない説明変数のみを抽出し、表示
relevant_feature_indices = pf_df.sum(axis=0) != 0
pf_df = pf_df.T[relevant_feature_indices]
pf_df.plot(kind='barh', figsize=(8, 4), stacked=True)
plt.show()
