{
  "id": 239981,
  "title": "[11th] LSTM + Dynamic Programming Post-processing",
  "url": "/competitions/indoor-location-navigation/writeups/ouranos-vicens-11th-lstm-dynamic-programming-post-",
  "author_name": "",
  "post_date": "2021-05-18T08:04:33.782400200Z",
  "votes": 23,
  "comment_count": 6,
  "views": 0,
  "content": "<p>Congratulations to all the winners! And specially to my teammate <a href=\"https://www.kaggle.com/Ouranos\" target=\"_blank\">@Ouranos</a>, that becomes also Grand Master after this very interesting competition. We team up in the last week and that give us an amazing boost. At the end something went wrong, but we get our gold medal 😊</p>\n<p>My work has been mainly in the solution postprocessing.  The question was how to take into account simultaneously at path level, a <strong>regression model</strong> for the positions, the relative information from the <strong>sensors</strong>, the sequence of paths obtained from identifying unique <strong>devices</strong>, and most importantly, the fact that the positions are discretized over a <strong>grid</strong>.</p>\n<p>The funny thing is that is possible to express that as a <strong>combinatorial optimization problem</strong> over the grid, with a cost function that express that we want a solution over the grid, as near as possible to the regression model, that agree as much as possible with the deltas obtained with the sensors, and use the information of the sequence of paths all simultaneously<br>\nFor a finite grid of points Xg and a given path p with nt steps, with model X(t), sensor relative position Delta(t), information of previous and next path Xpr,Deltat_p, Xn,DeltaT_n,  we can write a cost function:</p>\n<p>$$<br>\n\\sum_{i=1}^{nt}  \\epsilon (Xg(t)-X(t))^2 + \\alpha   (Xg(t-1)-Xg(t) + Delta(t))^2 + \\gamma  (Xg(1)-Xp)^2/Deltat_p  + \\gamma (Xg(nt)-Xn)^2)/Deltat_n<br>\n$$</p>\n<p>Given suitable alpha, gamma and epsilon this expression can be optimized <strong>exactly</strong> using <strong>dynamic programming</strong> over t.</p>\n<p>In our case, the model was developed by <a href=\"https://www.kaggle.com/Ouranos\" target=\"_blank\">@Ouranos</a>. It is an average of 3 LSTM models, one of them specific for every building,  trained with pseudolabeling </p>\n<p>Train -&gt; post-process-&gt; Pseudolabel train-&gt; post-process</p>\n<p>The deltas are calculated using the code provided by the organizers in their github, and the sequence is obtained in a different way that has been described in the discussions.  We use a hash of the device information provided in the .txt files </p>\n<pre><code>#    Brand:OPPO  Model:PBCM10    AndroidName:8.1.0   APILevel:27 \n#    type:1  name:BMI160 Accelerometer   version:2062600 vendor:BOSCH    resolution:0.0023956299 power:0.18  maximumRange:39.22661\n#    type:4  name:BMI160 Gyroscope   version:2062600 vendor:BOSCH    resolution:0.0010681152 power:0.9   maximumRange:34.906586\n#    type:2  name:AK09911 Magnetometer   version:1   vendor:AKM  resolution:0.5996704    power:2.4   maximumRange:4911.9995\n#    type:35 name:BMI160 Accelerometer Uncalibrated  version:2062600 vendor:BOSCH    resolution:0.0023956299 power:0.18  maximumRange:39.22661\n#    type:16 name:BMI160 Gyroscope Uncalibrated  version:2062600 vendor:BOSCH    resolution:0.0010681152 power:0.9   maximumRange:34.906586\n#    type:14 name:AK09911 Magnetometer Uncalibrated  version:1   vendor:AKM  resolution:0.5996704    power:2.4   maximumRange:4911.9995\n#    VersionName:v20191120-nightly-9-gde3748b    VersionCode:424 \n</code></pre>\n<p>When no information is provided, the 5 first characters of the path is a good proxy.</p>\n<p>Before starting the optimization, we extend the original grid dynamically with 2 types of points:<br>\n1.- We add points from the X solution that are far from any original grid point.<br>\n2.-When the distance between points in the X solution is bigger than a certain threshold, we introduce intermediate points.</p>\n<p>We are sharing the post-processing code at <a href=\"https://www.kaggle.com/vicensgaitan/11th-dynamic-programming-post-procesing\" target=\"_blank\">11th-dynamic-programming-post-procesing</a></p>",
  "messages": [
    {
      "id": "1312729",
      "postDate": "05/18/2021 08:04:33",
      "content": "<p>Congratulations to all the winners! And specially to my teammate <a href=\"https://www.kaggle.com/Ouranos\" target=\"_blank\">@Ouranos</a>, that becomes also Grand Master after this very interesting competition. We team up in the last week and that give us an amazing boost. At the end something went wrong, but we get our gold medal 😊</p>\n<p>My work has been mainly in the solution postprocessing.  The question was how to take into account simultaneously at path level, a <strong>regression model</strong> for the positions, the relative information from the <strong>sensors</strong>, the sequence of paths obtained from identifying unique <strong>devices</strong>, and most importantly, the fact that the positions are discretized over a <strong>grid</strong>.</p>\n<p>The funny thing is that is possible to express that as a <strong>combinatorial optimization problem</strong> over the grid, with a cost function that express that we want a solution over the grid, as near as possible to the regression model, that agree as much as possible with the deltas obtained with the sensors, and use the information of the sequence of paths all simultaneously<br>\nFor a finite grid of points Xg and a given path p with nt steps, with model X(t), sensor relative position Delta(t), information of previous and next path Xpr,Deltat_p, Xn,DeltaT_n,  we can write a cost function:</p>\n<p>$$<br>\n\\sum_{i=1}^{nt}  \\epsilon (Xg(t)-X(t))^2 + \\alpha   (Xg(t-1)-Xg(t) + Delta(t))^2 + \\gamma  (Xg(1)-Xp)^2/Deltat_p  + \\gamma (Xg(nt)-Xn)^2)/Deltat_n<br>\n$$</p>\n<p>Given suitable alpha, gamma and epsilon this expression can be optimized <strong>exactly</strong> using <strong>dynamic programming</strong> over t.</p>\n<p>In our case, the model was developed by <a href=\"https://www.kaggle.com/Ouranos\" target=\"_blank\">@Ouranos</a>. It is an average of 3 LSTM models, one of them specific for every building,  trained with pseudolabeling </p>\n<p>Train -&gt; post-process-&gt; Pseudolabel train-&gt; post-process</p>\n<p>The deltas are calculated using the code provided by the organizers in their github, and the sequence is obtained in a different way that has been described in the discussions.  We use a hash of the device information provided in the .txt files </p>\n<pre><code>#    Brand:OPPO  Model:PBCM10    AndroidName:8.1.0   APILevel:27 \n#    type:1  name:BMI160 Accelerometer   version:2062600 vendor:BOSCH    resolution:0.0023956299 power:0.18  maximumRange:39.22661\n#    type:4  name:BMI160 Gyroscope   version:2062600 vendor:BOSCH    resolution:0.0010681152 power:0.9   maximumRange:34.906586\n#    type:2  name:AK09911 Magnetometer   version:1   vendor:AKM  resolution:0.5996704    power:2.4   maximumRange:4911.9995\n#    type:35 name:BMI160 Accelerometer Uncalibrated  version:2062600 vendor:BOSCH    resolution:0.0023956299 power:0.18  maximumRange:39.22661\n#    type:16 name:BMI160 Gyroscope Uncalibrated  version:2062600 vendor:BOSCH    resolution:0.0010681152 power:0.9   maximumRange:34.906586\n#    type:14 name:AK09911 Magnetometer Uncalibrated  version:1   vendor:AKM  resolution:0.5996704    power:2.4   maximumRange:4911.9995\n#    VersionName:v20191120-nightly-9-gde3748b    VersionCode:424 \n</code></pre>\n<p>When no information is provided, the 5 first characters of the path is a good proxy.</p>\n<p>Before starting the optimization, we extend the original grid dynamically with 2 types of points:<br>\n1.- We add points from the X solution that are far from any original grid point.<br>\n2.-When the distance between points in the X solution is bigger than a certain threshold, we introduce intermediate points.</p>\n<p>We are sharing the post-processing code at <a href=\"https://www.kaggle.com/vicensgaitan/11th-dynamic-programming-post-procesing\" target=\"_blank\">11th-dynamic-programming-post-procesing</a></p>",
      "rawMarkdown": "Congratulations to all the winners! And specially to my teammate @Ouranos, that becomes also Grand Master after this very interesting competition. We team up in the last week and that give us an amazing boost. At the end something went wrong, but we get our gold medal 😊\n\nMy work has been mainly in the solution postprocessing.  The question was how to take into account simultaneously at path level, a **regression model** for the positions, the relative information from the **sensors**, the sequence of paths obtained from identifying unique **devices**, and most importantly, the fact that the positions are discretized over a **grid**.\n\nThe funny thing is that is possible to express that as a **combinatorial optimization problem** over the grid, with a cost function that express that we want a solution over the grid, as near as possible to the regression model, that agree as much as possible with the deltas obtained with the sensors, and use the information of the sequence of paths all simultaneously\nFor a finite grid of points Xg and a given path p with nt steps, with model X(t), sensor relative position Delta(t), information of previous and next path Xpr,Deltat_p, Xn,DeltaT_n,  we can write a cost function:\n\n$$\n\\sum_{i=1}^{nt}  \\epsilon (Xg(t)-X(t))^2 + \\alpha   (Xg(t-1)-Xg(t) + Delta(t))^2 + \\gamma  (Xg(1)-Xp)^2/Deltat_p  + \\gamma (Xg(nt)-Xn)^2)/Deltat_n\n$$\n\nGiven suitable alpha, gamma and epsilon this expression can be optimized **exactly** using **dynamic programming** over t.\n\nIn our case, the model was developed by @Ouranos. It is an average of 3 LSTM models, one of them specific for every building,  trained with pseudolabeling \n\nTrain -> post-process-> Pseudolabel train-> post-process\n\n The deltas are calculated using the code provided by the organizers in their github, and the sequence is obtained in a different way that has been described in the discussions.  We use a hash of the device information provided in the .txt files \n\n```\n#\tBrand:OPPO\tModel:PBCM10\tAndroidName:8.1.0\tAPILevel:27\t\n#\ttype:1\tname:BMI160 Accelerometer\tversion:2062600\tvendor:BOSCH\tresolution:0.0023956299\tpower:0.18\tmaximumRange:39.22661\n#\ttype:4\tname:BMI160 Gyroscope\tversion:2062600\tvendor:BOSCH\tresolution:0.0010681152\tpower:0.9\tmaximumRange:34.906586\n#\ttype:2\tname:AK09911 Magnetometer\tversion:1\tvendor:AKM\tresolution:0.5996704\tpower:2.4\tmaximumRange:4911.9995\n#\ttype:35\tname:BMI160 Accelerometer Uncalibrated\tversion:2062600\tvendor:BOSCH\tresolution:0.0023956299\tpower:0.18\tmaximumRange:39.22661\n#\ttype:16\tname:BMI160 Gyroscope Uncalibrated\tversion:2062600\tvendor:BOSCH\tresolution:0.0010681152\tpower:0.9\tmaximumRange:34.906586\n#\ttype:14\tname:AK09911 Magnetometer Uncalibrated\tversion:1\tvendor:AKM\tresolution:0.5996704\tpower:2.4\tmaximumRange:4911.9995\n#\tVersionName:v20191120-nightly-9-gde3748b\tVersionCode:424\t\n```\n\nWhen no information is provided, the 5 first characters of the path is a good proxy.\n\nBefore starting the optimization, we extend the original grid dynamically with 2 types of points:\n1.- We add points from the X solution that are far from any original grid point.\n2.-When the distance between points in the X solution is bigger than a certain threshold, we introduce intermediate points.\n\nWe are sharing the post-processing code at [11th-dynamic-programming-post-procesing] (https://www.kaggle.com/vicensgaitan/11th-dynamic-programming-post-procesing)",
      "votes": null
    },
    {
      "id": "1312762",
      "postDate": "05/18/2021 08:23:08",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a>. This was an exciting competition for us all. Our solutions supplemented each other perfectly. Great Dynamic Programming Post-processing, Bravo!!!</p>",
      "rawMarkdown": "Congratulations @vicensgaitan. This was an exciting competition for us all. Our solutions supplemented each other perfectly. Great Dynamic Programming Post-processing, Bravo!!!",
      "votes": null
    },
    {
      "id": "1312829",
      "postDate": "05/18/2021 09:22:03",
      "content": "<p>great solution</p>",
      "rawMarkdown": "great solution",
      "votes": null
    },
    {
      "id": "1312852",
      "postDate": "05/18/2021 09:30:47",
      "content": "<p>To my surprised, I also did similar postprocessing. <a href=\"https://www.kaggle.com/c/indoor-location-navigation/discussion/239998\" target=\"_blank\">my discussion</a><br>\nBut your method is much more sophisticated than mine.<br>\nThat separated gold (you) and silver (me). :)<br>\nCongrats!!</p>",
      "rawMarkdown": "To my surprised, I also did similar postprocessing. [my discussion](https://www.kaggle.com/c/indoor-location-navigation/discussion/239998)\nBut your method is much more sophisticated than mine.\nThat separated gold (you) and silver (me). :)\nCongrats!!",
      "votes": null
    },
    {
      "id": "1313833",
      "postDate": "05/18/2021 18:31:34",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a> ( <a href=\"https://www.kaggle.com/ouranos\" target=\"_blank\">@ouranos</a> ) for your upgrade to GrandMaster, it is exciting to think how super happy you have to be at this moment. Excellent competition with a brilliant high-level final solution!</p>",
      "rawMarkdown": "Congratulations @vicensgaitan ( @ouranos ) for your upgrade to GrandMaster, it is exciting to think how super happy you have to be at this moment. Excellent competition with a brilliant high-level final solution!",
      "votes": null
    },
    {
      "id": "1314126",
      "postDate": "05/19/2021 01:05:32",
      "content": "<p>Great solution and approach. Congrats GMs <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a> and <a href=\"https://www.kaggle.com/ouranos\" target=\"_blank\">@ouranos</a>!</p>",
      "rawMarkdown": "Great solution and approach. Congrats GMs @vicensgaitan and @ouranos!",
      "votes": null
    },
    {
      "id": "1314318",
      "postDate": "05/19/2021 05:33:38",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/ouranos\" target=\"_blank\">@ouranos</a> and <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a> for the great solution as well your GM rank. Well deserved!</p>",
      "rawMarkdown": "Congratulations @ouranos and @vicensgaitan for the great solution as well your GM rank. Well deserved!",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1312762,
      "author_name": "ouranos",
      "author_url": "",
      "post_date": "05/18/2021 08:23:08",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a>. This was an exciting competition for us all. Our solutions supplemented each other perfectly. Great Dynamic Programming Post-processing, Bravo!!!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1312829,
      "author_name": "max2020",
      "author_url": "",
      "post_date": "05/18/2021 09:22:03",
      "content": "<p>great solution</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1312852,
      "author_name": "iwatatakuya",
      "author_url": "",
      "post_date": "05/18/2021 09:30:47",
      "content": "<p>To my surprised, I also did similar postprocessing. <a href=\"https://www.kaggle.com/c/indoor-location-navigation/discussion/239998\" target=\"_blank\">my discussion</a><br>\nBut your method is much more sophisticated than mine.<br>\nThat separated gold (you) and silver (me). :)<br>\nCongrats!!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1313833,
      "author_name": "coreacasa",
      "author_url": "",
      "post_date": "05/18/2021 18:31:34",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a> ( <a href=\"https://www.kaggle.com/ouranos\" target=\"_blank\">@ouranos</a> ) for your upgrade to GrandMaster, it is exciting to think how super happy you have to be at this moment. Excellent competition with a brilliant high-level final solution!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1314126,
      "author_name": "robikscube",
      "author_url": "",
      "post_date": "05/19/2021 01:05:32",
      "content": "<p>Great solution and approach. Congrats GMs <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a> and <a href=\"https://www.kaggle.com/ouranos\" target=\"_blank\">@ouranos</a>!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1314318,
      "author_name": "neongen",
      "author_url": "",
      "post_date": "05/19/2021 05:33:38",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/ouranos\" target=\"_blank\">@ouranos</a> and <a href=\"https://www.kaggle.com/vicensgaitan\" target=\"_blank\">@vicensgaitan</a> for the great solution as well your GM rank. Well deserved!</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1312729": "Congratulations to all the winners! And specially to my teammate @Ouranos, that becomes also Grand Master after this very interesting competition. We team up in the last week and that give us an amazing boost. At the end something went wrong, but we get our gold medal 😊\n\nMy work has been mainly in the solution postprocessing.  The question was how to take into account simultaneously at path level, a **regression model** for the positions, the relative information from the **sensors**, the sequence of paths obtained from identifying unique **devices**, and most importantly, the fact that the positions are discretized over a **grid**.\n\nThe funny thing is that is possible to express that as a **combinatorial optimization problem** over the grid, with a cost function that express that we want a solution over the grid, as near as possible to the regression model, that agree as much as possible with the deltas obtained with the sensors, and use the information of the sequence of paths all simultaneously\nFor a finite grid of points Xg and a given path p with nt steps, with model X(t), sensor relative position Delta(t), information of previous and next path Xpr,Deltat_p, Xn,DeltaT_n,  we can write a cost function:\n\n$$\n\\sum_{i=1}^{nt}  \\epsilon (Xg(t)-X(t))^2 + \\alpha   (Xg(t-1)-Xg(t) + Delta(t))^2 + \\gamma  (Xg(1)-Xp)^2/Deltat_p  + \\gamma (Xg(nt)-Xn)^2)/Deltat_n\n$$\n\nGiven suitable alpha, gamma and epsilon this expression can be optimized **exactly** using **dynamic programming** over t.\n\nIn our case, the model was developed by @Ouranos. It is an average of 3 LSTM models, one of them specific for every building,  trained with pseudolabeling \n\nTrain -> post-process-> Pseudolabel train-> post-process\n\n The deltas are calculated using the code provided by the organizers in their github, and the sequence is obtained in a different way that has been described in the discussions.  We use a hash of the device information provided in the .txt files \n\n```\n#\tBrand:OPPO\tModel:PBCM10\tAndroidName:8.1.0\tAPILevel:27\t\n#\ttype:1\tname:BMI160 Accelerometer\tversion:2062600\tvendor:BOSCH\tresolution:0.0023956299\tpower:0.18\tmaximumRange:39.22661\n#\ttype:4\tname:BMI160 Gyroscope\tversion:2062600\tvendor:BOSCH\tresolution:0.0010681152\tpower:0.9\tmaximumRange:34.906586\n#\ttype:2\tname:AK09911 Magnetometer\tversion:1\tvendor:AKM\tresolution:0.5996704\tpower:2.4\tmaximumRange:4911.9995\n#\ttype:35\tname:BMI160 Accelerometer Uncalibrated\tversion:2062600\tvendor:BOSCH\tresolution:0.0023956299\tpower:0.18\tmaximumRange:39.22661\n#\ttype:16\tname:BMI160 Gyroscope Uncalibrated\tversion:2062600\tvendor:BOSCH\tresolution:0.0010681152\tpower:0.9\tmaximumRange:34.906586\n#\ttype:14\tname:AK09911 Magnetometer Uncalibrated\tversion:1\tvendor:AKM\tresolution:0.5996704\tpower:2.4\tmaximumRange:4911.9995\n#\tVersionName:v20191120-nightly-9-gde3748b\tVersionCode:424\t\n```\n\nWhen no information is provided, the 5 first characters of the path is a good proxy.\n\nBefore starting the optimization, we extend the original grid dynamically with 2 types of points:\n1.- We add points from the X solution that are far from any original grid point.\n2.-When the distance between points in the X solution is bigger than a certain threshold, we introduce intermediate points.\n\nWe are sharing the post-processing code at [11th-dynamic-programming-post-procesing] (https://www.kaggle.com/vicensgaitan/11th-dynamic-programming-post-procesing)",
    "1312762": "Congratulations @vicensgaitan. This was an exciting competition for us all. Our solutions supplemented each other perfectly. Great Dynamic Programming Post-processing, Bravo!!!",
    "1312829": "great solution",
    "1312852": "To my surprised, I also did similar postprocessing. [my discussion](https://www.kaggle.com/c/indoor-location-navigation/discussion/239998)\nBut your method is much more sophisticated than mine.\nThat separated gold (you) and silver (me). :)\nCongrats!!",
    "1313833": "Congratulations @vicensgaitan ( @ouranos ) for your upgrade to GrandMaster, it is exciting to think how super happy you have to be at this moment. Excellent competition with a brilliant high-level final solution!",
    "1314126": "Great solution and approach. Congrats GMs @vicensgaitan and @ouranos!",
    "1314318": "Congratulations @ouranos and @vicensgaitan for the great solution as well your GM rank. Well deserved!"
  },
  "source": "meta"
}