なぜn_estimatorsやepochsをパラメータサーチしてはいけないのか
ハイパーパラメータを探索するため、グリッドサーチやOptunaなどを利用することがあると思います。
しかし、「ハイパーパラメータ探索してみた」のようなQiita記事などでは間違って書かれていることも多いのですが、XGBoostやLightGBMの n_estimators
( num_boosting_rounds
)やKerasの epochs
をパラメータサーチの対象にしてはいけません。
いけません、というか、すごく無駄なことをしています。
なぜ、n_estimatorsやepochsを探索すると無駄なのか
理由はシンプルで、これらのパラメータは「大きい値で精度確認する過程で小さい値の結果も分かる」からです。
LightGBMのn_estimators
は構築する決定木の数を表しています。
例として、n_estimators=5
(こんな小さい値で学習することはないですが、簡単のため)で学習を行ったとします。学習の過程で、n_estimators=1
のスコアも、n_estimators=2
のスコアも確認することができます。
1, 2, ..., 5とn_estimators
を振って確認した場合、合計15個の木を構築する必要がありますが、正しくやれば5個の木で十分です。単純計算で3倍、探索を高速化することができるでしょう。
n_estimatorsは学習率によっては5000程度になることもざらにあります。500, 1000, 1500, ... , 5000と500刻みに探索した場合、合計で27500個の木を構築することになります。本当なら5000個で済むのに。しかも、500刻みで探索していた場合、最適な点を見逃す可能性もあります。
Kerasのepochs
に代表される、ニューラルネットワークのepoch数も同様です。
epochs=100
で学習した場合、その過程で1epochから100epochまでのすべての学習状態を取得することができます。
では、どうすればいいのか?
一般的なのはEarlyStoppingを使用することでしょう。
テストデータとは別にバリデーションデータを用意し、バリデーションで対しての精度がサチったら(一定epochのあいだ向上が見られなかったら)終わりにするという方法です。
LightGBMのscikit-learn interfaceを使っているなら、eval_set
とearly_stopping_rounds
を指定すれば動きます。n_estimators
は大きめに取っておくとよいでしょう。
import lightgbm as lgb params = { 'n_estimators': 10000 # 大きめにとっておく # 他のパラメータは省略 } model = lgb.LGBMClassifier(**params) model.fit(X_train, y_train, eval_set=[(X_valid, y_valid)], early_stopping_rounds=100)
scikit-learn interfaceを使っていないなら、lgb.train
関数にvalid_sets
、early_stopping_rounds
を設定すれば動きます。num_boost_round
はn_estimators
と同様、大きめに取っておきましょう。
import lightgbm as lgb train_set = lgb.Dataset(X_train, y_train) valid_set = lgb.Dataset(X_valid, y_valid) model = lgb.train(params, train_set, num_boost_round=10000, valid_sets=[valid_set], early_stopping_rounds=100)
KerasでEarlyStoppingを行うならkeras.callbacks.EarlyStopping
を使います。使う場合はkeras.callbacks.ModelCheckpoint
と組み合わせ、最も良いモデルを保存するようにしておくと良いでしょう。
from keras import callbacks # モデルの定義とcompileは予めしておく callbacks = [ callbacks.ModelCheckpoint('best_model.h5', save_best_only=True) callbacks.EarlyStopping(patience=5) # 5epoch改善が無ければ止める ] model.fit(X_train, y_train, epochs=1000, callbacks=callbacks, validation_data=[(X_valid, y_valid)]
PyTorchなど、他のフレームワークの場合もEarlyStoppingの仕組みは実装されています。
まとめ
学習の途中経過が全て確認可能な手法を使うとき、n_estimatorsやepochsのような「学習回数」のパラメータを調整するのは時間がもったいないです。
他にもやりがちな例で各種ライブラリのverbose
をチューニングしてしまう、というものがあります。verboseは学習中にどれくらいメッセージを吐き出すかというパラメータで、モデルの精度には一切影響を与えません。精度が変わらないので、もちろんチューニングする必要はありません。
機械学習モデルをチューニングする時はそれぞれのパラメータの意味を理解した上で行うようにしましょう。使っているアルゴリズムに対しての理解を深めることも助けになるでしょう。
Dockerでデータ分析環境を手軽に作る方法
何かデータ分析を行わなければいけないとき、手軽に分析環境を用意したいというニーズがあります。
Jupyter Notebook上でnumpy、pandas、matplotlib、scikit-learnあたりが使えれば十分でしょうか。XGBoostやLightGBMといったライブラリも使えるようにしておきたいという人もいるかと思います。
一方、ローカルにいろいろなライブラリをインストールしていくと、次第に環境が汚れていってライブラリの衝突などが起こりやすくなってしまいます。
KaggleにはKernelという計算環境があり、そこには主要な機械学習ライブラリが予めインストールされています。データ分析をやっていく上で不自由はありません。今回はDockerとdocker-composeを使ってKaggle Kernelを手元に再現し、ポータブルな分析環境として使う方法を紹介します。
データ分析界隈には、なんとなくDockerを敬遠しているような人もいるかと思いますので、この機会に入門してしまいましょう。
解説はMacOSで行いますが、Dockerとdocker-composeがインストールできれば同じ方法が使えるかと思います。
登場する用語の説明
Dockerは、まっさらな環境を簡単に作るツールです。
Dockerfileというファイルに環境の設定を書けば、そのとおりの環境を作ることができます。他人が作ったDockerfileに自分なりのカスタマイズを加えることも可能です。
今回は、Kaggle公式が公開しているpython環境をもとにカスタマイズを行っていきます。
加えてコンテナ(container)とイメージ(image)という用語も覚えましょう。
イメージはDockerfileをビルドして作ります。イメージはDockerfileという設計図を元に作られた「型」だと考えて良いと思います。
イメージを元にコンテナを起動し、そのコンテナ上でJupyterを立ち上げます。利用する際はコンテナにアクセスします。イメージができていればコンテナは数秒で起動できますし、どれだけ環境を汚してもイメージから起動しなおせばまた使うことができます。同じイメージから何個もコンテナを起動することも可能です。
Google Container Registryは便利なイメージが多く登録されているサイトです。今回はKaggleが提供しているPythonイメージを利用します。
docker-composeはDockerfileのビルドと起動を管理するツールです。
Dockerコンテナを起動する際、いろいろなオプションをつけることができます。しかし、それをいちいちコマンドラインで打つのは煩雑です。docker-composeを使えば、様々なオプションをdocker-compose.ymlというYAMLファイルで設定することができます。
docker-composeは本来は複数のコンテナを連携して使うために作られたツールですが、今回はコンテナを簡単に立ち上げるためだけに使いたいと思います。
Dockerとdocker-composeのインストール
それでは、Dockerとdocker-composeをインストールしていきましょう。
既にインストール済みの方はこの節は読み飛ばしてください。
https://docs.docker.com/docker-for-mac/install/ に従ってDocker Desktop for Macをインストールします。
インストールが終わったら、アプリケーションからDocker.app
を起動します。(起動にはしばらく時間がかかるかもしれません)
Dockerが起動されたら以下のコマンドを打ち、dockerとdocker-composeのバージョンが表示されるか確認してください。
$ docker --version
$ docker-compose --version
Kaggle Kernelを元に分析環境を作る
それでは、Kaggleが提供しているDockerfileを元に、データ分析の環境を作っていきます。
今回は以下のようなフォルダ構成で解析を進めていくとします。
.
├── .dockerignore
├── Dockerfile
├── docker-compose.yml
├── input/ # データ
├── notebook/ # Jupyter Notebook
└── script/ # スクリプト
このうち、以下の3つのファイルは新しく作成します。
- Dockerfile
- docker-compose.yml
- .dockerignore
Dockerfile
Dockerfileは、イメージの定義です。どういうOSを使って、どういうライブラリをインストールするのか、という内容を書きます。
# kaggleのpython環境をベースにする
FROM gcr.io/kaggle-images/python:v56
# ライブラリの追加インストール
RUN pip install -U pip && \
pip install fastprogress japanize-matplotlib
内容はこれだけです。
FROM gcr.io/kaggle-images/python:v56
は、Google Container Registry(gcr.io)上にあるKaggle公式Dockerイメージを出発点にしてイメージを定義する、という意味です。
gcr.io/kaggle-images/python
には、既にnumpyやpandasを始めとして、データ分析に必要な多くのライブラリが含まれています。
:v56
はタグの指定です。KaggleのDockerイメージは日々改善されているので、今の時点での最新版を書いておくと良いでしょう。タグの一覧はgcr.io/kaggle-images/pythonにアクセスすると見ることができます。
:latest
と指定して最新版を入れることもできますが、イメージが更新されるたびにダウンロードが走ってしまいますし、環境がころころ変わるのは望ましいことではないので、バージョンを特定しておくことをおすすめします。
もし足りないライブラリがあるならば、 RUN
コマンドを使うことで pip install
をすることができます。
docker-compose.yml
docker-compose.yml
にはコンテナを起動する際の設定を書きます。
version: "3"
services:
jupyter:
build: .
volumes:
- $PWD:/tmp/working
working_dir: /tmp/working
ports:
- 8888:8888
command: jupyter notebook --ip=0.0.0.0 --allow-root --no-browser
version
はdocker-compose.ymlの書き方のバージョンです。3を指定しておけばよいかと思います。
services
以下に起動するコンテナの設定を書いていきます。jupyter
はコンテナを管理するための名前です。
build: .
は同じフォルダにあるDockerfileをビルドする、という意味です。先程作成したDockerfileがビルドされます。
volumes
はマウントするフォルダの設定です。$PWD:/tmp/working
とすることにより、現在のディレクトリを、Dockerコンテナ上の/tmp/working
に紐付けることができます。これにより、Dockerコンテナの中からでも現在のディレクトリ(とその中のデータとか)にアクセスすることができます。
working_dir
はコンテナ内の初期ディレクトリの設定です。今回は/tmp/working
に設定しています。
ports
はポートフォワードの設定です。手元のポート:コンテナのポート
の形式で書きます。
ふだんJupyter Notebookを起動するとき、localhost:8888
からアクセスすることになるかと思います。今回はDockerコンテナ上でJupyterを起動するため、Dockerコンテナ内のlocalhost:8888
にアクセスしないとJupyterを見ることができません。しかし、portsの設定をしておくことで、Dockerコンテナ内の localhost:8888
を手元のlocalhost:8888
につなぐことができます。
command
はDockerコンテナを起動したときに走るコマンドの内容です。今回はJupyter Notebookを起動しています。
いくつか見慣れないオプションがついているかと思います。
--ip=0.0.0.0
は起動したJupyter Notebookにコンテナ外からアクセスできるようにするオプションです。
--allow-root
はルートでの実行を許可するオプションです。Dockerコンテナはデフォルトでルート権限で起動するので、このオプションが必要です。
--no-browser
はJupyter Notebook起動時にブラウザを立ち上げないオプションです。
.dockerignore
.dockerignoreは、Dockerfileをビルドする際に無視するファイルを列挙するものです。
今回の場合、データやノートブックはDockerfileのビルドの瞬間は必要ありませんから、.dockerignore
に書いておきましょう。(コンテナとのデータの共有は、ビルドを行った後にマウントで対応します)
input
notebook
script
input/
などに大容量のデータが入っていて、かつ.dockerignore
に記述もしなかった場合、Dockerのビルドの際に時間がかかるようになってしまいます。ビルドに必要の無いファイルやフォルダは、.dockerignore
に書くように心がけましょう。
起動してみる
それでは、実際に分析環境を起動してみましょう。
ここで注意ですが、この操作は初回時に限りめちゃめちゃ重いデータをダウンロードする必要があります。実は、Kaggleの公式イメージは便利なライブラリがたくさん入っている反面、とても重いDockerイメージになっています。その容量、なんと18GB!
学校や職場など、WiFi環境が整っている場所で行ってください。間違ってもテザリング中なんかにやらないようにしてくださいね。
$ docker-compose up --build
まず、最初にDockerfileのビルドが走り、その後Dockerコンテナの中でJupyter Notebookが起動されます。最後のJupyter Notebookが起動するところはだいたいこんな感じのログになるかと思います。
jupyter_1 | [I 07:11:32.796 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
jupyter_1 | [I 07:11:33.065 NotebookApp] JupyterLab extension loaded from /opt/conda/lib/python3.6/site-packages/jupyterlab
jupyter_1 | [I 07:11:33.065 NotebookApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
jupyter_1 | [I 07:11:33.068 NotebookApp] Serving notebooks from local directory: /tmp/working
jupyter_1 | [I 07:11:33.069 NotebookApp] 0 active kernels
jupyter_1 | [I 07:11:33.069 NotebookApp] The Jupyter Notebook is running at:
jupyter_1 | [I 07:11:33.069 NotebookApp] http://33c518cf1679:8888/?token=hogefugatoken
jupyter_1 | [I 07:11:33.069 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
jupyter_1 | [C 07:11:33.069 NotebookApp]
jupyter_1 |
jupyter_1 | Copy/paste this URL into your browser when you connect for the first time,
jupyter_1 | to login with a token:
jupyter_1 | http://33c518cf1679:8888/?token=hogefugatoken
最後のlogin with a tokenの下のURLをコピーし、33c518cf1679
の部分をlocalhost
に変えてブラウザのURLバーに入れればJupyter Notebookにアクセスできます。
ローカルにあるファイルにもアクセスできることを確認してください。
まとめ
今回はDockerとdocker-composeを使い、Kaggleの環境をベースにした分析環境の立ち上げを行いました。
自分なりにカスタマイズしたDockerfileを持っておけば、新しいデータが来たときも迅速に解析に取り掛かることができます。
みなさんもぜひ試してみてください。
- 作者: 山田明憲
- 出版社/メーカー: 技術評論社
- 発売日: 2018/08/25
- メディア: Kindle版
- この商品を含むブログを見る
追記 (2019/05/13)
Twitterでmhiro2さんにいただいた指摘を元に記事を修正しました。ありがとうございました!
Docker Hub のイメージは古いので、https://t.co/mGMtjYLeFK を使った方がより現行カーネルの環境に近くライブラリも新しいと思います。fastprogress も カーネルでは既に使えますし、gcr の方の latest だと入ってるみたいです。GPU 前提ならビルドするしかないので、NGC 使うのがベターですね。
— mhiro2 (@mhiro2_1127) 2019年5月13日
追記2 (2019/07/12)
Dockerのメモリ上限を大きくする方法についてu++さんが書いてくださいました。メニューバーのDockerマークから設定に飛び、メモリ上限を拡張してください。
Kaggle Eloコンペの振り返り・上位解法まとめ
KaggleのElo Merchant Category Recommendationコンペに参加しました。
僕は@kasuminkoさん、@hirokasさんとチームを組んで、ラスト2週間だけ参加しました。結果から書くと、Public 221位からのPrivate 2220位という乱高下で儚く散りました。
手元に銀メダル相当のスコアを持っていたにもかかわらず、間違ったサブミットを選んでしまっており、とても悔しいです。
- コンペの概要
- 上位解法
- 1st place solution (30CrMnSiA)
- 特徴量
- モデル
- 5th place solution (Evgeny Patekha)
- 特徴量
- モデル
- 7th place solution (senkin)
- 特徴量
- モデル
- その他
- 11th place solution (Zakaria EL Mesaoudi)
- 特徴量
- モデル
- その他
- 16th place solution (nlgn)
- 特徴量
- モデル
- 18th place solution (pocket)
- 特徴量
- モデル
- 上位解法のうち、今後も使えそうなアイディアのメモ
- 1st place solution (30CrMnSiA)
- 僕たちの解法
コンペの概要
Eloというブラジルのカード会社が主催となり、各ユーザーの購買行動に対応したRoyalty Scoreという値を予測するコンペです。
データとしては各カードの属性を書いたtrain.csv
/test.csv
と、それぞれのカードに紐付いた購買履歴(transaction)を表すhistorical_transactions.csv
/new_merchant_transactions.csv
の4ファイルが与えられていました。
タスクの種類は値を当てる回帰で、targetの分布は0を中心とした分布に加え、-33付近に外れ値が存在するというものでした。
評価指標はRMSEで、外れ値の影響を受けやすい指標です。特に今回は-33.22付近とかなり外れた位置にサンプルが存在するため、外れ値をどう捌くかが大きな論点のひとつでした。
続きを読むQuoraコンペの振り返りと上位解法まとめ
KaggleのQuora Insincere Questions Classificationコンペに参加しました。
結果は121位で、銀メダルでした。これで銀メダルが3枚目です。わーい。
Public Leaderboardで692位と振るわず、コンペのdeadlineが修論発表の当日だったので直前ほとんど何も出来ず、「Quora何もわからなかった」という絶望感でいっぱいでした。
Quora、最終日が修論発表当日なので時期が悪すぎる……最初は意気揚々とやってたけど今は普通に沼っているので終わったらちゃんと復習する枠かなぁ
— えじ|Amane Suzuki (@SakuEji) 2019年2月2日
蓋を開けてみたら多くのTeamが消え、あれよあれよという間に銀メダルになりました。
- タスクの概要
- 上位陣の手法
- 1st place solution (Psi)
- モデル
- Embedding
- 閾値
- バリデーション
- 2nd place solution (takapt)
- 3rd place solution (Guanshuo Xu)
- 7th place solution (yufuin)
- 10th place solution (tks)
- 13th place solution (Canming Wang)
- 15th place solution (Bai)
- 1st place solution (Psi)
- 覚えておきたいテクニック
- 【おまけ】151th place solution (僕)
- 終わりに
タスクの概要
QuoraというQ&Aサイト(日本で言うYahoo!知恵袋)に投稿された質問の中で、有害なもの(攻撃的、差別的、卑猥など)を分類するコンペです。
タスクの種類は0 or 1の2値分類で、正例がかなり少ない不均衡なデータセットになっています。
評価指標はF1 scoreです。確率として出力した予測値をどこから1として、どこから0とするかの閾値決めが大きく最終スコアに影響を与えました。
コンペの形式としてはKernel経由の提出のみを受け入れるKernel Onlyコンペかつ、締切後にテストデータを差し替えて順位を決定する2-stage制コンペでした。 1st stageではテストデータが56,000件程度であるのに対し、2nd stageでは376,000件と6倍程度に増えることが予告されていました。
制限時間内に実行出来なかった場合は順位がつかないという厳しいペナルティがあるため、素早く前処理をしたり、上手くモデルを訓練する必要のあるコンペだったと言えるでしょう。
続きを読む決定木は本当に変換に依存しないのか?
決定木をベースとしたモデル(RandomForestやXGBoost、LightGBMなど)は正規化などの前処理が必要ないと言われています。
理由として挙げられるのは「決定木は特徴量の大小関係のみに着目しており、値自体には意味がないから」というものです。
先日もkaggler-jaというSlackチャンネルでこの話が出ました(細かく読まなくて大丈夫です)。
自分で質問に答えておいて、「本当か?」という疑問が湧いてきたので実験してみることにしました。
結論から言うと、StandardScalerやMinMaxScalerなどの各特徴量について線形な変換に対しては結果は変化しないけど、logをかけたりするとちょっと変わるということが分かりました。
決定木のアルゴリズム(ざっくり)
決定木を作成する際のおおまかな流れは以下のとおりです。
- 目的変数(target)をうまく分離できる特徴量と、分割境界を決める
- サンプルを基準よりも小さい群と大きい群に分ける
- それぞれの群を繰り返し分割していく
2018年、たいへんお世話になりました。
大晦日なので実家に帰っています。あまり酒を嗜んだりはしない両親とシャンパンを飲み、話しているうちにこんな時間になってしまいました。
帰省する前は「親と話すことなんてそんなに多くはないよなぁ」と思っていましたが、24歳になって昔(中高時代など)を振り返っているうちに「あの頃自分はこう思っていたんだ。親のことをこう見ていたんだ」と伝えたくなりました。
父方、母方の祖母がともに今年亡くなったこともあり、残った人生を謳歌しようとしている両親を見ていると考えさせられるものがあります。
さて。本年を振り返ってみますと、良くも悪くも技術漬けの毎日であったように思います。
プログラミング言語としてはPython、C++、Golang、Rustあたりをちょいちょいと触っていましたし、要素技術としては機械学習、特にKaggleに多く触れた一年でした(研究をしろ)。
今年のKaggle戦績は銀2枚銅1枚で、それなりにコミットしたコンペでそれなりの結果を残したということに終止するかと思います。来年は金ピカのメダルとお金を狙っていきたいですね。DeNAは強い人ばかりなので、入社前にMasterになりたいという欲求が強いです。
競技プログラミングは結局水色でフィニッシュしてしまいました。特に終盤でRatedのコンテストに全然出られなかったのが足を引っ張ったかと思います。来年は予定の調整を頑張っていきたいです。
プログラミングまわりで少し頑張ったのは、9/21から毎日草を生やしたということでしょうか。もちろん途中にはすごくしょうもないコミットが挟まっていて、「手段の目的化」という言葉が頭をよぎらないわけではないですが、どんな日でも毎日PCを開いてコードを書くという習慣付けが行えたことは価値があることだと思っています。
ブログは自分としてはがんばって書きました。このブログは今年の4月に開設しましたが、現在読者数が47人になり、ちらほらと読んでいただけているようです。切りの良い数字を目指したいので、年末やることがなくてこの記事を読んでいる方は読者登録ボタンをぽちりと押して頂けると幸いです。来年は月1回以上書くという超低い目標を設定してやっていきたいと思います。金メダル取りました!って記事が書けるといいですね。
年末っぽいコンテンツとしては、Amazonの購入履歴などを見ながら今年買って(契約して)よかったものを挙げておきましょう。順番は思いついた順です。
- Google Home
- 声で指示するのが予想以上にストレスフリーだった。主に使用している機能はNature Remoと組み合わせた家電の制御と、目覚まし。あとは天気予報。今はAmazonで売ってないっぽいです。
- Netflix
- 月額1000円以下で無限にコンテンツがあってしまうので学生にはおすすめできない。
- アイリスオーヤマのふとん乾燥機
- 睡眠時のQOLが爆上がりする。知らない間に汗を吸って重たくなっていた布団が軽くなる。最高。
- ラムダッシュの5枚刃のやつ
- 今まで3枚刃を使っていたけど完全に時間の無駄だった。仕上がりのクオリティとかかる時間が格段に違う。クリスマスプレゼントでもらった。
- Dashlane
- パスワードを覚えたり、手入力したりという手間から開放された。1年契約した。
- Happy Hacking KeyBoard BT
- タイプ感がすごく良い。MBPと組み合わせた際の優雅さを犠牲に満足感を得る感じ。彼女にもプレゼントした。
- ダンボールをお手軽にゴミに出すやつ
- Kyash
- VISAカードとして使えるウォレットアプリ。手軽に送金が行えてユーザー体験が良いです。ユーザーが増えてくれると嬉しいです。
来年の目標の話をしましょう。
すでに上のほうでだいぶ書いてしまっていますが、まずは金メダルがほしいですね。修論をサクッと片付けてコミットしていきたいです。長期的な視野で行くと、キャリアについての考え方を固めていきたいです。自分の好みはユーザーの顔が想像できる所で施策を考えたり分析をしたりするところにあるのですが、それがどういう仕事になり、どういう場所で生きていくのかについて考えていきたいです。
4月から生活が大きく変わるので、早いうちに順応したいものです。いろいろな兼ね合いもあって修論時期と引っ越し先を探す時期と諸々がかぶってなかなか大変になりそうです。
いつもの通り、Amazon欲しいものリストがこちらです。新生活を控えた3月ごろになると生々しいリストになっているかと思いますが、今はかわいいもんです。
ついでにKyashのバーコードがこちらです。
手軽に投銭できるので、ぜひ僕で試してみてください。
それではみなさま、2018年は大変お世話になりました。2019年もどうぞよろしくお願いいたします。
間に合った!
コピペで使える。Kaggleでの実験を効率化する小技まとめ
この記事はKaggle Advent Calendar 2018の20日目の記事です。当初の予定ではPLAsTiCCコンペの振り返りをするはずだったのですが、時空の狭間に吸い込まれた結果0サブミットでフィニッシュしてしまいました。何ででしょうね。 そこで、代わりにKaggleで使える便利なスニペットまとめを書くことにします。
ちなみにもうひとネタあったのでいつか書きたいですが、修論があるのでいったん見送り……
- LINEに通知を送る
- 処理にかかる時間を計測する
- LightGBMの学習結果をログに出す
- Google Spreadsheetに結果を記録する
- Notebook上でライブラリを毎回再読込する
- DataFrameのメモリを節約する
- まとめ
LINEに通知を送る
「思考は止めてもサーバーは止めるな」とはkaggler-jaの管理者であるtkmさんの名言です。サーバーを止めないためには正常・異常問わず計算終了時に通知を送ることが重要です。
import requests def send_line_notification(message): line_token = 'YOUR_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)
- https://notify-bot.line.me/my/ からパーソナルアクセストークンを発行する
- 発行したアクセストークンを
YOUR_ACCESS_TOKEN
に入れる
これでLINE通知を送ることができます。アクセストークンはコンペが終わったら無効化すれば、GitHubにコードをそのままpushしても大丈夫です。
副作用として、計算が終了したことがわかってしまうというものがあります。
続きを読む