予測値を最頻値化版-LightGBM Base line−コメント付き (CV: 0.14017 / LB 0.13173 ) by Oregin

次の一投の行方を予測! プロ野球データ分析チャレンジ

簡単な前処理(inning数、裏表列の追加、game_infoの結合,カテゴリカル変数のエンコーディング)を行ったサンプルコードです。ご参考までご活用ください。

※Google Colabで実行可能です。

※今回のタスクは、多値分類タスクなので、交差検証での予測値を平均ではなく、最頻値とすべきとのご指摘をいただき修正いたしました。

CV= 0.14017 LB= 0.13173 でした。

ディレクトリ構成

  • ./notebook : このファイルを入れておくディレクトリ(カレントディレクトリをこのディレクトリに移動して実行してください。)
  • ./features : 前処理した特徴量を入れておくディレクトリ
  • ./data : test_data.csv,train_data.csv,game_info.csvを入れておくディレクトリ
# xfeatのインストール
!pip install git+https://github.com/pfnet-research/xfeat.git
# ------------------------------------------------------------------------------
# 各種ライブラリのインポート
# ------------------------------------------------------------------------------
import pandas as pd
import numpy as np
import json
import os
import random
import string
import re

from pathlib import Path
from tqdm import tqdm

import lightgbm as lgb
from sklearn.model_selection import KFold
from sklearn.metrics import f1_score
from sklearn import preprocessing
# データ読み込み
#####################################
###### train ########################
#####################################

train = pd.read_csv('../data/train_data.csv')
target = train['y']
train = train.drop(['id','y'],axis=1)

#####################################
#### test ###########################
#####################################

test = pd.read_csv('../data/test_data.csv')
test = test.drop('id',axis=1)

#####################################
#### test ###########################
#####################################

game = pd.read_csv('../data/game_info.csv')
game = game.drop('Unnamed: 0',axis=1)

前処理

# 訓練データのみにある列名(テストデータにはない列名)のリストを作成
delcollist = []
for col in train.columns:
  if not col in test.columns:
    delcollist.append(col)
# 訓練データのみにある列名を削除
train = train.drop(delcollist,axis=1)
# inning を 数値に変換
train['inning_num'] =  train['inning'].apply(lambda x: re.sub("\\D", "", x))
test['inning_num'] =  test['inning'].apply(lambda x: re.sub("\\D", "", x))
# 表裏を判定する関数
def omote_ura(x):
  if '表' in x:
    return 0
  else:
    return 1
# 表裏の列を追加
train['inning_ForB'] =  train['inning'].apply(lambda x: omote_ura(x))
test['inning_ForB'] =  test['inning'].apply(lambda x: omote_ura(x))
# game_infoの追加
train = pd.merge(train, game, how='left')
test = pd.merge(test, game, how='left')
# inningの削除
train = train.drop('inning',axis=1)
test = test.drop('inning',axis=1)
# カテゴリカル変数のカラムを抽出
categorical_columns = [x for x in train.columns if train[x].dtypes == 'object']
# カテゴリカル変数をカウントエンコードする
from xfeat import CountEncoder

encoder = CountEncoder(input_cols=categorical_columns)
train = encoder.fit_transform(train)
test = encoder.transform(test)
# 訓練データにターゲット列を追加する
train['target'] = target
# カテゴリカル変数をターゲットエンコーディングする
from sklearn.model_selection import KFold
from xfeat import TargetEncoder

fold = KFold(n_splits=5, shuffle=True, random_state=42)
encoder = TargetEncoder(input_cols=categorical_columns,
                        target_col='target',
                        fold=fold)
train = encoder.fit_transform(train)
test = encoder.transform(test)
# エンコーディング前の列を削除する
train = train.drop(categorical_columns,axis=1)
test = test.drop(categorical_columns,axis=1)
train = train.drop('target',axis=1)

学習と予測

SEED = 42
NFOLDS = 5
#####################################################3
### LGBで学習、予測する関数の定義
########################################################
def Train_and_Pred(train,target,test):
    # --------------------------------------
    # パラメータ定義
    # --------------------------------------
    lgb_params = {
                    'objective': 'multiclass',
                    'boosting_type': 'gbdt',
                    'n_estimators': 50000,
                    'colsample_bytree': 0.5,
                    'subsample': 0.5,
                    'subsample_freq': 3,
                    'reg_alpha': 8,
                    'reg_lambda': 2,
                    'random_state': SEED,
                    "bagging_fraction": 0.5520399476847848,
                    "bagging_freq": 1,
                    "feature_fraction": 0.4436319472771827,
                    "lambda_l1": 0.01113869595673112,
                    "lambda_l2": 8.706009358617911e-07,
                    "learning_rate": 0.012307412937706345,
                    "min_child_samples": 18,
                    "num_leaves": 8,        
                  }

    # --------------------------------------
    # 学習と予測
    # --------------------------------------
    kf = KFold(n_splits=NFOLDS, shuffle=True, random_state=SEED)
    lgb_oof = np.zeros(train.shape[0])
    lgb_pred = pd.DataFrame()

    for fold, (trn_idx, val_idx) in enumerate(kf.split(X=train)):
        X_train, y_train = train.iloc[trn_idx], target.iloc[trn_idx]
        X_valid, y_valid = train.iloc[val_idx], target.iloc[val_idx]
        X_test = test

        # LightGBM
        model = lgb.LGBMClassifier(**lgb_params)
        model.fit(X_train, y_train,
                  eval_set=(X_valid, y_valid),
                  eval_metric='logloss',
                  verbose=False,
                  early_stopping_rounds=500
                  )

        lgb_oof[val_idx] = model.predict(X_valid)
        lgb_pred[f'fold_{fold}'] = model.predict(X_test)
        f1_macro = f1_score(y_valid, lgb_oof[val_idx], average='macro')
        print(f"fold {fold} lgb score: {f1_macro}")

    f1_macro = f1_score(target, lgb_oof, average='macro')
    print("+-" * 40)
    print(f"score: {f1_macro}")
    print(f"model score: {model.score(train, target)}")

    return f1_macro,lgb_pred
#学習と予測の実行
score,pred = Train_and_Pred(train,target,test)
# 予測値の最頻値を求める(ご指摘をいただき修正)
sub_pred = pred.mode(axis=1)[0]
# ------------------------------------------------------------------------------
# 提出ファイルの作成
# ------------------------------------------------------------------------------

#テスト結果の出力
submit_df = pd.DataFrame({'y': sub_pred.astype(int)})
submit_df.index.name = 'id'
submit_df.to_csv('submission.csv')

以上

添付データ

  • BaseLine_BaseBall2.ipynb?X-Amz-Expires=10800&X-Amz-Date=20241207T215206Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIP7GCBGMWPMZ42PQ
  • Favicon
    new user
    コメントするには 新規登録 もしくは ログイン が必要です。