初めて教師あり学習(回帰)を試行錯誤してみる

scikit-learnを使い機械学習を勉強しています。

今日は機械学習の1つ「教師あり学習(回帰)」のモデルを作成していきます。
モデルの精度を調整するのは初めてなので、試行錯誤しながらやっております。私のような機械学習初心者の方励ましのコメントいただけると幸いです。
経験者の方がもし見てましたらアドバイスいただけるとありがたいです。

概要

UCIのデータセットを使います。
回帰用のモデルをいくつか試し、説明変数を変えながら、score()メソッドが高くなるように目指しています。

データセットについて

コンクリートを作る素材の配合により出来上がりの強度を予測するためのデータセットを利用しています。
素材としてはセメント等8種類あります。(下図)

Index(['Cement (component 1)(kg in a m^3 mixture)',
      'Blast Furnace Slag (component 2)(kg in a m^3 mixture)',
      'Fly Ash (component 3)(kg in a m^3 mixture)',
      'Water  (component 4)(kg in a m^3 mixture)',
      'Superplasticizer (component 5)(kg in a m^3 mixture)',
      'Coarse Aggregate  (component 6)(kg in a m^3 mixture)',
      'Fine Aggregate (component 7)(kg in a m^3 mixture)', 'Age (day)'],
     dtype='object')

試行錯誤

まずは全8つの説明変数を全て使って線形回帰、Ridge回帰、Lasso回帰を試します。

model_list = [
             lambda : ("線形回帰",LinearRegression()),
             lambda : ("Ridge回帰",Ridge()),
             lambda : ("Lasso回帰",Lasso())
             ]
result_list = []
for m in model_list:
 name, model = m()
 model.fit(concrete_train_X, concrete_train_y)
 score = model.score(concrete_test_X, concrete_test_y)
 result_list.append([score,name])

print(sorted(result_list,reverse=True))

実行結果を見ると全ての説明変数を使った場合のスコアはLasso回帰が一番よく0.625でした。

[
['score'             ,'モデル名'],
[0.6255946866551905'lasso回帰'], 
[0.624929725846002'ridge回帰'], 
[0.6249292900326935'線形回帰']
]

次に説明変数の全255通りで試します。
それぞれ試行錯誤を繰り返し、学習モデルも追加しました。

# 全ての特徴量の選択パターンをリスト化
concrete_train_X_list = [concrete_train_X]
concrete_test_X_list =[concrete_test_X]
doubling_X = lambda clm, X: (X + [i.drop(clm,axis=1for i in X])

for clm in concrete_train_X.columns:
 concrete_train_X_list = doubling_X(clm,concrete_train_X_list)
 concrete_test_X_list = doubling_X(clm,concrete_test_X_list)

# 最終リストはカラムなしのため削除
del concrete_train_X_list[-1]
del concrete_test_X_list[-1]

# 機械学習モデルをリスト化
model_list = [
           lambda : ("線形回帰",LinearRegression()),
           lambda : ("Ridge回帰",Ridge()),
           lambda : ("Lasso回帰",Lasso()),
           lambda : ("K-近傍法",KNeighborsRegressor()),
           lambda : ("ElasticNet",ElasticNet(alpha = 0.5)),
           lambda : ("決定木",DecisionTreeRegressor(random_state = 0)),
           lambda : ("SVM回帰",LinearSVR()),
           lambda : ("勾配ブースティング回帰",GradientBoostingRegressor()),
           lambda : ("バギング回帰",BaggingRegressor()),
           lambda : ("Ada",AdaBoostRegressor())
           ]

# 全パターンのモデルを作成してscoreを求める
result_list = []
for (train_X, test_X) in zip(concrete_train_X_list,concrete_test_X_list):
 for m in model_list:
   name, model = m()
   model.fit(train_X, concrete_train_y)
   score = model.score(test_X, concrete_test_y)
   result_list.append([score,name,train_X.columns])

print(sorted(result_list,reverse=True)[0:5])

結果を見るとscoreの高い上位5つはいずれも、「Cement」「Blast Furnace Slag」「Water」「Age」となっていることから、これらの要素はコンクリートの強度と相関があるといえるとだろうと。
そして、機械学習モデルは「勾配ブースティング回帰」が適しているといれるだろう。

[[0.8930809642824843, '勾配ブースティング回帰', 
    Index([
        'Cement (component 1)(kg in a m^3 mixture)',
        'Blast Furnace Slag (component 2)(kg in a m^3 mixture)',
        'Fly Ash (component 3)(kg in a m^3 mixture)',
        'Water  (component 4)(kg in a m^3 mixture)',
        'Fine Aggregate (component 7)(kg in a m^3 mixture)', 
        'Age (day)'
        ],
     dtype='object')], 
[0.8908595904596398, '勾配ブースティング回帰', 
    Index([
        'Cement (component 1)(kg in a m^3 mixture)',
        'Blast Furnace Slag (component 2)(kg in a m^3 mixture)',
        'Fly Ash (component 3)(kg in a m^3 mixture)',
        'Water  (component 4)(kg in a m^3 mixture)',
        'Superplasticizer (component 5)(kg in a m^3 mixture)',
        'Coarse Aggregate  (component 6)(kg in a m^3 mixture)',
        'Fine Aggregate (component 7)(kg in a m^3 mixture)', 
        'Age (day)'
        ],
     dtype='object')], 
[0.8905830131571623, '勾配ブースティング回帰', 
    Index([
        'Cement (component 1)(kg in a m^3 mixture)',
        'Blast Furnace Slag (component 2)(kg in a m^3 mixture)',
        'Fly Ash (component 3)(kg in a m^3 mixture)',
        'Water  (component 4)(kg in a m^3 mixture)', 
        'Age (day)'
        ],
     dtype='object')], 
[0.8899678568592612, '勾配ブースティング回帰', 
    Index([
        'Cement (component 1)(kg in a m^3 mixture)',
        'Blast Furnace Slag (component 2)(kg in a m^3 mixture)',
        'Water  (component 4)(kg in a m^3 mixture)',
        'Fine Aggregate (component 7)(kg in a m^3 mixture)', 
        'Age (day)'
        ],
     dtype='object')], 
[0.8896453161723351, '勾配ブースティング回帰', 
    Index([
        'Cement (component 1)(kg in a m^3 mixture)',
        'Blast Furnace Slag (component 2)(kg in a m^3 mixture)',
        'Fly Ash (component 3)(kg in a m^3 mixture)',
        'Water  (component 4)(kg in a m^3 mixture)',
        'Superplasticizer (component 5)(kg in a m^3 mixture)',
        'Fine Aggregate (component 7)(kg in a m^3 mixture)', 
        'Age (day)'
        ],
     dtype='object')]]

結論

スコアを見ると最初の0.625と比べて、0.893とかなり上昇しました。
ちゃんと全てを理解しているわけではありませんが、今は手を動かすことが重要だと強がりつつ、今日は一旦区切りとします。

この記事が気に入ったらサポートをしてみませんか?