{
  "id": 609553,
  "title": "48th Place Solution (Silver Medal)",
  "url": "/competitions/ariel-data-challenge-2025/discussion/609553",
  "author_name": "Ibrahim Habib",
  "post_date": "2025-09-27T19:43:13.929000",
  "votes": 2,
  "comment_count": 0,
  "views": 0,
  "content": "<p>First of all, I would like to thank all the organizers of this great contest for all their work and effort.<br>\nI would also like to thank all participants who shared their ideas and code, especially the gold medal winners of last year's contest.</p>\n<h1>The 48th Place Solution</h1>\n<h2>Data Calibration</h2>\n<p>I didn't do anything special here. I followed the standard calibration notebook and changed the binning value to 4 for AIRS and 48 for FGS.</p>\n<h2>Transit Detection</h2>\n<p>The technique here is copied from <a href=\"https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/c-number-daiwakun-1st-place-solution\" target=\"_blank\">last year's 1st place solution</a>. The curve is smoothed, then, using the points of least and largest derivative value, estimates of the drop transit and rise times are found. These are only initial estimates that will later be refined.</p>\n<p>To get the exact times where the transit drop begins and ends, we cut the signal to include only values from the signal's beginning until the initial estimate + a constant value.  Then we find 4 values, <em>a</em>, <em>b</em>, <em>t1</em>,  and <em>t2</em>, such that the RMSE between the signal and the following function is minimized.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F20416828%2F703a091aa92f7e1ca5d02d9f2b36bfa7%2Flatex.png?generation=1759002042022823&amp;alt=media\" alt=\"\"></p>\n<p>where <em>t1 &lt; t2</em> and <em>a &gt; b</em>. The desired values are <em>t1</em> and <em>t2</em>. Those are the exact times the transit drop phase begins and ends, respectively. The exact times for the transit rise start and end are calculated similarly and are called <em>t3</em> and <em>t4</em>.</p>\n<h2>Feature Extraction</h2>\n<p>This part was hugely inspired by last year's <a href=\"https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/through-the-thorns-to-the-star-6th-place-solution\" target=\"_blank\">6th place solution</a> and <a href=\"https://www.kaggle.com/code/vitalykudelya/neurips-non-ml-transit-curve-fitting\" target=\"_blank\">Vitaly Kudelya's Notebook</a>. For each wavelength, 7 transit depth values were extracted. The values were extracted in the following manner.</p>\n<p>First, for each planet, divide wavelengths into separate groups where neighboring wavelengths go to the same group. Wavelengths in the same group are averaged together (cross-wavelengths) to create a white curve per group.</p>\n<p>Then, the transit phases are detected in the manner discussed earlier.</p>\n<p>Next, we calculate the value <em>s</em> that minimizes the MAE of <code>np.concatenate([signal[:t1], signal[t2:t3]  * (s + 1.0), signal[t4:]])</code>. Stated more informally, we find the value such that when multiplied by the in-transit section it nearly equals the out-of-transit section, and we subtract 1 from that number. These values are extremely close to the target value; thus, they are great features for the model.</p>\n<p>Finally, we give each wavelength in the group that s-value.</p>\n<p>This is made 7 times, each time using a different number of groups. The used values are 1, 2, 4, 8, 16, 32, and 64.</p>\n<p>Now we have 7 values for each of the 283 wavelengths.</p>\n<h2>Spectrum Prediction</h2>\n<p>We have features of shape (num_planets, 7, num_wavelengths). We also extract the Rs and i values of each planet, making a tensor of shape (num_planets, 2). Both tensors are passed to a neural network.</p>\n<p>Since important information can be extracted from neighboring wavelengths, the features tensor is passed through three 1D-CNN layers with increasing kernel size and ReLU between them. The last CNN has an out_channels value of 1. Its output is squeezed to form a tensor of shape (batch_size, num_wavelengths).</p>\n<p>The CNN output is concatenated on the second axis with the star information (Rs and i). The data is then passed into three ResNet blocks. The final output has shape (batch_size, num_wavelengths).</p>\n<p>The model is trained with the Adam optimizer and MSE loss for 300 epochs.</p>\n<p>The final output is the predicted spectrum.</p>\n<h2>Sigma Prediction</h2>\n<p>Predicting the sigma value proved challenging, and different methods significantly impacted the public LB score (with overconfident methods yielding a score of 0.0 on the LB). Two solutions showed great results.</p>\n<p>The first was calculating the standard deviation of the predicted spectrum for each planet. Then, the values are scaled to a new mean. The other was calculating for each planet the variance of its white curve, and also scaling it to a new mean.</p>\n<p>Performing linear regression on these two features and the mean of the predicted spectrum showed great improvement.</p>\n<h2>The Code</h2>\n<p>You can access the winning notebook <a href=\"https://www.kaggle.com/code/ibrahimhabibeg/lr-sigma-with-nn\" target=\"_blank\">here</a>. There is also a repo for this project containing the code used in the winning submission and other experiments. It also contains more information on the code and how to use it in Kaggle submissions. You can access it <a href=\"https://github.com/ibrahimhabibeg/ariel-2025\" target=\"_blank\">here</a>.</p>\n<h2>References and Acknowledgments</h2>\n<p>There are so many people whose work helped me build mine. To keep this write-up short, I wrote the references section in the GitHub repo for this project. You can find the references section <a href=\"https://github.com/ibrahimhabibeg/ariel-2025?tab=readme-ov-file#refrences\" target=\"_blank\">here</a>.</p>",
  "messages": [
    {
      "id": 3295150,
      "postDate": "2025-09-27T19:43:13.930Z",
      "content": "<p>First of all, I would like to thank all the organizers of this great contest for all their work and effort.<br>\nI would also like to thank all participants who shared their ideas and code, especially the gold medal winners of last year's contest.</p>\n<h1>The 48th Place Solution</h1>\n<h2>Data Calibration</h2>\n<p>I didn't do anything special here. I followed the standard calibration notebook and changed the binning value to 4 for AIRS and 48 for FGS.</p>\n<h2>Transit Detection</h2>\n<p>The technique here is copied from <a href=\"https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/c-number-daiwakun-1st-place-solution\" target=\"_blank\">last year's 1st place solution</a>. The curve is smoothed, then, using the points of least and largest derivative value, estimates of the drop transit and rise times are found. These are only initial estimates that will later be refined.</p>\n<p>To get the exact times where the transit drop begins and ends, we cut the signal to include only values from the signal's beginning until the initial estimate + a constant value.  Then we find 4 values, <em>a</em>, <em>b</em>, <em>t1</em>,  and <em>t2</em>, such that the RMSE between the signal and the following function is minimized.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F20416828%2F703a091aa92f7e1ca5d02d9f2b36bfa7%2Flatex.png?generation=1759002042022823&amp;alt=media\" alt=\"\"></p>\n<p>where <em>t1 &lt; t2</em> and <em>a &gt; b</em>. The desired values are <em>t1</em> and <em>t2</em>. Those are the exact times the transit drop phase begins and ends, respectively. The exact times for the transit rise start and end are calculated similarly and are called <em>t3</em> and <em>t4</em>.</p>\n<h2>Feature Extraction</h2>\n<p>This part was hugely inspired by last year's <a href=\"https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/through-the-thorns-to-the-star-6th-place-solution\" target=\"_blank\">6th place solution</a> and <a href=\"https://www.kaggle.com/code/vitalykudelya/neurips-non-ml-transit-curve-fitting\" target=\"_blank\">Vitaly Kudelya's Notebook</a>. For each wavelength, 7 transit depth values were extracted. The values were extracted in the following manner.</p>\n<p>First, for each planet, divide wavelengths into separate groups where neighboring wavelengths go to the same group. Wavelengths in the same group are averaged together (cross-wavelengths) to create a white curve per group.</p>\n<p>Then, the transit phases are detected in the manner discussed earlier.</p>\n<p>Next, we calculate the value <em>s</em> that minimizes the MAE of <code>np.concatenate([signal[:t1], signal[t2:t3]  * (s + 1.0), signal[t4:]])</code>. Stated more informally, we find the value such that when multiplied by the in-transit section it nearly equals the out-of-transit section, and we subtract 1 from that number. These values are extremely close to the target value; thus, they are great features for the model.</p>\n<p>Finally, we give each wavelength in the group that s-value.</p>\n<p>This is made 7 times, each time using a different number of groups. The used values are 1, 2, 4, 8, 16, 32, and 64.</p>\n<p>Now we have 7 values for each of the 283 wavelengths.</p>\n<h2>Spectrum Prediction</h2>\n<p>We have features of shape (num_planets, 7, num_wavelengths). We also extract the Rs and i values of each planet, making a tensor of shape (num_planets, 2). Both tensors are passed to a neural network.</p>\n<p>Since important information can be extracted from neighboring wavelengths, the features tensor is passed through three 1D-CNN layers with increasing kernel size and ReLU between them. The last CNN has an out_channels value of 1. Its output is squeezed to form a tensor of shape (batch_size, num_wavelengths).</p>\n<p>The CNN output is concatenated on the second axis with the star information (Rs and i). The data is then passed into three ResNet blocks. The final output has shape (batch_size, num_wavelengths).</p>\n<p>The model is trained with the Adam optimizer and MSE loss for 300 epochs.</p>\n<p>The final output is the predicted spectrum.</p>\n<h2>Sigma Prediction</h2>\n<p>Predicting the sigma value proved challenging, and different methods significantly impacted the public LB score (with overconfident methods yielding a score of 0.0 on the LB). Two solutions showed great results.</p>\n<p>The first was calculating the standard deviation of the predicted spectrum for each planet. Then, the values are scaled to a new mean. The other was calculating for each planet the variance of its white curve, and also scaling it to a new mean.</p>\n<p>Performing linear regression on these two features and the mean of the predicted spectrum showed great improvement.</p>\n<h2>The Code</h2>\n<p>You can access the winning notebook <a href=\"https://www.kaggle.com/code/ibrahimhabibeg/lr-sigma-with-nn\" target=\"_blank\">here</a>. There is also a repo for this project containing the code used in the winning submission and other experiments. It also contains more information on the code and how to use it in Kaggle submissions. You can access it <a href=\"https://github.com/ibrahimhabibeg/ariel-2025\" target=\"_blank\">here</a>.</p>\n<h2>References and Acknowledgments</h2>\n<p>There are so many people whose work helped me build mine. To keep this write-up short, I wrote the references section in the GitHub repo for this project. You can find the references section <a href=\"https://github.com/ibrahimhabibeg/ariel-2025?tab=readme-ov-file#refrences\" target=\"_blank\">here</a>.</p>",
      "rawMarkdown": "First of all, I would like to thank all the organizers of this great contest for all their work and effort.\nI would also like to thank all participants who shared their ideas and code, especially the gold medal winners of last year's contest.\n\n# The 48th Place Solution\n\n## Data Calibration\n\nI didn't do anything special here. I followed the standard calibration notebook and changed the binning value to 4 for AIRS and 48 for FGS.\n\n## Transit Detection\n\nThe technique here is copied from [last year's 1st place solution](https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/c-number-daiwakun-1st-place-solution). The curve is smoothed, then, using the points of least and largest derivative value, estimates of the drop transit and rise times are found. These are only initial estimates that will later be refined.\n\nTo get the exact times where the transit drop begins and ends, we cut the signal to include only values from the signal's beginning until the initial estimate + a constant value.  Then we find 4 values, *a*, *b*, *t1*,  and *t2*, such that the RMSE between the signal and the following function is minimized.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F20416828%2F703a091aa92f7e1ca5d02d9f2b36bfa7%2Flatex.png?generation=1759002042022823&alt=media)\n\nwhere *t1 < t2* and *a > b*. The desired values are *t1* and *t2*. Those are the exact times the transit drop phase begins and ends, respectively. The exact times for the transit rise start and end are calculated similarly and are called *t3* and *t4*.\n\n## Feature Extraction\n\nThis part was hugely inspired by last year's [6th place solution](https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/through-the-thorns-to-the-star-6th-place-solution) and [Vitaly Kudelya's Notebook](https://www.kaggle.com/code/vitalykudelya/neurips-non-ml-transit-curve-fitting). For each wavelength, 7 transit depth values were extracted. The values were extracted in the following manner.\n\nFirst, for each planet, divide wavelengths into separate groups where neighboring wavelengths go to the same group. Wavelengths in the same group are averaged together (cross-wavelengths) to create a white curve per group.\n\nThen, the transit phases are detected in the manner discussed earlier.\n\nNext, we calculate the value *s* that minimizes the MAE of `np.concatenate([signal[:t1], signal[t2:t3]  * (s + 1.0), signal[t4:]])`. Stated more informally, we find the value such that when multiplied by the in-transit section it nearly equals the out-of-transit section, and we subtract 1 from that number. These values are extremely close to the target value; thus, they are great features for the model.\n\nFinally, we give each wavelength in the group that s-value.\n\nThis is made 7 times, each time using a different number of groups. The used values are 1, 2, 4, 8, 16, 32, and 64.\n\nNow we have 7 values for each of the 283 wavelengths.\n\n## Spectrum Prediction\n\nWe have features of shape (num_planets, 7, num_wavelengths). We also extract the Rs and i values of each planet, making a tensor of shape (num_planets, 2). Both tensors are passed to a neural network.\n\nSince important information can be extracted from neighboring wavelengths, the features tensor is passed through three 1D-CNN layers with increasing kernel size and ReLU between them. The last CNN has an out_channels value of 1. Its output is squeezed to form a tensor of shape (batch_size, num_wavelengths).\n\nThe CNN output is concatenated on the second axis with the star information (Rs and i). The data is then passed into three ResNet blocks. The final output has shape (batch_size, num_wavelengths).\n\nThe model is trained with the Adam optimizer and MSE loss for 300 epochs.\n\nThe final output is the predicted spectrum.\n\n## Sigma Prediction\n\nPredicting the sigma value proved challenging, and different methods significantly impacted the public LB score (with overconfident methods yielding a score of 0.0 on the LB). Two solutions showed great results.\n\nThe first was calculating the standard deviation of the predicted spectrum for each planet. Then, the values are scaled to a new mean. The other was calculating for each planet the variance of its white curve, and also scaling it to a new mean.\n\nPerforming linear regression on these two features and the mean of the predicted spectrum showed great improvement.\n\n## The Code\n\nYou can access the winning notebook [here](https://www.kaggle.com/code/ibrahimhabibeg/lr-sigma-with-nn). There is also a repo for this project containing the code used in the winning submission and other experiments. It also contains more information on the code and how to use it in Kaggle submissions. You can access it [here](https://github.com/ibrahimhabibeg/ariel-2025).\n\n## References and Acknowledgments\n\nThere are so many people whose work helped me build mine. To keep this write-up short, I wrote the references section in the GitHub repo for this project. You can find the references section [here](https://github.com/ibrahimhabibeg/ariel-2025?tab=readme-ov-file#refrences).",
      "votes": 2
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "3295150": "First of all, I would like to thank all the organizers of this great contest for all their work and effort.\nI would also like to thank all participants who shared their ideas and code, especially the gold medal winners of last year's contest.\n\n# The 48th Place Solution\n\n## Data Calibration\n\nI didn't do anything special here. I followed the standard calibration notebook and changed the binning value to 4 for AIRS and 48 for FGS.\n\n## Transit Detection\n\nThe technique here is copied from [last year's 1st place solution](https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/c-number-daiwakun-1st-place-solution). The curve is smoothed, then, using the points of least and largest derivative value, estimates of the drop transit and rise times are found. These are only initial estimates that will later be refined.\n\nTo get the exact times where the transit drop begins and ends, we cut the signal to include only values from the signal's beginning until the initial estimate + a constant value.  Then we find 4 values, *a*, *b*, *t1*,  and *t2*, such that the RMSE between the signal and the following function is minimized.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F20416828%2F703a091aa92f7e1ca5d02d9f2b36bfa7%2Flatex.png?generation=1759002042022823&alt=media)\n\nwhere *t1 < t2* and *a > b*. The desired values are *t1* and *t2*. Those are the exact times the transit drop phase begins and ends, respectively. The exact times for the transit rise start and end are calculated similarly and are called *t3* and *t4*.\n\n## Feature Extraction\n\nThis part was hugely inspired by last year's [6th place solution](https://www.kaggle.com/competitions/ariel-data-challenge-2024/writeups/through-the-thorns-to-the-star-6th-place-solution) and [Vitaly Kudelya's Notebook](https://www.kaggle.com/code/vitalykudelya/neurips-non-ml-transit-curve-fitting). For each wavelength, 7 transit depth values were extracted. The values were extracted in the following manner.\n\nFirst, for each planet, divide wavelengths into separate groups where neighboring wavelengths go to the same group. Wavelengths in the same group are averaged together (cross-wavelengths) to create a white curve per group.\n\nThen, the transit phases are detected in the manner discussed earlier.\n\nNext, we calculate the value *s* that minimizes the MAE of `np.concatenate([signal[:t1], signal[t2:t3]  * (s + 1.0), signal[t4:]])`. Stated more informally, we find the value such that when multiplied by the in-transit section it nearly equals the out-of-transit section, and we subtract 1 from that number. These values are extremely close to the target value; thus, they are great features for the model.\n\nFinally, we give each wavelength in the group that s-value.\n\nThis is made 7 times, each time using a different number of groups. The used values are 1, 2, 4, 8, 16, 32, and 64.\n\nNow we have 7 values for each of the 283 wavelengths.\n\n## Spectrum Prediction\n\nWe have features of shape (num_planets, 7, num_wavelengths). We also extract the Rs and i values of each planet, making a tensor of shape (num_planets, 2). Both tensors are passed to a neural network.\n\nSince important information can be extracted from neighboring wavelengths, the features tensor is passed through three 1D-CNN layers with increasing kernel size and ReLU between them. The last CNN has an out_channels value of 1. Its output is squeezed to form a tensor of shape (batch_size, num_wavelengths).\n\nThe CNN output is concatenated on the second axis with the star information (Rs and i). The data is then passed into three ResNet blocks. The final output has shape (batch_size, num_wavelengths).\n\nThe model is trained with the Adam optimizer and MSE loss for 300 epochs.\n\nThe final output is the predicted spectrum.\n\n## Sigma Prediction\n\nPredicting the sigma value proved challenging, and different methods significantly impacted the public LB score (with overconfident methods yielding a score of 0.0 on the LB). Two solutions showed great results.\n\nThe first was calculating the standard deviation of the predicted spectrum for each planet. Then, the values are scaled to a new mean. The other was calculating for each planet the variance of its white curve, and also scaling it to a new mean.\n\nPerforming linear regression on these two features and the mean of the predicted spectrum showed great improvement.\n\n## The Code\n\nYou can access the winning notebook [here](https://www.kaggle.com/code/ibrahimhabibeg/lr-sigma-with-nn). There is also a repo for this project containing the code used in the winning submission and other experiments. It also contains more information on the code and how to use it in Kaggle submissions. You can access it [here](https://github.com/ibrahimhabibeg/ariel-2025).\n\n## References and Acknowledgments\n\nThere are so many people whose work helped me build mine. To keep this write-up short, I wrote the references section in the GitHub repo for this project. You can find the references section [here](https://github.com/ibrahimhabibeg/ariel-2025?tab=readme-ov-file#refrences)."
  }
}