はじめに
量の少ないデータ量を用いて分析を行った際に、モデルの評価方法としてLeaveOneOut交差検証を用いたので、共有します。
LeaveOneOut交差検証では、あるnサンプルのデータについて、1サンプルをテストデータ、その他をトレインデータとして用いて、トレーニングとテストを実施します。
そして、テストデータを入れ替えながらこれをn回繰り返し、モデルの性能を評価するというものです。
k分割交差検証でいえば、kをデータ量のnサンプルと同じ値にしたものになります。
データ量が少ない場合に用いられるそうです。
下記では単回帰をLOO法で評価してみます。
コード
あるDataFrameがあり、その中から単回帰に用いる説明変数をloo_column
で指定しています。
DataFrameのmokuteki
に目的変数が入っているとします。
データを入れ替えながらn回学習を行い、最終的にRootMeanSquaredError
を計算し返します。
単回帰にはstatsmodels
を用いています。
loo.py
from sklearn.model_selection import LeaveOneOut
from statsmodels import api as sm
loo_column = "setsumei"
def loo_rmse(df,loo_column):
loo_X = df[loo_column]
# 単回帰の定数項を作成します。
loo_X = sm.add_constant(loo_X)
loo_y = df_analytics["recognition"]
loo = LeaveOneOut()
loo.get_n_splits(loo_X)
# square_errorを保存するリスト
se_list = list()
# trainとtestに用いるデータのindexを入れ替えながらデータ分くりかえす
for train_index, test_index in loo.split(loo_X):
X_train, X_test = loo_X.iloc[train_index], loo_X.iloc[test_index]
y_train, y_test = loo_y.iloc[train_index], loo_y.iloc[test_index]
# 単回帰の学習
model = sm.OLS(y_train,X_train)
result = model.fit()
# 学習結果を元にtestデータに対して予測。誤差を得る。
pred = result.params["const"] + result.params[loo_column] * X_test[loo_column].values[0]
diff = pred - y_test.values[0]
# 誤差を二乗して保存
se_list.append(diff**2)
# 二乗誤差を平均し、ルートを取って返す
ar = np.array(se_list)
print("RMSE:",np.sqrt(ar.mean()))
参考
ありがとうございました。