LoginSignup
14
17

More than 5 years have passed since last update.

半歩ずつ進める機械学習 ~scikit-learnボストン住宅価格編~⑤

Last updated at Posted at 2019-04-05

前回まで

前々回にscikit-learnのLinearRegressionを使って
ボストン住宅価格を予測するモデルを作り、交差検証を行いました
しかし学習・テストデータの分割方法が原因(仮定)で交差検証結果のバラつきが大きい事を受けて
前回の投稿で、複数のデータ分割方法について学びました
今回は、前回学んだ事を踏まえて、モデルの検証と精度アップを試みます。

まず試してみよう

前回学んだデータ分割方法は以下の三種でした

  • KFold
  • Stratified KFold
  • Group KFold

下の二つは分類問題に使う物らしいので
現在取り組んでいるボストン住宅価格の予想にはKFold(Shuffle = True)が適切かと思います

まずはバラつきが大きかった交差検証のコード

boston.py
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
print(cross_val_score(lr,env_data,price_data,cv = 5)
#[ 0.63861069  0.71334432  0.58645134  0.07842495 -0.26312455]

cross_val_scoreは引数cvに整数を指定すれば、指定された数にcross_val_scoreの中で分割してくれます。
cvにはインデックスを返すジェネレータを渡す事も可能で、その場合は渡されたジェネレータを使ってデータ分割を行うようです。
cross_val_scoreのリファレンス

ではランダムにインデックスを抽出してくれるジェネレータを作り、cross_val_scoreに渡してみます

boston.py
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
kf = KFold(n_splits = 5,shuffle = True,random_state = 1)
splitter = kf.split(env_data,price_data)#ジェネレータ生成
print(cross_val_score(lr,env_data,price_data,cv = splitter))
#[0.76348092 0.64664899 0.79214918 0.65064254 0.73524062]

KFold(random_state = 1)は乱数のシードです、毎回抜き出すデータが変わってもいい場合は指定はいりません。

何も考えずにデータを分割した場合と比べて結果は一目瞭然ですね

KFold(shuffle = False)
[ 0.63861069 0.71334432 0.58645134 0.07842495 -0.26312455]
KFold(shuffle = True)
[0.76348092 0.64664899 0.79214918 0.65064254 0.73524062]

パッと見るとモデルが良くなったように見えますが、評価方法が変わっただけでモデルの性能が変わったワケではありません。

cross_validate

ここまで交差検証にはcross_val_scoreを使用してきましたが
交差検証を行うのにcross_validateというメソッドもあります。
このメソッドを使えば目的変数と説明変数からモデルを作る為にかかった時間が出せたり
複数の評価指標を一度に計算出来たりと、cross_val_scoreと比較して便利な部分があります。
使い方はcross_val_scoreと殆ど同じです。

valid.py
from sklearn.model_selection import cross_val_score, cross_validate
from sklearn.model_selection import KFold
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
kf = KFold(n_splits = 5,shuffle = True,random_state = 1)

score = cross_val_score(lr,env_data,price_data,cv = kf,scoring = "neg_mean_squared_error")
scores = cross_validate(lr,env_data,price_data,cv = kf,scoring = {"neg_mean_squared_error","neg_mean_absolute_error"})

print(score)
print(scores)
"""
[-23.37456303 -28.62770207 -15.16049987 -27.21667391 -23.37278076]

{'fit_time': array([0.05200005, 0.00099993, 0.        , 0.00099993, 0.00300026]), 
'score_time': array([0.        , 0.        , 0.00099993, 0.00099993, 0.        ]), 
'test_neg_mean_absolute_error': array([-3.74913847, -3.30699838, -3.02845012, -3.56953509, -3.29932279]), 
'train_neg_mean_absolute_error': array([-3.19838165, -3.23054675, -3.42791942, -3.22939478, -3.26295039]), 
'test_neg_mean_squared_error': array([-23.37456303, -28.62770207, -15.16049987, -27.21667391,-23.37278076]), 
'train_neg_mean_squared_error': array([-21.86800809, -20.50443823, -23.79796506,-20.81849064,-21.61049124])}
"""

cross_validateで複数の評価指標による評価を一度に行う場合、scoring引数にdict(辞書型)を渡します。
一度に多角的な評価が可能なので、とても便利です

引数 "scoring" について

ここまでcross_valid_scoreを使う時には引数として

  • 説明変数
  • 目的変数
  • 分割数 or ジェネレータ

上記のみを渡してきましたが、cross_val_scorecross_validateには共に
scoringという引数が存在します。
これは、交差検証により、どんな指標を求めるかを指定するもので
指定無しの場合はデフォルトで推定器(Estimator)の持つ評価指標を採用します
今回のケースでは推定器はLinearRegressionなので、決定係数が採用されます。

その他の指標について

scikit-learnに標準で入っている評価指標は、以下の通りです。

Scoring Function Comment
Classification
‘accuracy’ metrics.accuracy_score
‘balanced_accuracy’ metrics.balanced_accuracy_score for binary targets
‘average_precision’ metrics.average_precision_score
‘brier_score_loss’ metrics.brier_score_loss
‘f1’ metrics.f1_score for binary targets
‘f1_micro’ metrics.f1_score micro-averaged
‘f1_macro’ metrics.f1_score macro-averaged
‘f1_weighted’ metrics.f1_score weighted average
‘f1_samples’ metrics.f1_score by multilabel sample
‘neg_log_loss’ metrics.log_loss requires predict_proba support
‘precision’ etc. metrics.precision_score suffixes apply as with ‘f1’
‘recall’ etc. metrics.recall_score suffixes apply as with ‘f1’
‘roc_auc’ metrics.roc_auc_score
Clustering
‘adjusted_mutual_info_score’ metrics.adjusted_mutual_info_score
‘adjusted_rand_score’ metrics.adjusted_rand_score
‘completeness_score’ metrics.completeness_score
‘fowlkes_mallows_score’ metrics.fowlkes_mallows_score
‘homogeneity_score’ metrics.homogeneity_score
‘mutual_info_score’ metrics.mutual_info_score
‘normalized_mutual_info_score’ metrics.normalized_mutual_info_score
‘v_measure_score’ metrics.v_measure_score
Regression
‘explained_variance’ metrics.explained_variance_score
‘neg_mean_absolute_error’ metrics.mean_absolute_error
‘neg_mean_squared_error’ metrics.mean_squared_error
‘neg_mean_squared_log_error’ metrics.mean_squared_log_error
‘neg_median_absolute_error’ metrics.median_absolute_error
‘r2’ metrics.r2_score

リファレンスはこちら

次回へ

次回は上記スコアリング指標の内容を勉強するか、住宅価格予測モデルの精度向上のどちらかをやりたいと思います。

お願い

機械学習の初心者が、学んだ知識の確認と備忘用に投稿しています。
間違っている部分や、何かお気づきの事がありましたらご指摘頂けますと幸いです
あと、独学者なので「私も今勉強中なんです!」みたいな人がいればコメント貰えると喜びます。

14
17
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
14
17