{
  "id": 127891,
  "title": "3rd solution - single TRANSFORMER model, link to kernel",
  "content": "<p>I'm sorry. It was a traditional Korean holidays until today, so I didn't have time to write this. Thank you for your patience.</p>\n\n<p>First of all, I would like to thank Booz Allen Hamilton for hosting this interesting competition. And congratulates to the all participants and especially the winners! </p>\n\n<p>I like deep neural networks so I prefer to solve all the problems with a deep neural networks. 😃 </p>\n\n<p>I focus on the structure of the input data rather than understanding the input data. And concentrate on making the model's input by avoiding missing information as much as possible, hoping that the model will do more than I expected. 😊 </p>\n\n<p>In other words, I focus <code>less</code> on feature engineering and <code>more</code> on finding a neural net model architecture that fits the data.</p>\n\n<h1>Interesting point</h1>\n\n<ul>\n<li>What's interesting is that using position-related information(especially position embedding) decreases local CV score.\n<ul><li>The performance of the BERT, ALBERT and GPT2 models was not good. (Because these models use position embedding)</li>\n<li>So I used the TRANSFORMER model without position embedding.</li></ul></li>\n</ul>\n\n<h1>Pre-processing</h1>\n\n<h3>Aggregation by game_session</h3>\n\n<p>The sequence of installation_id is too long to be used as it is. So I aggregated log data (train_df) by game_session. Please see the example below.\n<code>\ndf = train_df\nevent_code = pd.crosstab(df['game_session'], df['event_code'])\nevent_id = pd.crosstab(df['game_session'], df['event_id'])\n...\nagged_df = pd.concat([event_code, event_id, game_accuracy, max_round])\nsession_df = df.drop_duplicates('game_session', keep='last').reset_index(drop=True)\nsession_df = session_df.merge(agged_df, how='left', on='game_session')\n</code></p>\n\n<p>The LSTM and TRANSFORMER models in NLP receive sequence of words (or sentence) as input. Similarly, I will use the sequence of game_sessions (or installation_id) as input here. </p>\n\n<h1>Model</h1>\n\n<p>Best private score: 0.564\nSingle transformer model used.</p>\n\n<h3>TRANSFORMER MODEL BLOCK</h3>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1658108%2F6a4d5317015ad5235b526b46d1327fee%2Fdsb20192.png?generation=1582589525333424&amp;alt=media\" alt=\"\"></p>\n\n<p>Prediction from game_sessions of an installation_id</p>\n\n<h3>The key here is how to create embedding from the game_session.</h3>\n\n<p><code>Categorical columns</code> (such as event_code, title, world, etc...) were embedded respectively. Then, the categorical_vector were obtained by concatenating the embeddings. Next the nn.linear layer is applied for the dimension reduction of the categorical vector.\n<code>\nself.categorical_proj = nn.Sequential(\n            nn.Linear(cfg.emb_size*num_categorical_columns, cfg.hidden_size//2),\n            nn.LayerNorm(cfg.hidden_size//2),\n        ) <br>\n</code></p>\n\n<p><code>Continuous columns</code> were embedded directly using a linear layer.\n<code>\nself.continuous_emb = nn.Sequential( <br>\n            nn.Linear(num_continuous_columns, cfg.hidden_size//2),\n            nn.LayerNorm(cfg.hidden_size//2),\n        )\n</code>\n* I used np.log1p for normalization of continuous columns.</p>\n\n<h3>hyper parameters</h3>\n\n<ul>\n<li>optimizer: AdamW</li>\n<li>schedular: WarmupLinearSchedule</li>\n<li>learning_rate: 1e-04</li>\n<li>dropout: 0.2</li>\n<li>number of layers : 2</li>\n<li>embedding_size: 100</li>\n<li>hidden_size: 500</li>\n</ul>\n\n<h1>Modified loss function</h1>\n\n<p><a href=\"https://www.kaggle.com/c/data-science-bowl-2019/discussion/124836\">https://www.kaggle.com/c/data-science-bowl-2019/discussion/124836</a>\nAs mentioned in this link, the 0 and 3 classes of the accuracy_group may be very close. \nnum_correct can have 0 or 1, if the num_correct has 1 then the accuracy_group increases 3 points.\nOn the other hand, num_incorrect decreases 1 point when num_incorrect has 1 and decreases 2 points when num_incorrect has 2 or more.</p>\n\n<p>This could be expressed as \n```</p>\n\n<h1>num_incorrect[num_incorrect &gt; 2 ] = 2 # Constrained not to exceed 2.</h1>\n\n<p>new_accuracy_group = 3 * num_correct - num_incorrect\n```</p>\n\n<p>Using the above equation, we can calculate the real values of 0 to 3 from num_correct, num_incorrect.\nTherefore, the prediction of the model is set to [num_correct_pred, num_incorrect_pred]</p>\n\n<p>```\nprediction = model(x)  # prediction = [num_correct_pred, num_incorrect_pred]</p>\n\n<h1>target = [num_correct; num_incorrect]</h1>\n\n<p><code>\n**Then train the model with the modified_loss below.**\n</code>\nmodified_loss = mse_loss( prediction, target )\n```</p>\n\n<p>After the training is done, we can use the new_accuracy_group calculated from \"num_correct_pred, num_incorrect_pred\".\n<code>\nnum_correct_pred, num_incorrect_pred = prediction\nnew_accuracy_group = 3 * num_correct_pred - num_incorrect_pred\n</code></p>\n\n<p>We can also use original accuracy_group to slightly improve performance.\n```\nprediction = model(x)  # prediction = [accuracy_group_pred, num_correct_pred, num_incorrect_pred]</p>\n\n<h1>target = [accuracy_group; num_correct; num_incorrect]</h1>\n\n<p>```</p>\n\n<p><strong>The final_accuracy_group is calculated as below.</strong>\n<code>\nnew_accuracy_group = 3 * num_correct_pred - num_incorrect_pred\nfinal_accuracy_group = (accuracy_group_pred + new_accuracy_group) / 2\n</code></p>\n\n<h1>Additional training data generation</h1>\n\n<p>I generated an additional label for game_sessions, where the type is <strong>Game</strong>. From the \"correct\":true, “correct”:false of event_data, I was able to create num_correct and num_incorrect, and likewise I was able to create an accuracy_group.\nThe number of additional training samples generated is 41,194.</p>\n\nPre-training and fine-tuning steps\n\n<ul>\n<li>Pre-training step - up to 3 epoch, the model was trained with the original labels + additional labels.</li>\n<li>Fine-tuning step - from 4 epoch, the model was trained with the original labels.</li>\n</ul>\n\n<h1>Data Augmentation</h1>\n\n<ul>\n<li>training time augmentation - For installation_id with more than 30 game_sessions, up to 50% were randomly removed in the old order.</li>\n<li>test time augmentation - For installation_id with more than 30 game_sessions, up to 60% were randomly removed in the old order.</li>\n</ul>\n\n<h2>Link to kernel</h2>\n\n<p><a href=\"https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615\">https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615</a></p>\n\n<p>It is a shame to me sharing the uncleane code. But first I decided to share the kernel and make a clean code. Maybe in two weeks? ;)</p>\n\n<ul>\n<li>The training code is also released. I'm sorry it's still unclean code.\n<a href=\"https://github.com/lime-robot/dsb2019\">https://github.com/lime-robot/dsb2019</a></li>\n</ul>",
  "comments": [
    {
      "id": 731908,
      "author_name": "Limerobot",
      "author_url": "",
      "post_date": "2020-01-29T08:11:56.877000",
      "content": "<p>It is a shame to me sharing the uncleane code. \nBut first I decided to share the kernel and make a clean code. Maybe in two weeks?\n<a href=\"https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615\">https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615</a></p>",
      "votes": 5,
      "replies": [
        {
          "id": 731937,
          "author_name": "Y. O.",
          "author_url": "",
          "post_date": "2020-01-29T09:17:52.630000",
          "content": "<p>Thank you so much. I’m sorry for creating the extra work.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 732212,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-29T15:22:09.887000",
          "content": "<p>It's ok 😂 </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 732690,
      "author_name": "Yan Linn Aung",
      "author_url": "",
      "post_date": "2020-01-30T05:39:07.343000",
      "content": "<p>Great job. Thanks for sharing!</p>",
      "votes": 2,
      "replies": [
        {
          "id": 732692,
          "author_name": "Agupon",
          "author_url": "",
          "post_date": "2020-01-30T05:42:49.400000",
          "content": "<p>*YEAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<strong>💪 👎 👎 *</strong></p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 731558,
      "author_name": "kensler",
      "author_url": "",
      "post_date": "2020-01-28T19:33:18.833000",
      "content": "<p><a href=\"/limerobot\">@limerobot</a>, congratulations and thanks for the interesting writeup!  This was my first Kaggle competition and I invested a ton of time on it.  Very frustrating that we had kernels that would have been solid silver but we ended up just missing Bronze.  I had an idea for and LSTM using train summarized by session but we didnt quite get it working.  I'd really like to understand all the details of how you manipulated the data and built your model.  Might you share the code?</p>",
      "votes": 2,
      "replies": [
        {
          "id": 731727,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-29T01:04:35.370000",
          "content": "<p>Please check your e-mail 😃</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 731840,
          "author_name": "kensler",
          "author_url": "",
          "post_date": "2020-01-29T06:08:36.617000",
          "content": "<p>Many thanks!  So much to learn!!!  😊 </p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 731500,
      "author_name": "Abdur Rehman",
      "author_url": "",
      "post_date": "2020-01-28T17:56:49.867000",
      "content": "<p><a href=\"/limerobot\">@limerobot</a> Great Solution and Congrats on winning. Can you share your kernel please? I want to give a try to your approach and expecting a lot to learn from your solution.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 731728,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-29T01:04:42.010000",
          "content": "<p>Please check your e-mail 😃</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 731961,
          "author_name": "toshi_k",
          "author_url": "",
          "post_date": "2020-01-29T09:53:45.893000",
          "content": "<p><a href=\"/limerobot\">@limerobot</a> Could you share your kernel with me too ? I want to compare my model with yours.</p>\n\n<p>EDIT: Sorry, I've missed the link. Thank you for sharing !!</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 731998,
          "author_name": "Abdur Rehman",
          "author_url": "",
          "post_date": "2020-01-29T11:10:31.620000",
          "content": "<p>Thanks <a href=\"/limerobot\">@limerobot</a> </p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1058685,
      "author_name": "MhdSharuk",
      "author_url": "",
      "post_date": "2020-10-24T05:20:21.173000",
      "content": "<p>Could you please share your kernel..</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 754013,
      "author_name": "Jye",
      "author_url": "",
      "post_date": "2020-02-22T23:23:08.630000",
      "content": "<p>Great solution, and thanks for sharing the code and write-up. </p>\n\n<p>I'm just curious about one thing. The goal of the competition was to \"Uncover the factors to help measure how young children learn\". With something like a decision tree we can quite easily have an idea about the most important factors, but with a Transformer model (or nn in general) that seems to be a lot harder. </p>\n\n<p>How do you think your model could be used to identify the best learning patterns in children? Do you think it's better to have a less accurate but more readable model for the use case of the competition organisers?</p>\n\n<p>Would be great to hear your thoughts!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 772339,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-03-15T11:28:33.580000",
          "content": "<p><a href=\"/jyesawtellrickson\">@jyesawtellrickson</a>  I'm really sorry for late reply. Please consider using notifications(@) to me. 🐱 </p>\n\n<p>I think the results of various models will help competition organisers.</p>\n\n<p>For example, the fact that performance has decreased when sequential information is used can help clarify the relationship between random path and linear progression.\nBelow is what competition organiser mentioned.</p>\n\n<p><a href=\"https://www.kaggle.com/c/data-science-bowl-2019/discussion/115034\">https://www.kaggle.com/c/data-science-bowl-2019/discussion/115034</a></p>\n\n<blockquote>\n  <p>The app is designed to try to guide the kids through an idealized learning path, which is intended to present players with a pattern of exposure-&gt;exploration-&gt;practice-&gt;demonstration (as in demonstration of knowledge). Each of the worlds in the app may have one or more such sequences of media objects, and sometimes the app does not follow this exact formula. </p>\n  \n  <p><code>However, kids are not required to follow the path that is laid out for them, and whether the suggested linear progression leads to better learning outcomes than a random path is not yet clear.</code>  Perhaps this competition will give us some insights into this question as well!</p>\n</blockquote>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 741660,
      "author_name": "Yassine Alouini",
      "author_url": "",
      "post_date": "2020-02-10T21:34:51.520000",
      "content": "<p>So much great ideas. And I should get better at applying transformers. Thanks for sharing the insights and the kernel! </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 737144,
      "author_name": "Yuan",
      "author_url": "",
      "post_date": "2020-02-05T00:48:49.720000",
      "content": "<p>Congratz and thanks for the big sharing! It is super helpful for learning! 👍  🤘 </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 733698,
      "author_name": "Akhil Gupta",
      "author_url": "",
      "post_date": "2020-01-31T12:47:46.153000",
      "content": "<p>Nice work</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 733639,
      "author_name": "HELLOWORLD",
      "author_url": "",
      "post_date": "2020-01-31T11:30:18.540000",
      "content": "<p>what is transformer? i dont know that. can you describe some? </p>",
      "votes": 1,
      "replies": [
        {
          "id": 772342,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-03-15T11:33:21.797000",
          "content": "<p>Please refer to the \"Attention Is All You Need\" paper or a well-organized blog on the Internet. 😃 \nI think that's a better way.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 733511,
      "author_name": "Parikshit Agarwal",
      "author_url": "",
      "post_date": "2020-01-31T08:35:49.117000",
      "content": "<p>very impressive!!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 733462,
      "author_name": "Nandesh Prasad",
      "author_url": "",
      "post_date": "2020-01-31T06:47:32.763000",
      "content": "<p>Great Job Buddy </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 733317,
      "author_name": "kevin_hu",
      "author_url": "",
      "post_date": "2020-01-31T00:28:39.570000",
      "content": "<p>very interesting kernel.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 733138,
      "author_name": "Patrick Chan",
      "author_url": "",
      "post_date": "2020-01-30T18:09:16.540000",
      "content": "<p>Congrats Limerobot. Very good impressive work with a single model. Appreciate if you can also point us to your training kernel and code.  Many thanks.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 732670,
      "author_name": "Kuldeep  Arya",
      "author_url": "",
      "post_date": "2020-01-30T04:42:15.660000",
      "content": "<p>it's very interesting and great kernal its very useful for learning purpose. thanks for sharing </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 732566,
      "author_name": "corochann",
      "author_url": "",
      "post_date": "2020-01-30T00:13:03.790000",
      "content": "<p>Interesting approach. Congrats!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 732295,
      "author_name": "Miyabon",
      "author_url": "",
      "post_date": "2020-01-29T16:39:04.940000",
      "content": "<p>Congrats &amp; Thanks for sharing!!🎉 😄 👍 </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 732232,
      "author_name": "S.Sakai_65",
      "author_url": "",
      "post_date": "2020-01-29T15:43:13.933000",
      "content": "<p>Great job. Really helpful. Thanks for sharing.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 732222,
      "author_name": "Wonho Song",
      "author_url": "",
      "post_date": "2020-01-29T15:32:23.920000",
      "content": "<p>It's a really beautiful write-up. Thank you for sharing !</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 732009,
      "author_name": "Kevin_Tran",
      "author_url": "",
      "post_date": "2020-01-29T11:30:20.637000",
      "content": "<p>very helpful :)</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 731989,
      "author_name": "hendrikjoosten",
      "author_url": "",
      "post_date": "2020-01-29T10:43:42.053000",
      "content": "<p>This is a very good explanation, looking forward to the clean code release!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 731979,
      "author_name": "Dan Ofer",
      "author_url": "",
      "post_date": "2020-01-29T10:26:49.573000",
      "content": "<p>Dang, 3d place with just 1 model and relatively little FE? Neat! \n(It's interesting to see how Attention models worked well for some and not others. How much worse was your model with the PE?).</p>",
      "votes": 1,
      "replies": [
        {
          "id": 732219,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-29T15:29:18.027000",
          "content": "<p>I remember with PE decreased the local CV score about 0.02~0.03</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 731909,
      "author_name": "Changmin Choi",
      "author_url": "",
      "post_date": "2020-01-29T08:14:36.767000",
      "content": "<p>Congrats on winning the competition and thank you for sharing the approach!! \nCould you share your code please? </p>",
      "votes": 1,
      "replies": [
        {
          "id": 732217,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-29T15:24:24.443000",
          "content": "<p>Please see the link above 😃 </p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 731028,
      "author_name": "toshi_k",
      "author_url": "",
      "post_date": "2020-01-28T09:18:34.020000",
      "content": "<p>Thank you for sharing !\nHow did you aggregate the output of Transformer ? Are the numbers of <code>game_session</code> different for each installation_id ?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 731156,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-28T12:09:13.200000",
          "content": "<p>Yep, installation_id is a variable-length sequence.\nSo I set the sequence length to 100 and I added PAD tokens to the front in the case of a short sequence. Then like the figure above, I took the last output of the sequence.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 730885,
      "author_name": "Raghawendra Singh",
      "author_url": "",
      "post_date": "2020-01-28T04:03:51.453000",
      "content": "<p>Very impressive!!! Thanks for sharing your solution.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 730884,
      "author_name": "Hanjoon Choe",
      "author_url": "",
      "post_date": "2020-01-28T03:59:26.780000",
      "content": "<p>Thank you for sharing! I should learn this! ;-) Congratulations!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 730835,
      "author_name": "Kha Vo",
      "author_url": "",
      "post_date": "2020-01-28T02:01:00.640000",
      "content": "<p><a href=\"/limerobot\">@limerobot</a>  Great solution! May I ask would you share your kernel? I want to try to blend your method with mine and see the effect. </p>",
      "votes": 1,
      "replies": [
        {
          "id": 731143,
          "author_name": "Limerobot",
          "author_url": "",
          "post_date": "2020-01-28T11:55:20.873000",
          "content": "<p>Please check your e-mail 😃 </p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 731851,
          "author_name": "Kha Vo",
          "author_url": "",
          "post_date": "2020-01-29T06:16:59.333000",
          "content": "<p>Thanks. I will do that in 2 weeks and let you know the result. </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 730825,
      "author_name": "narsil (jobs-in-data.com)",
      "author_url": "",
      "post_date": "2020-01-28T01:39:23.410000",
      "content": "<p>Amazing work. Congrats on 3rd place and GM status - you earned it. </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 730578,
      "author_name": "Gammer",
      "author_url": "",
      "post_date": "2020-01-27T16:44:44.783000",
      "content": "<p>Great job. I was curious about your solution. Thanks for sharing.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 730430,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-27T13:30:50.150000",
      "content": "",
      "votes": 1,
      "replies": [
        {
          "id": 730814,
          "author_name": "",
          "author_url": "",
          "post_date": "2020-01-28T00:35:43.240000",
          "content": "",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 3455513,
      "author_name": "",
      "author_url": "",
      "post_date": "2026-05-09T15:25:48.787000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 731829,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-29T05:56:25.900000",
      "content": "",
      "votes": 0,
      "replies": [
        {
          "id": 732215,
          "author_name": "",
          "author_url": "",
          "post_date": "2020-01-29T15:24:05.560000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 731801,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-29T04:40:24.670000",
      "content": "",
      "votes": 0,
      "replies": [
        {
          "id": 732214,
          "author_name": "",
          "author_url": "",
          "post_date": "2020-01-29T15:23:56.983000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 751327,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-02-20T05:58:04.840000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 732707,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-30T06:11:06.540000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 731868,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-29T06:49:21.770000",
      "content": "",
      "votes": 0,
      "replies": [
        {
          "id": 732216,
          "author_name": "",
          "author_url": "",
          "post_date": "2020-01-29T15:24:12.420000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 736519,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-02-04T09:43:54.930000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 733059,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-30T15:44:42.570000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 731859,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-01-29T06:27:23.977000",
      "content": "",
      "votes": 1,
      "replies": []
    }
  ],
  "comment_count": 58,
  "messages": [
    {
      "id": 730414,
      "postDate": "2020-01-27T13:19:21.023Z",
      "content": "<p>I'm sorry. It was a traditional Korean holidays until today, so I didn't have time to write this. Thank you for your patience.</p>\n\n<p>First of all, I would like to thank Booz Allen Hamilton for hosting this interesting competition. And congratulates to the all participants and especially the winners! </p>\n\n<p>I like deep neural networks so I prefer to solve all the problems with a deep neural networks. 😃 </p>\n\n<p>I focus on the structure of the input data rather than understanding the input data. And concentrate on making the model's input by avoiding missing information as much as possible, hoping that the model will do more than I expected. 😊 </p>\n\n<p>In other words, I focus <code>less</code> on feature engineering and <code>more</code> on finding a neural net model architecture that fits the data.</p>\n\n<h1>Interesting point</h1>\n\n<ul>\n<li>What's interesting is that using position-related information(especially position embedding) decreases local CV score.\n<ul><li>The performance of the BERT, ALBERT and GPT2 models was not good. (Because these models use position embedding)</li>\n<li>So I used the TRANSFORMER model without position embedding.</li></ul></li>\n</ul>\n\n<h1>Pre-processing</h1>\n\n<h3>Aggregation by game_session</h3>\n\n<p>The sequence of installation_id is too long to be used as it is. So I aggregated log data (train_df) by game_session. Please see the example below.\n<code>\ndf = train_df\nevent_code = pd.crosstab(df['game_session'], df['event_code'])\nevent_id = pd.crosstab(df['game_session'], df['event_id'])\n...\nagged_df = pd.concat([event_code, event_id, game_accuracy, max_round])\nsession_df = df.drop_duplicates('game_session', keep='last').reset_index(drop=True)\nsession_df = session_df.merge(agged_df, how='left', on='game_session')\n</code></p>\n\n<p>The LSTM and TRANSFORMER models in NLP receive sequence of words (or sentence) as input. Similarly, I will use the sequence of game_sessions (or installation_id) as input here. </p>\n\n<h1>Model</h1>\n\n<p>Best private score: 0.564\nSingle transformer model used.</p>\n\n<h3>TRANSFORMER MODEL BLOCK</h3>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1658108%2F6a4d5317015ad5235b526b46d1327fee%2Fdsb20192.png?generation=1582589525333424&amp;alt=media\" alt=\"\"></p>\n\n<p>Prediction from game_sessions of an installation_id</p>\n\n<h3>The key here is how to create embedding from the game_session.</h3>\n\n<p><code>Categorical columns</code> (such as event_code, title, world, etc...) were embedded respectively. Then, the categorical_vector were obtained by concatenating the embeddings. Next the nn.linear layer is applied for the dimension reduction of the categorical vector.\n<code>\nself.categorical_proj = nn.Sequential(\n            nn.Linear(cfg.emb_size*num_categorical_columns, cfg.hidden_size//2),\n            nn.LayerNorm(cfg.hidden_size//2),\n        ) <br>\n</code></p>\n\n<p><code>Continuous columns</code> were embedded directly using a linear layer.\n<code>\nself.continuous_emb = nn.Sequential( <br>\n            nn.Linear(num_continuous_columns, cfg.hidden_size//2),\n            nn.LayerNorm(cfg.hidden_size//2),\n        )\n</code>\n* I used np.log1p for normalization of continuous columns.</p>\n\n<h3>hyper parameters</h3>\n\n<ul>\n<li>optimizer: AdamW</li>\n<li>schedular: WarmupLinearSchedule</li>\n<li>learning_rate: 1e-04</li>\n<li>dropout: 0.2</li>\n<li>number of layers : 2</li>\n<li>embedding_size: 100</li>\n<li>hidden_size: 500</li>\n</ul>\n\n<h1>Modified loss function</h1>\n\n<p><a href=\"https://www.kaggle.com/c/data-science-bowl-2019/discussion/124836\">https://www.kaggle.com/c/data-science-bowl-2019/discussion/124836</a>\nAs mentioned in this link, the 0 and 3 classes of the accuracy_group may be very close. \nnum_correct can have 0 or 1, if the num_correct has 1 then the accuracy_group increases 3 points.\nOn the other hand, num_incorrect decreases 1 point when num_incorrect has 1 and decreases 2 points when num_incorrect has 2 or more.</p>\n\n<p>This could be expressed as \n```</p>\n\n<h1>num_incorrect[num_incorrect &gt; 2 ] = 2 # Constrained not to exceed 2.</h1>\n\n<p>new_accuracy_group = 3 * num_correct - num_incorrect\n```</p>\n\n<p>Using the above equation, we can calculate the real values of 0 to 3 from num_correct, num_incorrect.\nTherefore, the prediction of the model is set to [num_correct_pred, num_incorrect_pred]</p>\n\n<p>```\nprediction = model(x)  # prediction = [num_correct_pred, num_incorrect_pred]</p>\n\n<h1>target = [num_correct; num_incorrect]</h1>\n\n<p><code>\n**Then train the model with the modified_loss below.**\n</code>\nmodified_loss = mse_loss( prediction, target )\n```</p>\n\n<p>After the training is done, we can use the new_accuracy_group calculated from \"num_correct_pred, num_incorrect_pred\".\n<code>\nnum_correct_pred, num_incorrect_pred = prediction\nnew_accuracy_group = 3 * num_correct_pred - num_incorrect_pred\n</code></p>\n\n<p>We can also use original accuracy_group to slightly improve performance.\n```\nprediction = model(x)  # prediction = [accuracy_group_pred, num_correct_pred, num_incorrect_pred]</p>\n\n<h1>target = [accuracy_group; num_correct; num_incorrect]</h1>\n\n<p>```</p>\n\n<p><strong>The final_accuracy_group is calculated as below.</strong>\n<code>\nnew_accuracy_group = 3 * num_correct_pred - num_incorrect_pred\nfinal_accuracy_group = (accuracy_group_pred + new_accuracy_group) / 2\n</code></p>\n\n<h1>Additional training data generation</h1>\n\n<p>I generated an additional label for game_sessions, where the type is <strong>Game</strong>. From the \"correct\":true, “correct”:false of event_data, I was able to create num_correct and num_incorrect, and likewise I was able to create an accuracy_group.\nThe number of additional training samples generated is 41,194.</p>\n\nPre-training and fine-tuning steps\n\n<ul>\n<li>Pre-training step - up to 3 epoch, the model was trained with the original labels + additional labels.</li>\n<li>Fine-tuning step - from 4 epoch, the model was trained with the original labels.</li>\n</ul>\n\n<h1>Data Augmentation</h1>\n\n<ul>\n<li>training time augmentation - For installation_id with more than 30 game_sessions, up to 50% were randomly removed in the old order.</li>\n<li>test time augmentation - For installation_id with more than 30 game_sessions, up to 60% were randomly removed in the old order.</li>\n</ul>\n\n<h2>Link to kernel</h2>\n\n<p><a href=\"https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615\">https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615</a></p>\n\n<p>It is a shame to me sharing the uncleane code. But first I decided to share the kernel and make a clean code. Maybe in two weeks? ;)</p>\n\n<ul>\n<li>The training code is also released. I'm sorry it's still unclean code.\n<a href=\"https://github.com/lime-robot/dsb2019\">https://github.com/lime-robot/dsb2019</a></li>\n</ul>",
      "rawMarkdown": "I'm sorry. It was a traditional Korean holidays until today, so I didn't have time to write this. Thank you for your patience.\n\nFirst of all, I would like to thank Booz Allen Hamilton for hosting this interesting competition. And congratulates to the all participants and especially the winners! \n\nI like deep neural networks so I prefer to solve all the problems with a deep neural networks. 😃 \n\nI focus on the structure of the input data rather than understanding the input data. And concentrate on making the model's input by avoiding missing information as much as possible, hoping that the model will do more than I expected. 😊 \n\nIn other words, I focus `less` on feature engineering and `more` on finding a neural net model architecture that fits the data.\n\n\n# Interesting point\n- What's interesting is that using position-related information(especially position embedding) decreases local CV score.\n\t- The performance of the BERT, ALBERT and GPT2 models was not good. (Because these models use position embedding)\n\t- So I used the TRANSFORMER model without position embedding.\n\n# Pre-processing\n\n### Aggregation by game_session\n\nThe sequence of installation\\_id is too long to be used as it is. So I aggregated log data (train\\_df) by game_session. Please see the example below.\n```\ndf = train_df\nevent_code = pd.crosstab(df['game_session'], df['event_code'])\nevent_id = pd.crosstab(df['game_session'], df['event_id'])\n...\nagged_df = pd.concat([event_code, event_id, game_accuracy, max_round])\nsession_df = df.drop_duplicates('game_session', keep='last').reset_index(drop=True)\nsession_df = session_df.merge(agged_df, how='left', on='game_session')\n```\n\nThe LSTM and TRANSFORMER models in NLP receive sequence of words (or sentence) as input. Similarly, I will use the sequence of game\\_sessions (or installation\\_id) as input here. \n\n\n# Model\n\nBest private score: 0.564\nSingle transformer model used.\n\n### TRANSFORMER MODEL BLOCK\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1658108%2F6a4d5317015ad5235b526b46d1327fee%2Fdsb20192.png?generation=1582589525333424&amp;alt=media)\n\n\nPrediction from game\\_sessions of an installation\\_id\n\n### The key here is how to create embedding from the game_session.\n\n`Categorical columns` (such as event\\_code, title, world, etc...) were embedded respectively. Then, the categorical_vector were obtained by concatenating the embeddings. Next the nn.linear layer is applied for the dimension reduction of the categorical vector.\n```\nself.categorical_proj = nn.Sequential(\n            nn.Linear(cfg.emb_size*num_categorical_columns, cfg.hidden_size//2),\n            nn.LayerNorm(cfg.hidden_size//2),\n        )  \n```\n\n`Continuous columns` were embedded directly using a linear layer.\n```\nself.continuous_emb = nn.Sequential(                \n            nn.Linear(num_continuous_columns, cfg.hidden_size//2),\n            nn.LayerNorm(cfg.hidden_size//2),\n        )\n```\n* I used np.log1p for normalization of continuous columns.\n\n### hyper parameters\n- optimizer: AdamW\n- schedular: WarmupLinearSchedule\n- learning_rate: 1e-04\n- dropout: 0.2\n- number of layers : 2\n- embedding_size: 100\n- hidden_size: 500\n\n\n\n\n# Modified loss function\n\nhttps://www.kaggle.com/c/data-science-bowl-2019/discussion/124836\nAs mentioned in this link, the 0 and 3 classes of the accuracy_group may be very close. \nnum\\_correct can have 0 or 1, if the num\\_correct has 1 then the accuracy\\_group increases 3 points.\nOn the other hand, num\\_incorrect decreases 1 point when num\\_incorrect has 1 and decreases 2 points when num\\_incorrect has 2 or more.\n\nThis could be expressed as \n```\n# num_incorrect[num_incorrect &gt; 2 ] = 2 # Constrained not to exceed 2.\nnew_accuracy_group = 3 * num_correct - num_incorrect\n```\n\nUsing the above equation, we can calculate the real values of 0 to 3 from num\\_correct, num\\_incorrect.\nTherefore, the prediction of the model is set to [num\\_correct\\_pred, num\\_incorrect\\_pred]\n\n```\nprediction = model(x)  # prediction = [num_correct_pred, num_incorrect_pred]\n# target = [num_correct; num_incorrect]\n```\n**Then train the model with the modified_loss below.**\n```\nmodified_loss = mse_loss( prediction, target )\n```\n\nAfter the training is done, we can use the new_accuracy\\_group calculated from \"num\\_correct\\_pred, num\\_incorrect\\_pred\".\n```\nnum_correct_pred, num_incorrect_pred = prediction\nnew_accuracy_group = 3 * num_correct_pred - num_incorrect_pred\n```\n\nWe can also use original accuracy\\_group to slightly improve performance.\n```\nprediction = model(x)  # prediction = [accuracy_group_pred, num_correct_pred, num_incorrect_pred]\n# target = [accuracy_group; num_correct; num_incorrect]\n```\n\n**The final\\_accuracy\\_group is calculated as below.**\n```\nnew_accuracy_group = 3 * num_correct_pred - num_incorrect_pred\nfinal_accuracy_group = (accuracy_group_pred + new_accuracy_group) / 2\n```\n\n\n# Additional training data generation\n\nI generated an additional label for game\\_sessions, where the type is **Game**. From the \"correct\":true, “correct”:false of event\\_data, I was able to create num\\_correct and num\\_incorrect, and likewise I was able to create an accuracy_group.\nThe number of additional training samples generated is 41,194.\n\n#### Pre-training and fine-tuning steps\n- Pre-training step - up to 3 epoch, the model was trained with the original labels + additional labels.\n- Fine-tuning step - from 4 epoch, the model was trained with the original labels.\n\n\n# Data Augmentation\n- training time augmentation - For installation\\_id with more than 30 game_sessions, up to 50% were randomly removed in the old order.\n- test time augmentation - For installation\\_id with more than 30 game_sessions, up to 60% were randomly removed in the old order.\n\n\n## Link to kernel\nhttps://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615\n\nIt is a shame to me sharing the uncleane code. But first I decided to share the kernel and make a clean code. Maybe in two weeks? ;)\n\n- The training code is also released. I'm sorry it's still unclean code.\nhttps://github.com/lime-robot/dsb2019",
      "votes": 155
    },
    {
      "id": 731908,
      "postDate": "2020-01-29T08:11:56.877Z",
      "content": "<p>It is a shame to me sharing the uncleane code. \nBut first I decided to share the kernel and make a clean code. Maybe in two weeks?\n<a href=\"https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615\">https://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615</a></p>",
      "rawMarkdown": "It is a shame to me sharing the uncleane code. \nBut first I decided to share the kernel and make a clean code. Maybe in two weeks?\nhttps://www.kaggle.com/limerobot/dsb2019-v77-tr-dt-aug0-5-3tta?scriptVersionId=27448615",
      "votes": 5,
      "replies": [
        {
          "id": 731937,
          "postDate": "2020-01-29T09:17:52.630Z",
          "content": "<p>Thank you so much. I’m sorry for creating the extra work.</p>",
          "rawMarkdown": "Thank you so much. I’m sorry for creating the extra work.",
          "votes": 1
        },
        {
          "id": 732212,
          "postDate": "2020-01-29T15:22:09.887Z",
          "content": "<p>It's ok 😂 </p>",
          "rawMarkdown": "It's ok 😂 ",
          "votes": 1
        }
      ]
    },
    {
      "id": 732690,
      "postDate": "2020-01-30T05:39:07.343Z",
      "content": "<p>Great job. Thanks for sharing!</p>",
      "rawMarkdown": "Great job. Thanks for sharing!",
      "votes": 2,
      "replies": [
        {
          "id": 732692,
          "postDate": "2020-01-30T05:42:49.400Z",
          "content": "<p>*YEAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<strong>💪 👎 👎 *</strong></p>",
          "rawMarkdown": "*YEAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!**💪 👎 👎 ***"
        }
      ]
    },
    {
      "id": 731558,
      "postDate": "2020-01-28T19:33:18.833Z",
      "content": "<p><a href=\"/limerobot\">@limerobot</a>, congratulations and thanks for the interesting writeup!  This was my first Kaggle competition and I invested a ton of time on it.  Very frustrating that we had kernels that would have been solid silver but we ended up just missing Bronze.  I had an idea for and LSTM using train summarized by session but we didnt quite get it working.  I'd really like to understand all the details of how you manipulated the data and built your model.  Might you share the code?</p>",
      "rawMarkdown": "@limerobot, congratulations and thanks for the interesting writeup!  This was my first Kaggle competition and I invested a ton of time on it.  Very frustrating that we had kernels that would have been solid silver but we ended up just missing Bronze.  I had an idea for and LSTM using train summarized by session but we didnt quite get it working.  I'd really like to understand all the details of how you manipulated the data and built your model.  Might you share the code?",
      "votes": 2,
      "replies": [
        {
          "id": 731727,
          "postDate": "2020-01-29T01:04:35.370Z",
          "content": "<p>Please check your e-mail 😃</p>",
          "rawMarkdown": "Please check your e-mail 😃",
          "votes": 2
        },
        {
          "id": 731840,
          "postDate": "2020-01-29T06:08:36.617Z",
          "content": "<p>Many thanks!  So much to learn!!!  😊 </p>",
          "rawMarkdown": "Many thanks!  So much to learn!!!  😊 "
        }
      ]
    },
    {
      "id": 731500,
      "postDate": "2020-01-28T17:56:49.867Z",
      "content": "<p><a href=\"/limerobot\">@limerobot</a> Great Solution and Congrats on winning. Can you share your kernel please? I want to give a try to your approach and expecting a lot to learn from your solution.</p>",
      "rawMarkdown": "@limerobot Great Solution and Congrats on winning. Can you share your kernel please? I want to give a try to your approach and expecting a lot to learn from your solution.",
      "votes": 2,
      "replies": [
        {
          "id": 731728,
          "postDate": "2020-01-29T01:04:42.010Z",
          "content": "<p>Please check your e-mail 😃</p>",
          "rawMarkdown": "Please check your e-mail 😃",
          "votes": 3
        },
        {
          "id": 731961,
          "postDate": "2020-01-29T09:53:45.893Z",
          "content": "<p><a href=\"/limerobot\">@limerobot</a> Could you share your kernel with me too ? I want to compare my model with yours.</p>\n\n<p>EDIT: Sorry, I've missed the link. Thank you for sharing !!</p>",
          "rawMarkdown": "@limerobot Could you share your kernel with me too ? I want to compare my model with yours.\n\nEDIT: Sorry, I've missed the link. Thank you for sharing !!",
          "votes": 1
        },
        {
          "id": 731998,
          "postDate": "2020-01-29T11:10:31.620Z",
          "content": "<p>Thanks <a href=\"/limerobot\">@limerobot</a> </p>",
          "rawMarkdown": "Thanks @limerobot "
        }
      ]
    },
    {
      "id": 1058685,
      "postDate": "2020-10-24T05:20:21.173Z",
      "content": "<p>Could you please share your kernel..</p>",
      "rawMarkdown": "Could you please share your kernel..",
      "votes": 1
    },
    {
      "id": 754013,
      "postDate": "2020-02-22T23:23:08.630Z",
      "content": "<p>Great solution, and thanks for sharing the code and write-up. </p>\n\n<p>I'm just curious about one thing. The goal of the competition was to \"Uncover the factors to help measure how young children learn\". With something like a decision tree we can quite easily have an idea about the most important factors, but with a Transformer model (or nn in general) that seems to be a lot harder. </p>\n\n<p>How do you think your model could be used to identify the best learning patterns in children? Do you think it's better to have a less accurate but more readable model for the use case of the competition organisers?</p>\n\n<p>Would be great to hear your thoughts!</p>",
      "rawMarkdown": "Great solution, and thanks for sharing the code and write-up. \n\nI'm just curious about one thing. The goal of the competition was to \"Uncover the factors to help measure how young children learn\". With something like a decision tree we can quite easily have an idea about the most important factors, but with a Transformer model (or nn in general) that seems to be a lot harder. \n\nHow do you think your model could be used to identify the best learning patterns in children? Do you think it's better to have a less accurate but more readable model for the use case of the competition organisers?\n\nWould be great to hear your thoughts!",
      "votes": 1,
      "replies": [
        {
          "id": 772339,
          "postDate": "2020-03-15T11:28:33.580Z",
          "content": "<p><a href=\"/jyesawtellrickson\">@jyesawtellrickson</a>  I'm really sorry for late reply. Please consider using notifications(@) to me. 🐱 </p>\n\n<p>I think the results of various models will help competition organisers.</p>\n\n<p>For example, the fact that performance has decreased when sequential information is used can help clarify the relationship between random path and linear progression.\nBelow is what competition organiser mentioned.</p>\n\n<p><a href=\"https://www.kaggle.com/c/data-science-bowl-2019/discussion/115034\">https://www.kaggle.com/c/data-science-bowl-2019/discussion/115034</a></p>\n\n<blockquote>\n  <p>The app is designed to try to guide the kids through an idealized learning path, which is intended to present players with a pattern of exposure-&gt;exploration-&gt;practice-&gt;demonstration (as in demonstration of knowledge). Each of the worlds in the app may have one or more such sequences of media objects, and sometimes the app does not follow this exact formula. </p>\n  \n  <p><code>However, kids are not required to follow the path that is laid out for them, and whether the suggested linear progression leads to better learning outcomes than a random path is not yet clear.</code>  Perhaps this competition will give us some insights into this question as well!</p>\n</blockquote>",
          "rawMarkdown": "@jyesawtellrickson  I'm really sorry for late reply. Please consider using notifications(@) to me. 🐱 \n\nI think the results of various models will help competition organisers.\n\nFor example, the fact that performance has decreased when sequential information is used can help clarify the relationship between random path and linear progression.\nBelow is what competition organiser mentioned.\n\nhttps://www.kaggle.com/c/data-science-bowl-2019/discussion/115034\n\n&gt; The app is designed to try to guide the kids through an idealized learning path, which is intended to present players with a pattern of exposure-&gt;exploration-&gt;practice-&gt;demonstration (as in demonstration of knowledge). Each of the worlds in the app may have one or more such sequences of media objects, and sometimes the app does not follow this exact formula. \n\n&gt; `However, kids are not required to follow the path that is laid out for them, and whether the suggested linear progression leads to better learning outcomes than a random path is not yet clear.`  Perhaps this competition will give us some insights into this question as well!\n\n",
          "votes": 1
        }
      ]
    },
    {
      "id": 741660,
      "postDate": "2020-02-10T21:34:51.520Z",
      "content": "<p>So much great ideas. And I should get better at applying transformers. Thanks for sharing the insights and the kernel! </p>",
      "rawMarkdown": "So much great ideas. And I should get better at applying transformers. Thanks for sharing the insights and the kernel! ",
      "votes": 1
    },
    {
      "id": 737144,
      "postDate": "2020-02-05T00:48:49.720Z",
      "content": "<p>Congratz and thanks for the big sharing! It is super helpful for learning! 👍  🤘 </p>",
      "rawMarkdown": "Congratz and thanks for the big sharing! It is super helpful for learning! 👍  🤘 ",
      "votes": 1
    },
    {
      "id": 733698,
      "postDate": "2020-01-31T12:47:46.153Z",
      "content": "<p>Nice work</p>",
      "rawMarkdown": "Nice work",
      "votes": 1
    },
    {
      "id": 733639,
      "postDate": "2020-01-31T11:30:18.540Z",
      "content": "<p>what is transformer? i dont know that. can you describe some? </p>",
      "rawMarkdown": "what is transformer? i dont know that. can you describe some? ",
      "votes": 1,
      "replies": [
        {
          "id": 772342,
          "postDate": "2020-03-15T11:33:21.797Z",
          "content": "<p>Please refer to the \"Attention Is All You Need\" paper or a well-organized blog on the Internet. 😃 \nI think that's a better way.</p>",
          "rawMarkdown": "Please refer to the \"Attention Is All You Need\" paper or a well-organized blog on the Internet. 😃 \nI think that's a better way."
        }
      ]
    },
    {
      "id": 733511,
      "postDate": "2020-01-31T08:35:49.117Z",
      "content": "<p>very impressive!!</p>",
      "rawMarkdown": "very impressive!!",
      "votes": 1
    },
    {
      "id": 733462,
      "postDate": "2020-01-31T06:47:32.763Z",
      "content": "<p>Great Job Buddy </p>",
      "rawMarkdown": "Great Job Buddy ",
      "votes": 1
    },
    {
      "id": 733317,
      "postDate": "2020-01-31T00:28:39.570Z",
      "content": "<p>very interesting kernel.</p>",
      "rawMarkdown": "very interesting kernel.",
      "votes": 1
    },
    {
      "id": 733138,
      "postDate": "2020-01-30T18:09:16.540Z",
      "content": "<p>Congrats Limerobot. Very good impressive work with a single model. Appreciate if you can also point us to your training kernel and code.  Many thanks.</p>",
      "rawMarkdown": "Congrats Limerobot. Very good impressive work with a single model. Appreciate if you can also point us to your training kernel and code.  Many thanks.",
      "votes": 1
    },
    {
      "id": 732670,
      "postDate": "2020-01-30T04:42:15.660Z",
      "content": "<p>it's very interesting and great kernal its very useful for learning purpose. thanks for sharing </p>",
      "rawMarkdown": "it's very interesting and great kernal its very useful for learning purpose. thanks for sharing ",
      "votes": 1
    },
    {
      "id": 732566,
      "postDate": "2020-01-30T00:13:03.790Z",
      "content": "<p>Interesting approach. Congrats!</p>",
      "rawMarkdown": "Interesting approach. Congrats!",
      "votes": 1
    },
    {
      "id": 732295,
      "postDate": "2020-01-29T16:39:04.940Z",
      "content": "<p>Congrats &amp; Thanks for sharing!!🎉 😄 👍 </p>",
      "rawMarkdown": "Congrats &amp; Thanks for sharing!!🎉 😄 👍 ",
      "votes": 1
    },
    {
      "id": 732232,
      "postDate": "2020-01-29T15:43:13.933Z",
      "content": "<p>Great job. Really helpful. Thanks for sharing.</p>",
      "rawMarkdown": "Great job. Really helpful. Thanks for sharing.",
      "votes": 1
    },
    {
      "id": 732222,
      "postDate": "2020-01-29T15:32:23.920Z",
      "content": "<p>It's a really beautiful write-up. Thank you for sharing !</p>",
      "rawMarkdown": "It's a really beautiful write-up. Thank you for sharing !",
      "votes": 1
    },
    {
      "id": 732009,
      "postDate": "2020-01-29T11:30:20.637Z",
      "content": "<p>very helpful :)</p>",
      "rawMarkdown": "very helpful :)",
      "votes": 1
    },
    {
      "id": 731989,
      "postDate": "2020-01-29T10:43:42.053Z",
      "content": "<p>This is a very good explanation, looking forward to the clean code release!</p>",
      "rawMarkdown": "This is a very good explanation, looking forward to the clean code release!",
      "votes": 1
    },
    {
      "id": 731979,
      "postDate": "2020-01-29T10:26:49.573Z",
      "content": "<p>Dang, 3d place with just 1 model and relatively little FE? Neat! \n(It's interesting to see how Attention models worked well for some and not others. How much worse was your model with the PE?).</p>",
      "rawMarkdown": "Dang, 3d place with just 1 model and relatively little FE? Neat! \n(It's interesting to see how Attention models worked well for some and not others. How much worse was your model with the PE?).",
      "votes": 1,
      "replies": [
        {
          "id": 732219,
          "postDate": "2020-01-29T15:29:18.027Z",
          "content": "<p>I remember with PE decreased the local CV score about 0.02~0.03</p>",
          "rawMarkdown": "I remember with PE decreased the local CV score about 0.02~0.03"
        }
      ]
    },
    {
      "id": 731909,
      "postDate": "2020-01-29T08:14:36.767Z",
      "content": "<p>Congrats on winning the competition and thank you for sharing the approach!! \nCould you share your code please? </p>",
      "rawMarkdown": "Congrats on winning the competition and thank you for sharing the approach!! \nCould you share your code please? ",
      "votes": 1,
      "replies": [
        {
          "id": 732217,
          "postDate": "2020-01-29T15:24:24.443Z",
          "content": "<p>Please see the link above 😃 </p>",
          "rawMarkdown": "Please see the link above 😃 "
        }
      ]
    },
    {
      "id": 731028,
      "postDate": "2020-01-28T09:18:34.020Z",
      "content": "<p>Thank you for sharing !\nHow did you aggregate the output of Transformer ? Are the numbers of <code>game_session</code> different for each installation_id ?</p>",
      "rawMarkdown": "Thank you for sharing !\nHow did you aggregate the output of Transformer ? Are the numbers of `game_session` different for each installation_id ?",
      "votes": 1,
      "replies": [
        {
          "id": 731156,
          "postDate": "2020-01-28T12:09:13.200Z",
          "content": "<p>Yep, installation_id is a variable-length sequence.\nSo I set the sequence length to 100 and I added PAD tokens to the front in the case of a short sequence. Then like the figure above, I took the last output of the sequence.</p>",
          "rawMarkdown": "Yep, installation_id is a variable-length sequence.\nSo I set the sequence length to 100 and I added PAD tokens to the front in the case of a short sequence. Then like the figure above, I took the last output of the sequence.",
          "votes": 1
        }
      ]
    },
    {
      "id": 730885,
      "postDate": "2020-01-28T04:03:51.453Z",
      "content": "<p>Very impressive!!! Thanks for sharing your solution.</p>",
      "rawMarkdown": "Very impressive!!! Thanks for sharing your solution.",
      "votes": 1
    },
    {
      "id": 730884,
      "postDate": "2020-01-28T03:59:26.780Z",
      "content": "<p>Thank you for sharing! I should learn this! ;-) Congratulations!</p>",
      "rawMarkdown": "Thank you for sharing! I should learn this! ;-) Congratulations!",
      "votes": 1
    },
    {
      "id": 730835,
      "postDate": "2020-01-28T02:01:00.640Z",
      "content": "<p><a href=\"/limerobot\">@limerobot</a>  Great solution! May I ask would you share your kernel? I want to try to blend your method with mine and see the effect. </p>",
      "rawMarkdown": "@limerobot  Great solution! May I ask would you share your kernel? I want to try to blend your method with mine and see the effect. ",
      "votes": 1,
      "replies": [
        {
          "id": 731143,
          "postDate": "2020-01-28T11:55:20.873Z",
          "content": "<p>Please check your e-mail 😃 </p>",
          "rawMarkdown": "Please check your e-mail 😃 ",
          "votes": 1
        },
        {
          "id": 731851,
          "postDate": "2020-01-29T06:16:59.333Z",
          "content": "<p>Thanks. I will do that in 2 weeks and let you know the result. </p>",
          "rawMarkdown": "Thanks. I will do that in 2 weeks and let you know the result. ",
          "votes": 1
        }
      ]
    },
    {
      "id": 730825,
      "postDate": "2020-01-28T01:39:23.410Z",
      "content": "<p>Amazing work. Congrats on 3rd place and GM status - you earned it. </p>",
      "rawMarkdown": "Amazing work. Congrats on 3rd place and GM status - you earned it. ",
      "votes": 1
    },
    {
      "id": 730578,
      "postDate": "2020-01-27T16:44:44.783Z",
      "content": "<p>Great job. I was curious about your solution. Thanks for sharing.</p>",
      "rawMarkdown": "Great job. I was curious about your solution. Thanks for sharing.",
      "votes": 1
    },
    {
      "id": 730430,
      "postDate": "2020-01-27T13:30:50.150Z",
      "content": "<p>Congrats!  Very impressive job.  Curious how many heads did the Transformer layers have?\nI also found that adding positional encodings made the transformer worse.  I did add in game time and seconds elapsed (from first event to last event for installation_id) though so it had some sense of timing.  Also curious exactly what features you used?  Thanks.</p>",
      "rawMarkdown": "Congrats!  Very impressive job.  Curious how many heads did the Transformer layers have?\nI also found that adding positional encodings made the transformer worse.  I did add in game time and seconds elapsed (from first event to last event for installation_id) though so it had some sense of timing.  Also curious exactly what features you used?  Thanks.",
      "votes": 1,
      "replies": [
        {
          "id": 730814,
          "postDate": "2020-01-28T00:35:43.240Z",
          "content": "<p>Only one head was used.\n<code>\ndef get_reg():\n    return nn.Sequential(\n            nn.Linear(cfg.hidden_size, cfg.hidden_size),\n            nn.LayerNorm(cfg.hidden_size),\n            nn.Dropout(cfg.dropout),\n            nn.ReLU(),\n            nn.Linear(cfg.hidden_size, cfg.hidden_size),\n            nn.LayerNorm(cfg.hidden_size),\n            nn.Dropout(cfg.dropout),\n            nn.ReLU(),\n            nn.Linear(cfg.hidden_size, cfg.target_size), <br>\n    ) <br>\nself.reg_layer = get_reg()\n</code>\nI didn't consider <code>seconds elapsed</code> 😂 ;  it looks like a good feature.</p>\n\n<p>The features I used are \nCategorical columns = ['title', 'type', 'world']\nContinuous columns = ['event_count', 'game_time', 'max_game_time']</p>\n\n<p>The rest columns you can see the agged_df I mentioned above. 😊 </p>",
          "rawMarkdown": "Only one head was used.\n```\ndef get_reg():\n    return nn.Sequential(\n            nn.Linear(cfg.hidden_size, cfg.hidden_size),\n            nn.LayerNorm(cfg.hidden_size),\n            nn.Dropout(cfg.dropout),\n            nn.ReLU(),\n            nn.Linear(cfg.hidden_size, cfg.hidden_size),\n            nn.LayerNorm(cfg.hidden_size),\n            nn.Dropout(cfg.dropout),\n            nn.ReLU(),\n            nn.Linear(cfg.hidden_size, cfg.target_size),            \n    )        \nself.reg_layer = get_reg()\n```\nI didn't consider `seconds elapsed` 😂 ;  it looks like a good feature.\n\nThe features I used are \nCategorical columns = ['title', 'type', 'world']\nContinuous columns = ['event\\_count', 'game\\_time', 'max\\_game_time']\n\nThe rest columns you can see the agged\\_df I mentioned above. 😊 ",
          "votes": 2
        }
      ]
    },
    {
      "id": 3455513,
      "postDate": "2026-05-09T15:25:48.787Z",
      "content": "<p>I learned a lot from here. Thanks!</p>",
      "rawMarkdown": " I learned a lot from here. Thanks!"
    },
    {
      "id": 731829,
      "postDate": "2020-01-29T05:56:25.900Z",
      "content": "<p><a href=\"/limerobot\">@limerobot</a> Congratulations for this Post and your achievement. Most of the top result posts mostly discussed about Feature Engineering. But your post explained less about feature engineering and more about Model building(NN). Since I started to NN, I would like to know your way of handling the features and how you built the NN Model with Transformers. Please share the Notebook link for my learning.</p>",
      "rawMarkdown": "@limerobot Congratulations for this Post and your achievement. Most of the top result posts mostly discussed about Feature Engineering. But your post explained less about feature engineering and more about Model building(NN). Since I started to NN, I would like to know your way of handling the features and how you built the NN Model with Transformers. Please share the Notebook link for my learning.",
      "replies": [
        {
          "id": 732215,
          "postDate": "2020-01-29T15:24:05.560Z",
          "content": "<p>Please see the link above 😃 </p>",
          "rawMarkdown": "Please see the link above 😃 "
        }
      ]
    },
    {
      "id": 731801,
      "postDate": "2020-01-29T04:40:24.670Z",
      "content": "<p><a href=\"/limerobot\">@limerobot</a> Congrats for winning the prize and thanks for great summary!!!\nI had been competing in this competition for two months. My solution is based on LGB and XGB. I found it is very important for Boosting models to feed features which describe what game did an user played before the assessment (time-series features.) Therefore, if I had have enough experiences, I would have built attention-base model/LSTM. \nDuring competition, you were stepping up in LB day by day even though you joined this comp late (I think you said so in discussion), and I was really waiting your solution. After reading your summary, I am getting really curious about how you implemented in actual coding. If possible, could I read your code? I am summarizing my solution and share it in near future (<a href=\"https://github.com/yuooka/DSB2019-104th\">under construction</a>).</p>",
      "rawMarkdown": "@limerobot Congrats for winning the prize and thanks for great summary!!!\nI had been competing in this competition for two months. My solution is based on LGB and XGB. I found it is very important for Boosting models to feed features which describe what game did an user played before the assessment (time-series features.) Therefore, if I had have enough experiences, I would have built attention-base model/LSTM. \nDuring competition, you were stepping up in LB day by day even though you joined this comp late (I think you said so in discussion), and I was really waiting your solution. After reading your summary, I am getting really curious about how you implemented in actual coding. If possible, could I read your code? I am summarizing my solution and share it in near future ([under construction](https://github.com/yuooka/DSB2019-104th)).",
      "replies": [
        {
          "id": 732214,
          "postDate": "2020-01-29T15:23:56.983Z",
          "content": "<p>Please see the link above 😃 </p>",
          "rawMarkdown": "Please see the link above 😃 "
        }
      ]
    },
    {
      "id": 751327,
      "postDate": "2020-02-20T05:58:04.840Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 732707,
      "postDate": "2020-01-30T06:11:06.540Z",
      "rawMarkdown": "",
      "votes": 1,
      "isDeleted": true
    },
    {
      "id": 731868,
      "postDate": "2020-01-29T06:49:21.770Z",
      "rawMarkdown": "",
      "isDeleted": true,
      "replies": [
        {
          "id": 732216,
          "postDate": "2020-01-29T15:24:12.420Z",
          "content": "<p>Please see the link above 😃 </p>",
          "rawMarkdown": "Please see the link above 😃 "
        }
      ]
    },
    {
      "id": 736519,
      "postDate": "2020-02-04T09:43:54.930Z",
      "content": "<p>Congrats and thanks for sharing!</p>",
      "rawMarkdown": "Congrats and thanks for sharing!",
      "votes": 1
    },
    {
      "id": 733059,
      "postDate": "2020-01-30T15:44:42.570Z",
      "content": "<p>Really interesting. Thank you !</p>",
      "rawMarkdown": "Really interesting. Thank you !",
      "votes": 1
    },
    {
      "id": 731859,
      "postDate": "2020-01-29T06:27:23.977Z",
      "content": "<p>Thanks for this blog, Really helpful 😃 </p>",
      "rawMarkdown": "Thanks for this blog, Really helpful 😃 ",
      "votes": 1
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-23T23:50:50Z",
  "competition_id": 16531,
  "competition_slug": "data-science-bowl-2019",
  "team_id": 3957064,
  "solution_url": "/competitions/data-science-bowl-2019/writeups/limerobot-3rd-solution-single-transformer-model-li"
}