Regonn&Curry.fm Episode 125収録後記 KaggleのSimulationコンペでscoreの変動を通知する仕組みを作る
このnoteは、Regonn&Curry.fm というポッドキャストの第125回の収録後記です。
第125回では、Papers with Datasets、不動産テックDiscord、CoeFont Studio、アップル春の新製品、4月目標結果、今週のKaggleについて話しました。
このnoteではSimulationコンペでscoreの変動をlineで通知する仕組みについて書きます。
何故作ったか、通知の例
KaggleのSimulationコンペでは、1日に数回の対戦が行われ、対戦の勝敗によりscoreが変動します。
この対戦は、いつ行われるかわからないため、scoreの変動が気になってしまい、My Submissiosのページを見に行く回数が増えてしまいました。
そこで、スコアの変動があると、Lineに通知するようにしました。
次のように通知がされます。
この画像の通知だと、対戦の結果、スコアが1166.4から1171.1に変動したことがわかります。またurlはリプレイのURLにしており、クリックするとどのような試合だったかがわかるリプレイのページに飛ぶことができます。
方法
Kaggle apiを使うと自分のサブミット一覧を取得することができます。
これを利用し、Kaggle apiを定期的に実行し、前回とscoreが変わっていればLineに通知します。
手順1:LineとKaggle apiの設定
次のブログを参考に、Lineのパーソナルアクセストークンを取得します。
また、次のブログを参考に、Kaggle apiの設定をしましょう。
手順2:My submissionsからrefとコンペ名の取得
KaggleのMy submissionsから、通知したいサブのref番号を取得します。
ref番号は、このPublic Scoreの隣にあるEpisodesのViewのリンク先のURLから取得することができます。
Hungry Geezeであれば、次のようなリンクになっているので、このxxxxxxの部分です。
https://www.kaggle.com/c/hungry-geese/submissions?dialog=episodes-submission-xxxxxx
これを通知したいサブの分だけ取得します。例えば10000と10001の2つのサブを通知したい場合は、後のコードのCHECK_SUB_REF_LISTは 次のようにします。
CHECK_SUB_REF_LIST = ['10000', '10001']
また、kaggleのコンペ名も後のコードのCOMPETEにします。
先程のurlの真ん中にあるもので、今回の場合は'hungry-geese'です。
COMPETE = 'hungry-geese'
手順3:コードを書く
from pathlib import Path
import requests
from kaggle.api.kaggle_api_extended import KaggleApi
SAVE_TXT_DIR = Path('hungry-geese-txt') # スコアの一時保存フォルダ
if not SAVE_TXT_DIR.is_dir():
SAVE_TXT_DIR.mkdir()
LINE_TOKEN = <lineのtokenを入れる>
COMPETE = 'hungry-geese' # コンペにより変更する
def send_line_notification(message):
line_token = LINE_TOKEN
endpoint = 'https://notify-api.line.me/api/notify'
message = "\n{}".format(message)
payload = {'message': message}
headers = {'Authorization': 'Bearer {}'.format(line_token)}
requests.post(endpoint, data=payload, headers=headers)
def get_before_score_from_file(ref):
file_path = Path(SAVE_TXT_DIR / f'{ref}.txt')
if file_path.is_file():
with open(file_path, 'r') as f:
before_score = f.readline()
else:
before_score = '0'
return before_score
def write_score_to_file(ref, public_score):
"""次に前回のスコアとして読み込むため、txtファイルにscoreを保存しておく"""
with open(SAVE_TXT_DIR / f'{ref}.txt', 'w') as f:
f.write(str(public_score))
def get_sub_info(submission):
public_score = submission['publicScore']
file_name = submission['fileName']
return public_score, file_name
def main():
api = KaggleApi()
api.authenticate()
submissions_list = api.competitions_submissions_list(COMPETE)
for ref in CHECK_SUB_REF_LIST:
for submission in submissions_list:
if str(submission['ref']) != ref:
continue
public_score, file_name = get_sub_info(submission)
message = f'score: {public_score + ",":<7} {file_name + ",":<40} url: https://www.kaggle.com/c/hungry-geese/submissions?dialog=episodes-submission-{ref}'
print(message)
before_score = get_before_score_from_file(ref)
write_score_to_file(ref, public_score)
if before_score != public_score:
message = f'score: {before_score} -> {message}'
send_line_notification(message)
break
if __name__ == "__main__":
CHECK_SUB_REF_LIST = ['10000', '10001'] # 通知したいサブに変更する
main()
上のコードで、前回と異なる場合に次のような通知がLineにされます。
手順4:定期的に実行する
MacやLinuxであれば、watchで定期に実行できます。10分ごとに実行する場合は、次のコマンドとなります。
watch -n 600 python main.py
終わりに
時間を節約できる仕組みの作成良いです。
これから次のページにSimulationコンペで使えるコードをまとめていきたいと思います。是非参照いただき、また書いてもらえれば。
コメントお待ちしています。匿名の質問はマシュマロから→https://marshmallow-qa.com/currypurin