2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
能見氏(以下、能見):次はコード構成とデバッグの話です。Time-seriesコンペに関して、Kaggle環境でコードを書き切るのは、コード量が多くなるのでけっこうつらくなりがちです。そのため、手元で書いてGitで管理することをおすすめします。ただ、Time-seriesコンペでは信頼性の高い、わりと複雑なコードを書かなければいけないので、デバッグやテストの管理がしやすいように書きたいというのもあるかなと思っています。
自分がやりやすい方法で書くのが一番かと思いますが、私の場合は、ロジックを全部スクリプトに移動させて、Notebookはそれを呼び出すだけというかたちにする方向に落ち着きました。
分割したスクリプトをどうやってKaggle環境で実行するかは、(スライドを示して)下のリンク(※)をご覧ください。
※https://www.m3tech.blog/entry/2021/01/13/180000
※https://zenn.dev/hattan0523/articles/c55dfd51bb81e5
また、Time-seriesコンペでは専用のモジュールが必要なので、手元で書いても動かせないという大きな問題がありますが、これを解決するAPI Emulatorという良い方法があります。
Time-series APIと同じインターフェイスで、train.csvのデータをちょっとずつ返すコードを手元で用意して、手元ではそれを使って実行する、要はモックですね。これは、サブを消費せずに手元でデバッグできるのですごく有用で、個人的には必ず使ったほうがよいと言い切れるぐらい良いものだと思っています。
もし手元で実行する場合は、環境を揃えることを忘れずにやっておきましょう。
あと、ベンチマークも大事です。高速化は、もちろん個々のテクニックも大事ですが、再現性のある時間測定環境を作ることが、私は一番大事だと思っています。
Notebookから実装の本体をスクリプトに移動しておくと、本番のNotebookは汚さずに本番で呼び出すコードをベンチマークするようなスクリプトを書けるので、そういう方法を採ると個人的にはけっこうよかったです。
最後にエラーハンドリングの話です。
これは参加したことのある方はよくわかると思いますが、このコンペでサブ時にエラーが出ても、エラー要因はほとんどわかりません。Kaggle環境上で問題を切り分けるのはかなりつらいので、そもそもエラーが出ないように書きたいという動機があります。
それからコードコンペには2-stage制という恐ろしい制度があって、締切後にホストがデータを差し替えて再実行した時にエラーが出ると失格になってしまいます。Time-seriesコンペはデータの性質との兼ね合いもあって、過去4回のうち3回は2-stage制になっています。このルールではエラーが起きると取り返しがつきません。極端に言うと、どんなデータに差し替えられても絶対に死なないコードを書く必要があります。
では、Time-seriesコンペで最低限何をしたらよいのかというと、(スライドを示して)推論のforループの階層で例外をとにかく全部キャッチしてしまいましょう。絶対このpredictだけは呼んでしまう、といった書き方にします。こうすると、基本的に自分が書いた中のコードでどんな事故が起きても、ダメージが推論1回分に抑えられるので、やるかやらないかでいえば、絶対やったほうがよい処理です。
ただ、コンペ初期は逆に問題の発見が遅れるという問題もあります。個人的にはコンペ初期はやらずに、終盤に忘れずに入れるというのを心懸けておくとよいかなと思っています。
それ以外にも例外のキャッチはなるべく細かく入れておくと、当然被害の範囲が小さく抑えられます。
あと、さっき話したAPI Emulatorの応用で、エミュレータが返すデータをわざと壊してみてもよいでしょう。わざと一部のカラムを欠損させたデータにして、自分のコードがきちんと動くか確認するテストをするのも個人的にはおすすめします。
例外処理のコード自体にバグがあって、例外をキャッチする先でさらに例外が出てしまうような予想外の問題は得てして起きるので、そういう問題をあぶり出すのによいかなと思います。
制限時間オーバーは例外をいくらキャッチしてもどうしようもないので、この見積もりもきちんとやっておきましょう。実際にサブミットした時間を計ったり、エミュレータで実測したりと、いろいろな方法で推定して突き合わせてみるとよいんじゃないかなと思います。
あとは、これはテクニックというよりは心構えの話なのですが、私が大事にしたほうがよいと思っている点を1点共有しておきます。それは「暗黙の仮定」を意識しましょうという点です。
2-stage制の場合、Kaggle側から2nd stageでどういうデータが来るかはあまり詳しい仕様を与えられません。「それってどうなの?」みたいに思わなくもないですが、そういう条件の下でロバストなコードを書こうとした時に、「自分のコードはホストが言っていないことを暗黙に仮定しているんじゃないか?」という自問自答してみることは、大事なのではないかと思います。
ここまでいろいろ言ってしまいましたが、Time-seriesコンペで私はこういうかたちで書いているというテンプレートを紹介します。基本的に見たままなのであんまり解説するところもないのですが、この一番上で公式のモジュールとエミュレータを環境によって呼び分けて、どちらでも動くようにしています。
(スライドを示して)1個、ちょっと見ただけではわかりづらいところはこのへんですね。推論に渡すデータフレームに予測値を代入しますが、この代入を1ヶ所にまとめています。
例えばアンサンブルする時は、このコードの中で何回も代入して差し込んで、最後にこのモデル数で割るみたいなことをつい書きたくなりますが、そうすると途中で例外が発生した時に、割る前の半端な値が代入された状態でpredictしちゃいます。
こういう「例外が起きた時に整合性のある状態を保てるか?」みたいな考え方は「例外安全性」と呼ばれています。C++などを書いたことがある人にはよく知られていると思いますが、あまりKaggleでは聞いたことがないので、ちょっとここでお話ししました。このへんを考えておけるようになると、一段階信頼性の高いコードが書けるようになるんじゃないかなと思っています。
今日はTime-seriesコンペで大変なポイントと、それに対する4つの処方箋を解説してきました。
最後に、今日の話を聞いて「やはりTime-seriesコンペって面倒くさいな」と思った方もけっこういるのではないかと思います。しかし、個人的には現状メダルが取りやすい仕様のコンペだと思いますし、大変さを乗り切ると、実装力は間違いなく付くと思っています。
(スライドを示して)今日は、このへんのバッチとストリームの両対応が大変とか、状態管理がどうとか、今日はお話ししませんでしたが、アーティファクトの依存関係が大変とか、Time-seriesコンペでだいたい苦しむようなポイントは、現実のデータ分析基盤でもリアルな課題になっているのではないでしょうか。
今後もTime-seriesコンペはたぶん継続的に出てくると思うので、みなさんもぜひ参加してほしいなと思います。ということで、今日の発表を終わりたいと思います。ありがとうございました。
司会者:ありがとうございました。いや、メチャクチャ知見が詰まっていてすごいなと感じました。
ちなみに、Riiidでもtraining dataがすごい量だったと思いますが、Train用の特徴量を作ったりするのも、ストリーム処理をしたのでしょうか?
能見:そうですね。Riiidコンペのtrain dataは2億ぐらいでしたっけ?1億でしたっけ?まぁまぁありましたよね。でもGCPのPreemptible Instanceで、64コアぐらいのやつでフワッと回したら10〜15分ぐらいで計算が終わりました。即座ではありませんが、私のKaggleのやり方的には、ぜんぜん問題がないぐらいのスピード感でした。
司会者:なるほど。すばらしい。ちなみに、MLBコンペの話で、例えば2日目の推論をしようとした時に、1日目の特徴量は使いたい場合、NFLでは使えたと思うのですが、特徴量を作る・作らないみたいな2パターンがあると思っていればよいんでしょうか?
能見:特徴量というか、目的変数ですかね。
司会者:あ、そうですね。目的変数か。
能見:はい。Riiidでは1ステップ前の目的変数を取得できたので、それでラグ特徴量が作れたのですが、MLBの場合は、それが取得できないかたちになっていたので、テスト期間中に対するターゲットの値がわかりませんでした。
Time-seriesコンペも毎回微妙に仕様が変わっていたり、テストデータの期間の開き方もたぶん毎回微妙に違ったりすると思うので、そのへんはよく注意したほうがよいと思います。今回のMLBでは、あまり最初にホストからそのへんの情報がはっきり与えられていなくて、ほかの日本人Kagglerの方がよい感じに質問してくれて答えが出てきたところがあったので、非常に助かりました。わからなかったら質問してみるのも大事だと思います。
司会者:なるほど。ありがとうございました。
能見:ありがとうございました。
関連タグ:
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略