{
  "id": 603649,
  "title": "39th place solution: Ensemble Approach Using GBDT",
  "url": "/competitions/cmi-detect-behavior-with-sensor-data/discussion/603649",
  "author_name": "pay",
  "post_date": "2025-09-03T12:35:00.586000",
  "votes": 7,
  "comment_count": 0,
  "views": 0,
  "content": "<p>First of all, I would like to thank the competition organizers and everyone involved. My solution is not as strong as those of the top competitors, but since there seem to be relatively few examples that incorporated GBDT into the ensemble, I’d like to briefly share my approach.</p>\n<hr>\n<h1>Overview</h1>\n<ul>\n<li>Built two types of models: IMU-only, All-sensor<ul>\n<li>Depending on the availability of the TOF sensor, a different model was applied.</li></ul></li>\n<li>The ensemble consisted of GBDT (LightGBM, XGBoost) and 1D-CNN + LSTM.</li>\n<li>Final predictions were obtained by taking a weighted sum of probabilities followed by post-processing.</li>\n<li>In post-processing, I selected the class with the maximum probability among either the target group or the non-target group, depending on which group had the higher total probability.</li>\n<li>None of the models performed particularly well individually, but after ensembling, the CV reached IMU: 0.821, All: 0.881.</li>\n<li>No correction was made for sensor differences due to handedness.</li>\n<li>Private: 0.844, Public: 0.863</li>\n</ul>\n<h1>GBDT</h1>\n<ul>\n<li>Created new channels directly from raw data.</li>\n<li>Computed features with a window size of 15 and a stride of 5.</li>\n<li>Aggregated window features over the entire sequence as well as the latter half.</li>\n<li>Additional features included handedness and signal length.</li>\n<li>From here, I removed unnecessary variables and tuned the hyperparameters.<ul>\n<li>For example, magnitude-related features are always non-negative, so calculating zero crossings is meaningless and did not contribute to prediction for any class.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F8d4590897e45f387014c432f2ab076b4%2F2025-09-03%2021.09.45.png?generation=1756901411239564&amp;alt=media\" alt=\"\"></li></ul></li>\n</ul>\n<h1>1D-CNN + LSTM</h1>\n<ul>\n<li>Used a dual-head structure: one for IMU-only and one for all sensors, trained with multi-task learning.</li>\n<li>Data augmentation included:<ul>\n<li>MixUp</li>\n<li>Time warping</li>\n<li>Scaling</li>\n<li>Noise injection</li></ul></li>\n<li>To account for missing TOF signals, randomly masked TOF and THM during each mini-batch training.</li>\n<li>Loss Function: Cross Entropy Loss<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F0bfd815d0d1e879a39f4faedf3ae0043%2F2025-09-03%2021.11.26.png?generation=1756901526633273&amp;alt=media\" alt=\"\"></li>\n</ul>\n<h1>Post-processing</h1>\n<ul>\n<li>Summed the predicted probabilities of the 18 classes for the target group.</li>\n<li>If this sum &gt; 0.5, the predicted label was the target class with the highest probability.</li>\n<li>Otherwise, the predicted label was the non-target class with the highest probability.</li>\n<li>This post-processing improved the score by about 0.001.</li>\n</ul>\n<h1>Cross-validation</h1>\n<ul>\n<li>Used grouped stratified 5-fold CV, ensuring background information was distributed as evenly as possible.</li>\n<li>Although single models were not very strong, the combination of ensemble + post-processing resulted in CV: IMU 0.821, All 0.881.<br>\nOnly IMU<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F113daa24c7f03bc1d915d44190a3ccfa%2F2025-09-03%2021.15.35.png?generation=1756901746706512&amp;alt=media\" alt=\"\"></li>\n</ul>\n<p>All<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F06d3c37faf00a431c0e1cc034a0109ed%2F2025-09-03%2021.16.16.png?generation=1756901790808744&amp;alt=media\" alt=\"\"></p>\n<p>Thank you for your reading.</p>",
  "messages": [
    {
      "id": 3281006,
      "postDate": "2025-09-03T12:35:00.587Z",
      "content": "<p>First of all, I would like to thank the competition organizers and everyone involved. My solution is not as strong as those of the top competitors, but since there seem to be relatively few examples that incorporated GBDT into the ensemble, I’d like to briefly share my approach.</p>\n<hr>\n<h1>Overview</h1>\n<ul>\n<li>Built two types of models: IMU-only, All-sensor<ul>\n<li>Depending on the availability of the TOF sensor, a different model was applied.</li></ul></li>\n<li>The ensemble consisted of GBDT (LightGBM, XGBoost) and 1D-CNN + LSTM.</li>\n<li>Final predictions were obtained by taking a weighted sum of probabilities followed by post-processing.</li>\n<li>In post-processing, I selected the class with the maximum probability among either the target group or the non-target group, depending on which group had the higher total probability.</li>\n<li>None of the models performed particularly well individually, but after ensembling, the CV reached IMU: 0.821, All: 0.881.</li>\n<li>No correction was made for sensor differences due to handedness.</li>\n<li>Private: 0.844, Public: 0.863</li>\n</ul>\n<h1>GBDT</h1>\n<ul>\n<li>Created new channels directly from raw data.</li>\n<li>Computed features with a window size of 15 and a stride of 5.</li>\n<li>Aggregated window features over the entire sequence as well as the latter half.</li>\n<li>Additional features included handedness and signal length.</li>\n<li>From here, I removed unnecessary variables and tuned the hyperparameters.<ul>\n<li>For example, magnitude-related features are always non-negative, so calculating zero crossings is meaningless and did not contribute to prediction for any class.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F8d4590897e45f387014c432f2ab076b4%2F2025-09-03%2021.09.45.png?generation=1756901411239564&amp;alt=media\" alt=\"\"></li></ul></li>\n</ul>\n<h1>1D-CNN + LSTM</h1>\n<ul>\n<li>Used a dual-head structure: one for IMU-only and one for all sensors, trained with multi-task learning.</li>\n<li>Data augmentation included:<ul>\n<li>MixUp</li>\n<li>Time warping</li>\n<li>Scaling</li>\n<li>Noise injection</li></ul></li>\n<li>To account for missing TOF signals, randomly masked TOF and THM during each mini-batch training.</li>\n<li>Loss Function: Cross Entropy Loss<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F0bfd815d0d1e879a39f4faedf3ae0043%2F2025-09-03%2021.11.26.png?generation=1756901526633273&amp;alt=media\" alt=\"\"></li>\n</ul>\n<h1>Post-processing</h1>\n<ul>\n<li>Summed the predicted probabilities of the 18 classes for the target group.</li>\n<li>If this sum &gt; 0.5, the predicted label was the target class with the highest probability.</li>\n<li>Otherwise, the predicted label was the non-target class with the highest probability.</li>\n<li>This post-processing improved the score by about 0.001.</li>\n</ul>\n<h1>Cross-validation</h1>\n<ul>\n<li>Used grouped stratified 5-fold CV, ensuring background information was distributed as evenly as possible.</li>\n<li>Although single models were not very strong, the combination of ensemble + post-processing resulted in CV: IMU 0.821, All 0.881.<br>\nOnly IMU<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F113daa24c7f03bc1d915d44190a3ccfa%2F2025-09-03%2021.15.35.png?generation=1756901746706512&amp;alt=media\" alt=\"\"></li>\n</ul>\n<p>All<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F06d3c37faf00a431c0e1cc034a0109ed%2F2025-09-03%2021.16.16.png?generation=1756901790808744&amp;alt=media\" alt=\"\"></p>\n<p>Thank you for your reading.</p>",
      "rawMarkdown": "First of all, I would like to thank the competition organizers and everyone involved. My solution is not as strong as those of the top competitors, but since there seem to be relatively few examples that incorporated GBDT into the ensemble, I’d like to briefly share my approach.\n\n---\n# Overview\n\n- Built two types of models: IMU-only, All-sensor\n - Depending on the availability of the TOF sensor, a different model was applied.\n- The ensemble consisted of GBDT (LightGBM, XGBoost) and 1D-CNN + LSTM.\n- Final predictions were obtained by taking a weighted sum of probabilities followed by post-processing.\n- In post-processing, I selected the class with the maximum probability among either the target group or the non-target group, depending on which group had the higher total probability.\n- None of the models performed particularly well individually, but after ensembling, the CV reached IMU: 0.821, All: 0.881.\n- No correction was made for sensor differences due to handedness.\n- Private: 0.844, Public: 0.863\n\n# GBDT\n- Created new channels directly from raw data.\n- Computed features with a window size of 15 and a stride of 5.\n- Aggregated window features over the entire sequence as well as the latter half.\n- Additional features included handedness and signal length.\n- From here, I removed unnecessary variables and tuned the hyperparameters.\n - For example, magnitude-related features are always non-negative, so calculating zero crossings is meaningless and did not contribute to prediction for any class.\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F8d4590897e45f387014c432f2ab076b4%2F2025-09-03%2021.09.45.png?generation=1756901411239564&alt=media)\n\n# 1D-CNN + LSTM\n- Used a dual-head structure: one for IMU-only and one for all sensors, trained with multi-task learning.\n- Data augmentation included:\n - MixUp\n - Time warping\n - Scaling\n - Noise injection\n- To account for missing TOF signals, randomly masked TOF and THM during each mini-batch training.\n- Loss Function: Cross Entropy Loss\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F0bfd815d0d1e879a39f4faedf3ae0043%2F2025-09-03%2021.11.26.png?generation=1756901526633273&alt=media)\n\n# Post-processing\n- Summed the predicted probabilities of the 18 classes for the target group.\n- If this sum > 0.5, the predicted label was the target class with the highest probability.\n- Otherwise, the predicted label was the non-target class with the highest probability.\n- This post-processing improved the score by about 0.001.\n\n# Cross-validation\n- Used grouped stratified 5-fold CV, ensuring background information was distributed as evenly as possible.\n- Although single models were not very strong, the combination of ensemble + post-processing resulted in CV: IMU 0.821, All 0.881.\nOnly IMU\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F113daa24c7f03bc1d915d44190a3ccfa%2F2025-09-03%2021.15.35.png?generation=1756901746706512&alt=media)\n\nAll\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F06d3c37faf00a431c0e1cc034a0109ed%2F2025-09-03%2021.16.16.png?generation=1756901790808744&alt=media)\n\nThank you for your reading.",
      "votes": 7
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "3281006": "First of all, I would like to thank the competition organizers and everyone involved. My solution is not as strong as those of the top competitors, but since there seem to be relatively few examples that incorporated GBDT into the ensemble, I’d like to briefly share my approach.\n\n---\n# Overview\n\n- Built two types of models: IMU-only, All-sensor\n - Depending on the availability of the TOF sensor, a different model was applied.\n- The ensemble consisted of GBDT (LightGBM, XGBoost) and 1D-CNN + LSTM.\n- Final predictions were obtained by taking a weighted sum of probabilities followed by post-processing.\n- In post-processing, I selected the class with the maximum probability among either the target group or the non-target group, depending on which group had the higher total probability.\n- None of the models performed particularly well individually, but after ensembling, the CV reached IMU: 0.821, All: 0.881.\n- No correction was made for sensor differences due to handedness.\n- Private: 0.844, Public: 0.863\n\n# GBDT\n- Created new channels directly from raw data.\n- Computed features with a window size of 15 and a stride of 5.\n- Aggregated window features over the entire sequence as well as the latter half.\n- Additional features included handedness and signal length.\n- From here, I removed unnecessary variables and tuned the hyperparameters.\n - For example, magnitude-related features are always non-negative, so calculating zero crossings is meaningless and did not contribute to prediction for any class.\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F8d4590897e45f387014c432f2ab076b4%2F2025-09-03%2021.09.45.png?generation=1756901411239564&alt=media)\n\n# 1D-CNN + LSTM\n- Used a dual-head structure: one for IMU-only and one for all sensors, trained with multi-task learning.\n- Data augmentation included:\n - MixUp\n - Time warping\n - Scaling\n - Noise injection\n- To account for missing TOF signals, randomly masked TOF and THM during each mini-batch training.\n- Loss Function: Cross Entropy Loss\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F0bfd815d0d1e879a39f4faedf3ae0043%2F2025-09-03%2021.11.26.png?generation=1756901526633273&alt=media)\n\n# Post-processing\n- Summed the predicted probabilities of the 18 classes for the target group.\n- If this sum > 0.5, the predicted label was the target class with the highest probability.\n- Otherwise, the predicted label was the non-target class with the highest probability.\n- This post-processing improved the score by about 0.001.\n\n# Cross-validation\n- Used grouped stratified 5-fold CV, ensuring background information was distributed as evenly as possible.\n- Although single models were not very strong, the combination of ensemble + post-processing resulted in CV: IMU 0.821, All 0.881.\nOnly IMU\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F113daa24c7f03bc1d915d44190a3ccfa%2F2025-09-03%2021.15.35.png?generation=1756901746706512&alt=media)\n\nAll\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F10857393%2F06d3c37faf00a431c0e1cc034a0109ed%2F2025-09-03%2021.16.16.png?generation=1756901790808744&alt=media)\n\nThank you for your reading."
  },
  "complete": true,
  "source": "existing_discussion",
  "competition_id": 102335,
  "competition_slug": "cmi-detect-behavior-with-sensor-data",
  "team_id": 13934749,
  "solution_url": "/competitions/cmi-detect-behavior-with-sensor-data/writeups/39th-place-solution"
}