【特徴量の追加編】機械学習を用いた大相撲千秋楽の勝敗予想
はじめに
前回は、「Sports Analyst Meetup #4」でのLTに向けて、ベンチマークとなる機械学習モデルを構築しました。新しい特徴量を追加することで、予測モデルの性能が向上することも確認しました。
本記事では、新しい特徴量を加えて、ベンチマークのLightGBMモデルの改善に挑戦します。
「連勝・連敗」特徴量の追加
千秋楽を迎えるに当たって、力士が何連勝・何連敗しているかを示す特徴量です。例えば9日に勝利した後で10〜14日に5連敗している場合は 'wins_till_final_day' が 0 で 'loses_till_final_day' が5になります。直感的には、千秋楽の勝敗に影響を与えそうな特徴量です。
def calc_wins_till_final_day(row): cnt = 0 for i in range(14): if row.iloc[14 - i] == 1: cnt += 1 else: return cnt return cnt def calc_loses_till_final_day(row): cnt = 0 for i in range(14): if row.iloc[14 - i] == 0: cnt += 1 else: return cnt return cnt df['wins_till_final_day'] = df.apply(calc_wins_till_final_day, axis=1) df['loses_till_final_day'] = df.apply(calc_loses_till_final_day, axis=1)
この2つの特徴量を前回の機械学習モデル(CVスコアはAUC: 0.554915)に加えたところ、CVスコアはAUC: 0.561075に向上しました。feature importanceで見ると上から3, 4番目に登場してきています。
testデータセットでの性能を見たところ、0.5を閾値にした場合の正答率と混同行列は次の通りに変化しました。
0.5476190476190477 → 0.5561904761904762
array([[302, 218], [257, 273]]) → array([[299, 221], [245, 285]])
tsfresh特徴量の追加
次いで、tsfreshという時系列特徴量を作成してくれるライブラリを利用します。勝敗の0, 1を時系列情報と見なし、特徴量を抽出する狙いがあります。
tsfreshの利用に当たって、dataframeを加工します。現在は1行ごとに列方向に勝敗を保持していますが、tsfreshでは縦方向にデータを保持する必要があります。
df_list = [] for index, row in df.iterrows(): _df = pd.DataFrame(row.iloc[1:15].T) _df.columns = ['results'] _df['id'] = index df_list.append(_df) df_tsf = pd.concat(df_list).reset_index(drop=True) df_tsf['results'] = df_tsf['results'].astype(float) df_tsf.head()
あとは extract_features 関数を利用するだけで、800近くの特徴量を生成できます。今回は select_features 関数を利用し選定した9個の特徴量を利用しました。
from tsfresh import extract_features extracted_features = extract_features(df_tsf, column_id='id')
これらの特徴量を機械学習モデルに加えたところ、CVスコアはAUC: 0.5699616に向上しました。feature importanceで見ると、追加した特徴量が予測に寄与していると確認できます。しかし残念ながら、testデータセットでの性能は「連勝・連敗」特徴量を追加した時点を上回ることはありませんでした。