Kaggle睡眠コンペで銀メダル取りました!

Tamae Itabashi
JDSC Tech Blog
Published in
Jan 5, 2024

はじめまして!JDSCでコンサルタントとして働いている板橋と申します!今日はこちらのKaggleコンペに出て銀メダルを獲ったことを書いていこうと思います。(初めてのTechBlogです。お手柔らかにお願いいたします…)

Biz人材だけどKaggleに出てみた

JDSCは、データサイエンス、エンジニアリング、ビジネスの三位一体の組織であることを強みにしています。そして、組織としてだけではなく、個人としても三位一体を目指していこう!ということを掲げ、社員1人1人が自己研鑽を続けている会社でもあります(本当にみんな呼吸するように勉強するからすごい)。

私はコンサルタントとして働いていますが、データサイエンスの領域も勉強したいと考えており(まだ勉強歴1年半の初心者ですが…)、今回社内のデータサイエンティストとチームを組んでKaggleに挑戦するにいたりました。ビジネス人材だけどこれからデータサイエンスを勉強していきたい方への学びに少しでも貢献できればと思い、この記事を書きます!

やったことをまとめます

<参加したコンペの概要>
「Child Mind Institute — Detect Sleep States」というコンペに参加しました。タスクは被験者の手首に装着した加速度センサーのデータから就寝時(onset)と起床時(wakeup)の時刻を予測するというものです。1~3カ月の期間、277人のユーザーについて5秒間隔(5秒で1ステップ)でデータが取られていたので、1人あたりのデータが非常に長くデータ量も多いコンペでした。一方でデータはanglez、 enmoの2種類のテーブルデータという、非常にシンプルで分かりやすいコンペでした。

<アプローチ>
大きく①awake(起きている状態)/sleep(寝ている状態)の2値分類をし、onset/wakeupの時間を判定するstateアプローチ、②onset/wakeup確率を直接求めにいくeventアプローチ、の2つのアプローチを試みました。

初めは①のアプローチのみで進めようと考えて実施しました。しかし2値分類の精度自体はかなり高いものが出たものの、CVが満足できる数値に至らず、このアプローチだけでは不十分だということに気が付きました。state確率の変化の最大値が必ずしもevent確率の最大点となるわけではないため、これによる差が大きく出てしまうことが原因と推察し(最終的にはstateアプローチも捨てきれず、同様なモデルで予測しにいきましたが)、メインは②eventアプローチをとることとしました。

また、①のアプローチにちょうど行き詰まっていたタイミングでtuboさんのnotebookが公開され停滞状況を打開することができました。event detect系のタスクは経験が少なかったため、非常に勉強になりました。

<処理内容_前処理>
データ数が非常に多かったので、主な前処理はノイズデータの除去をしました。また、event detectの場合onset/wakeupの1stepのみを1とするとデータの偏りが非常に大きいため、event stepで確率1となり、そこから離れるほど0に近づくようなラベルデータを作りました。このときの減衰度合い(sigma)が非常に重要で、ここをモデル構築と合わせて検証しつつ調整したのがスコアにかなり効きました。

<処理内容_モデル>
主には、GRUベースのモデルと2DUnetのアンサンブルでした。それぞれについて先述のsigmaをかえて複数パターンでモデルを構築しました。

・model① 良さげモデル
- offsetがおよそ60stepのモデル
- LB:0.73〜で単体モデルでは一番精度いい

・model② うっすら当たりやすいがぼやけてるモデル
- offsetがおよそ120stepのモデル
- LB:0.73前後で悪くない

・model③ 尖っているが、外れやすいモデル
- offsetがおよそ20stepのモデル(だいぶ狭い範囲でピンポイントに当てにいく)
- LB:0.72〜と少し低め

<処理内容_後処理>
peak detectはscipi.find_peaksで実施し、Optunaでハイパラメーターチューニングをしました。が、いろいろなパターンで何度やっても、なるべく多くpeakをとってくるものがscoreが最大となりました。一方で今回のコンペでは、実はsubmitデータの行数が多すぎる(提出するpeak数が多すぎる)とscoring errorになる、というtipsに早めに気づいていたため、scoring errorにならない範囲で広く拾ってこれるように調整しました。

そしてモデルのアンサンブルも色々試しました!Discussionでは、「Ensemble is crucial in this competition」と色々な人が書いていたので、コンペ終盤はここに一番時間をかけました。単純に足すのではなく各モデルの予測結果に重み付けしてみたり、各モデルに対して移動平均をとってなめらかにしてみたり、、色々やったのですが正直あまり効果は出ずでした。結果、一応出すだけ出していたstate確率から、あまりにおかしい点だけ除去する後処理のみ採用しました。

今回の学びとこれからも学びを継続するために

前処理がめちゃくちゃ大変だということがまず一番の学びです。以前SIGNATEのビギナーコンペに出たことがあったのですが、その際のデータとは比べ物にならないほどデータ量が多く、全てのデータを与えられた形のまま扱っていたのではメモリに乗らない、みたいなことが多かったことが印象的でした。あとは、サーバーのスペックって大事なのだということを痛感しました。

そしてデータサイエンティストって本当にすごい…今回は方針を立ててもらったり、タスクを切り出してもらったりして取り組んだのですが、1人ではとても挑めなかった(まだ全然無理)と振り返って噛みしめており、勉強の道のりは長いなぁと思いました。

最後に

JDSCにはKaggle部という部活もあり勉強できる環境はびっくりするくらいたくさんあります!(Kaggle部始動のタイミングで忙殺されており今回は部外活動をしてしまった)なんでこんな教えてくれるの?って不安になるくらい応援してくれる文化があるので、これからもこういうコンペに継続してチャレンジしていこうと思います!また、今回はモデル構築の部分は私はノータッチで、前処理と後処理の部分を担当しました。今後もこうやってチームを組んで出ることもあると思うのですが、自分が担当できる領域をじわじわ広げていければと思っています。

そして、一緒に取り組んでくれたデータサイエンティストの方に感謝を!私が業務後ヘロヘロになっている中、同じくヘロヘロなはずなのに「よーし!やっとKaggleできる!」とウキウキしながら取り組んでいた姿が印象的です。新しいnotebookが公開されると「これは思いつかなかった!勉強になるぅ!」とこれまたウキウキしていて、こうやって新しいことを吸収するのが楽しくて楽しくてしょうがないみたいな人が将来化け物になるのだと確信しました(今も十分化け物ですが)

最後まで読んでいただいてありがとうございます。また記事をかけるように日々精進します!

--

--