本記事はZOZO Advent Calendar 2025 シリーズ 8 の 19 日目の記事です。
はじめに
はじめまして、株式会社ZOZOの新卒一年目機械学習エンジニアの小倉です、普段は推薦チームで業務を行っています。
先日Kaggleで行われた「MABe Challenge」にチームで参加し、1,412チーム中2位となり、金メダルを獲得しました。
また、今回の結果によってKaggle Competitions Masterに昇格しました。
チームを組んでくださったtentenさんありがとうございました!
本記事では、「MABe Challenge」の振り返りを行います。
コンペ説明
概要
以下に簡潔にまとめましたが、詳細を知りたい場合はKaggle MABe Overviewページ参照のこと
このコンペは、マウスが複数匹で生活する中で行う、「社会的な行動」と「個別の行動」を、自動で特定することが目的です。
従来、動物の行動分析は人間が長時間ビデオを見て記録していましたが、これを自動化し、神経科学や生物学の研究を加速させることを目指しています。
データセット
以下に簡潔にまとめましたが、詳細を知りたい場合はKaggle MABe Dataページ参照のこと
このデータセットは、座標データ」「メタデータ」「行動ラベル」の3つで構成されています。
-
トラッキングデータ(入力値)
動画そのものではなく、マウスの体の各部位ごとのトラッキングポイント(x, y) 座標の時系列データ。トラッキングポイントは、鼻、耳、腰、尾の付け根など(※ただし、ラボによって追跡している部位の数や種類は異なる) -
メタデータ
実験環境や対象個体に関する属性情報。
撮影されたラボID、1秒あたりのフレーム数(fps)、1cmあたりのピクセル数、ケージの形やサイズ、マウスの系統、性別、年齢、色、個体識別ID、候補action label、 等 -
アノテーションデータ(正解ラベル)
専門家が判定した行動の記録。「どのマウスが(Agent)」「どのマウス対して(Target)」「何の行動を(Action)」「いつから(Start)」「いつまで(Stop)」したか。
評価指標
本コンペティションでは、F値(F-Score)の変種を指標として使用。
- F値は、各ラボおよび各ビデオごとに平均化
- スコアの対象となるのは、そのビデオで実際にアノテーションが行われた特定の行動と特定のマウスのみ
解法
概要
- ソロ行動とペア行動を分けて学習・予測
- LossはBinary Cross Entropy
- 予測はラボ・actionごとに最適化されたthresholdを使用
データの前処理
- すべてのトラッキングデータは30 FPSに変換
- 機能: 線形補間
- ラベル: 最近傍補間
- 距離/速度/加速度は、事前に計算された統計を使用して標準化
- 欠損値は線形補間
- 欠落している身体部位の特徴は、同じフレーム内の既存の身体部位の特徴の平均に置き換え
- AdaptableSnailの25 FPSトラッキングデータの処理
参考:https://www.kaggle.com/competitions/MABe-mouse-behavior-detection/discussion/612531#3305943- 問題:
- ラベルは30 FPSで提供
- マウスIDの交換が発生
- 修正点:
- マウスIDは追跡可視化ビデオを目視し、手動で修正
- ラベルのフレームレートはそれに応じて調整
- 問題:
特徴量
- Solo(単体)とPair(ペア)のactionごとでモデルを分離したので、それぞれに適した特徴量(速度、加速度、部位間距離)を作成
- メタ特徴量:性別やラボIDを埋め込み層(Embedding)に通してモデルに入力
- mouseの性別
- フレームレート
- ラボID
- 候補action label
- ソロ
- BodyParts間の距離
- BodyPartsごとの速度
- BodyPartsごとの加速度
- ペア
- マウス間の身体部位間の距離
- 速度
- 加速度
モデルアーキテクチャ
- CNN + RNN / Transformer
Input → Multi-scale Conv (k =3,5,7,9) → Conv Fusion → Bi-GRU or Transformer → Linear → Output - SqueezeFormer
Input → SqueezeFormer → Output
トレーニング
- 5-fold stratified cross-validation
- テストセットに出現するラボのデータのみを使用して、フォールド(検証用グループ)を作成
- 各フォールド間でラボIDの分布が一定になるよう、層化(Stratified)を行う
- LossはBCE
- EMA (decay = 0.999)
- Cosine LR schedule
- また、各epochにおいて、ラボとアクションごとに最適な閾値を用いてスコア計算し、Early Stopping
公開データセットである「CalMS21」と「CRIM13」由来のラボデータは、常に(全ての)訓練セットに含める。
- Data Augmentation
- Gaussian noise
- Time stretching
- Frame shift (shift features only; labels unchanged)
- Left/right body-part flipping
- Mixup
推論と後処理
- Sliding-windowで推論(stride = 128)
- Sliding-windowの両端の32フレームは破棄し、残りの予測結果で平均
- TTA
後処理
-
閾値設定
- 最適な閾値は、各フォールドおよび各ラボ × アクションのペアごとに個別に計算され、最終的な閾値はフォールド固有のしきい値を平均化したもの
- 各フレームにおいて、閾値を超えるアクションの中から、最もスコアの高いアクションを選択(ここの処理は、他のチームではより賢い方法が紹介されていました。)
-
AdaptableSnail 25 FPS調整
- 予測結果のstart_frameとstop_frameに
30 / 25倍する - 追跡データにマウスIDのスワップが存在する場合、この調整は意味がなかった
- 非公開データセットには、マウスIDの交換のないデータが含まれていたようで
- その結果、プライベートスコアが+0.009向上
- 予測結果のstart_frameとstop_frameに
おわりに
Kaggle MABe Challenge の参加記録を書きました。
今回のコンペで念願の金メダルを獲得し、Kaggle Competitions Masterに昇格しましたが、つよつよなチームメンバーのおかげで得られた結果でした。
今回の結果を糧にさらなる技術の研鑽に励んでいきたいと思います。

