{
  "id": 129885,
  "title": "47th place solution",
  "content": "<p>Thank you for Google as a host and Kaggle team! I really learned many NLP technics especially BERT form this competition.</p>\n\n<h1>Key point of final model</h1>\n\n<ul>\n<li>Use first and last part of text if length exceed max_seq_length</li>\n<li>Averaging 4 BERT base-uncased model</li>\n<li>Postprocessing: Fit target distribution with train data (a part of target columns)\n<ul><li>Detail is in below.</li></ul></li>\n<li>Concatenate pool_output &amp; sequence_output from bert_layer for GlobalAveragePooling1D</li>\n<li>10 fold with MultilabelStratifiedKFold (thanks <a href=\"/ratthachat\">@ratthachat</a> !)</li>\n<li>Strong heart for solo participation</li>\n</ul>\n\n<h1>Didn’t work for me</h1>\n\n<ul>\n<li>Pre-training with stackoverflow data (150,000 sentences)</li>\n<li>Multi sample dropout</li>\n<li>The other models\n<ul><li>Roberta</li>\n<li>Albert</li>\n<li>XLNet</li></ul></li>\n<li>Concatenate question only output &amp; answer only model </li>\n<li>Concatenate category MLP with BERT model</li>\n<li>LSTM head instead of Dense with BERT model</li>\n<li>Freeze half of BertLayer for reducing model complexity</li>\n<li>Skip half of BertLayer for reducing model complexity</li>\n<li>USE + MLP</li>\n<li>LSTM model with gensim embedding</li>\n<li>custom loss\n<ul><li>BCE &amp; MSE</li>\n<li>focal loss</li></ul></li>\n<li>Word count feature</li>\n<li>Concat title and question_body as a one block (removing [\"SEP\"] between them)</li>\n<li>Up-sampling for imbalance target column</li>\n</ul>\n\n<h1>My postprocessing class</h1>\n\n<p>```\nclass OptimPreds(object):\n    def <strong>init</strong>(self, df_train):\n        self.score_range_dict = {}\n        for i, c in enumerate(df_train.columns[11:]):\n            cnt = df_train[c].value_counts(normalize=True).sort_index()\n            self.score_range_dict[i] = [cnt.index.values.tolist(), cnt.values.tolist()]\n    def predict(self, preds, i):\n        return pd.cut(rank_average(preds), [-np.inf] + np.cumsum(self.score_range_dict[i][1])[:-1].tolist() + [np.inf], labels = self.score_range_dict[i][0])</p>\n\n<p>def optim_predict(pred, do_round=True, target=[ 2,  5,  7,  9, 11, 12, 13, 14, 15, 16, 19]):\n    for i in range(pred.shape[1]):\n        if i in target:\n            pred[:,i] = optim.predict(pred[:,i], i)\n    return pred\n```</p>",
  "comments": [
    {
      "id": 750199,
      "author_name": "guchio3",
      "author_url": "",
      "post_date": "2020-02-19T07:34:48.157000",
      "content": "<p><a href=\"/kenmatsu4\">@kenmatsu4</a> Thanks for sharing a great solution :D\nCan I ask you some questions?</p>\n\n<p>```\n1. &gt; Use first and last part of text if length exceed max_seq_length \nQ. How did you set the ratio for the first and last? (ex. 1 : 1, or 2 : 1 or etc …)  </p>\n\n<ol>\n<li><p>&gt; Averaging 4 BERT base-uncased model \nQ. What is the difference of the four models?  </p></li>\n<li><p>&gt; Fit target distribution with train data (a part of target columns) <br>\n Q. How did you choose the part of the target columns? Did you use oof?  </p></li>\n<li><p>&gt; Freeze half of BertLayer for reducing model complexity <br>\n Q. Which BertLayers did you freeze? <br>\n```  </p></li>\n</ol>\n\n<p>Thanks!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 750532,
          "author_name": "kenmatsu4",
          "author_url": "",
          "post_date": "2020-02-19T13:37:49.467000",
          "content": "<p>Thank you for your question, <a href=\"/guchio3\">@guchio3</a> !\nThe followings are my answer to your questions :D</p>\n\n<p><code>\n1. &gt; Use first and last part of text if length exceed max_seq_length\nQ. How did you set the ratio for the first and last? (ex. 1 : 1, or 2 : 1 or etc …) <br>\n</code></p>\n\n<p>-&gt; I tried various type of the ratio, however 1 : 1 was the best for me.</p>\n\n<p><code>\n2. &gt; Averaging 4 BERT base-uncased model\nQ. What is the difference of the four models?\n</code>\n-&gt; Used the models described as the following figure.\n￼<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F291723%2Fff85f6338fa415af7375021586f8704b%2F2020-02-19%2022.21.16.png?generation=1582119385493091&amp;alt=media\" alt=\"fig\"></p>\n\n<p><code>\n3. &gt; Fit target distribution with train data (a part of target columns)   Q. How did you choose the part of the target columns? Did you use oof? <br>\n</code>\n-&gt; Yes, I tried all of the columns and then, pick-up columns which has improvement with the post processing.</p>\n\n<p><code>\n4. &gt; Freeze half of BertLayer for reducing model complexity   Q. Which BertLayers did you freeze? <br>\n</code>\n-&gt; Set trainable as False for first half on the list of TFBertLayer class.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 750537,
          "author_name": "guchio3",
          "author_url": "",
          "post_date": "2020-02-19T13:42:28.427000",
          "content": "<p>Thank you for the quick and detailed answer.\nNow it's clear for me!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 742303,
      "author_name": "Ailurophile",
      "author_url": "",
      "post_date": "2020-02-11T08:17:10.937000",
      "content": "<p>Congratulations!\nThanks for Sharing your Approach &amp; Insights!! <a href=\"/kenmatsu4\">@kenmatsu4</a> </p>",
      "votes": 1,
      "replies": [
        {
          "id": 742345,
          "author_name": "kenmatsu4",
          "author_url": "",
          "post_date": "2020-02-11T08:47:19.600000",
          "content": "<p>Thanks!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 742186,
      "author_name": "Dracarys",
      "author_url": "",
      "post_date": "2020-02-11T06:13:20.450000",
      "content": "<p>You really did a great job, thanks for sharing.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 742341,
          "author_name": "kenmatsu4",
          "author_url": "",
          "post_date": "2020-02-11T08:46:23.430000",
          "content": "<p>Thanks!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 742278,
      "author_name": "Neuron Engineer",
      "author_url": "",
      "post_date": "2020-02-11T07:48:25.330000",
      "content": "<p>Let us continue our learning and exciting journey ! <a href=\"/kenmatsu4\">@kenmatsu4</a> </p>",
      "votes": 2,
      "replies": [
        {
          "id": 742343,
          "author_name": "kenmatsu4",
          "author_url": "",
          "post_date": "2020-02-11T08:47:11.823000",
          "content": "<p>Thanks ratthachat! Let's get gold medal next time!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    }
  ],
  "comment_count": 9,
  "messages": [
    {
      "id": 742168,
      "postDate": "2020-02-11T05:49:11.387Z",
      "content": "<p>Thank you for Google as a host and Kaggle team! I really learned many NLP technics especially BERT form this competition.</p>\n\n<h1>Key point of final model</h1>\n\n<ul>\n<li>Use first and last part of text if length exceed max_seq_length</li>\n<li>Averaging 4 BERT base-uncased model</li>\n<li>Postprocessing: Fit target distribution with train data (a part of target columns)\n<ul><li>Detail is in below.</li></ul></li>\n<li>Concatenate pool_output &amp; sequence_output from bert_layer for GlobalAveragePooling1D</li>\n<li>10 fold with MultilabelStratifiedKFold (thanks <a href=\"/ratthachat\">@ratthachat</a> !)</li>\n<li>Strong heart for solo participation</li>\n</ul>\n\n<h1>Didn’t work for me</h1>\n\n<ul>\n<li>Pre-training with stackoverflow data (150,000 sentences)</li>\n<li>Multi sample dropout</li>\n<li>The other models\n<ul><li>Roberta</li>\n<li>Albert</li>\n<li>XLNet</li></ul></li>\n<li>Concatenate question only output &amp; answer only model </li>\n<li>Concatenate category MLP with BERT model</li>\n<li>LSTM head instead of Dense with BERT model</li>\n<li>Freeze half of BertLayer for reducing model complexity</li>\n<li>Skip half of BertLayer for reducing model complexity</li>\n<li>USE + MLP</li>\n<li>LSTM model with gensim embedding</li>\n<li>custom loss\n<ul><li>BCE &amp; MSE</li>\n<li>focal loss</li></ul></li>\n<li>Word count feature</li>\n<li>Concat title and question_body as a one block (removing [\"SEP\"] between them)</li>\n<li>Up-sampling for imbalance target column</li>\n</ul>\n\n<h1>My postprocessing class</h1>\n\n<p>```\nclass OptimPreds(object):\n    def <strong>init</strong>(self, df_train):\n        self.score_range_dict = {}\n        for i, c in enumerate(df_train.columns[11:]):\n            cnt = df_train[c].value_counts(normalize=True).sort_index()\n            self.score_range_dict[i] = [cnt.index.values.tolist(), cnt.values.tolist()]\n    def predict(self, preds, i):\n        return pd.cut(rank_average(preds), [-np.inf] + np.cumsum(self.score_range_dict[i][1])[:-1].tolist() + [np.inf], labels = self.score_range_dict[i][0])</p>\n\n<p>def optim_predict(pred, do_round=True, target=[ 2,  5,  7,  9, 11, 12, 13, 14, 15, 16, 19]):\n    for i in range(pred.shape[1]):\n        if i in target:\n            pred[:,i] = optim.predict(pred[:,i], i)\n    return pred\n```</p>",
      "rawMarkdown": "Thank you for Google as a host and Kaggle team! I really learned many NLP technics especially BERT form this competition.\n\n# Key point of final model\n- Use first and last part of text if length exceed max\\_seq\\_length\n- Averaging 4 BERT base-uncased model\n- Postprocessing: Fit target distribution with train data (a part of target columns)\n   - Detail is in below.\n- Concatenate pool\\_output &amp; sequence\\_output from bert\\_layer for GlobalAveragePooling1D\n- 10 fold with MultilabelStratifiedKFold (thanks @ratthachat !)\n- Strong heart for solo participation\n\n# Didn’t work for me\n- Pre-training with stackoverflow data (150,000 sentences)\n- Multi sample dropout\n- The other models\n    - Roberta\n    - Albert\n    - XLNet\n- Concatenate question only output &amp; answer only model \n- Concatenate category MLP with BERT model\n- LSTM head instead of Dense with BERT model\n- Freeze half of BertLayer for reducing model complexity\n- Skip half of BertLayer for reducing model complexity\n- USE + MLP\n- LSTM model with gensim embedding\n- custom loss\n    - BCE &amp; MSE\n    - focal loss\n- Word count feature\n- Concat title and question\\_body as a one block (removing [\"SEP\"] between them)\n- Up-sampling for imbalance target column\n\n# My postprocessing class\n```\nclass OptimPreds(object):\n    def __init__(self, df_train):\n        self.score_range_dict = {}\n        for i, c in enumerate(df_train.columns[11:]):\n            cnt = df_train[c].value_counts(normalize=True).sort_index()\n            self.score_range_dict[i] = [cnt.index.values.tolist(), cnt.values.tolist()]\n    def predict(self, preds, i):\n        return pd.cut(rank_average(preds), [-np.inf] + np.cumsum(self.score_range_dict[i][1])[:-1].tolist() + [np.inf], labels = self.score_range_dict[i][0])\n\ndef optim_predict(pred, do_round=True, target=[ 2,  5,  7,  9, 11, 12, 13, 14, 15, 16, 19]):\n    for i in range(pred.shape[1]):\n        if i in target:\n            pred[:,i] = optim.predict(pred[:,i], i)\n    return pred\n```",
      "votes": 25
    },
    {
      "id": 750199,
      "postDate": "2020-02-19T07:34:48.157Z",
      "content": "<p><a href=\"/kenmatsu4\">@kenmatsu4</a> Thanks for sharing a great solution :D\nCan I ask you some questions?</p>\n\n<p>```\n1. &gt; Use first and last part of text if length exceed max_seq_length \nQ. How did you set the ratio for the first and last? (ex. 1 : 1, or 2 : 1 or etc …)  </p>\n\n<ol>\n<li><p>&gt; Averaging 4 BERT base-uncased model \nQ. What is the difference of the four models?  </p></li>\n<li><p>&gt; Fit target distribution with train data (a part of target columns) <br>\n Q. How did you choose the part of the target columns? Did you use oof?  </p></li>\n<li><p>&gt; Freeze half of BertLayer for reducing model complexity <br>\n Q. Which BertLayers did you freeze? <br>\n```  </p></li>\n</ol>\n\n<p>Thanks!</p>",
      "rawMarkdown": "@kenmatsu4 Thanks for sharing a great solution :D\nCan I ask you some questions?\n\n```\n1. &gt; Use first and last part of text if length exceed max_seq_length   \nQ. How did you set the ratio for the first and last? (ex. 1 : 1, or 2 : 1 or etc …)  \n\n  \n2. &gt; Averaging 4 BERT base-uncased model   \nQ. What is the difference of the four models?  \n\n  \n3. &gt; Fit target distribution with train data (a part of target columns)  \n Q. How did you choose the part of the target columns? Did you use oof?  \n\n  \n4. &gt; Freeze half of BertLayer for reducing model complexity  \n Q. Which BertLayers did you freeze?   \n```  \n\nThanks!",
      "votes": 1,
      "replies": [
        {
          "id": 750532,
          "postDate": "2020-02-19T13:37:49.467Z",
          "content": "<p>Thank you for your question, <a href=\"/guchio3\">@guchio3</a> !\nThe followings are my answer to your questions :D</p>\n\n<p><code>\n1. &gt; Use first and last part of text if length exceed max_seq_length\nQ. How did you set the ratio for the first and last? (ex. 1 : 1, or 2 : 1 or etc …) <br>\n</code></p>\n\n<p>-&gt; I tried various type of the ratio, however 1 : 1 was the best for me.</p>\n\n<p><code>\n2. &gt; Averaging 4 BERT base-uncased model\nQ. What is the difference of the four models?\n</code>\n-&gt; Used the models described as the following figure.\n￼<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F291723%2Fff85f6338fa415af7375021586f8704b%2F2020-02-19%2022.21.16.png?generation=1582119385493091&amp;alt=media\" alt=\"fig\"></p>\n\n<p><code>\n3. &gt; Fit target distribution with train data (a part of target columns)   Q. How did you choose the part of the target columns? Did you use oof? <br>\n</code>\n-&gt; Yes, I tried all of the columns and then, pick-up columns which has improvement with the post processing.</p>\n\n<p><code>\n4. &gt; Freeze half of BertLayer for reducing model complexity   Q. Which BertLayers did you freeze? <br>\n</code>\n-&gt; Set trainable as False for first half on the list of TFBertLayer class.</p>",
          "rawMarkdown": "Thank you for your question, @guchio3 !\nThe followings are my answer to your questions :D\n\n```\n1. &gt; Use first and last part of text if length exceed max_seq_length\nQ. How did you set the ratio for the first and last? (ex. 1 : 1, or 2 : 1 or etc …)  \n```\n\n-&gt; I tried various type of the ratio, however 1 : 1 was the best for me.\n\n```\n2. &gt; Averaging 4 BERT base-uncased model\nQ. What is the difference of the four models?\n```\n-&gt; Used the models described as the following figure.\n￼![fig](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F291723%2Fff85f6338fa415af7375021586f8704b%2F2020-02-19%2022.21.16.png?generation=1582119385493091&amp;alt=media)\n\n```\n3. &gt; Fit target distribution with train data (a part of target columns)   Q. How did you choose the part of the target columns? Did you use oof?  \n```\n-&gt; Yes, I tried all of the columns and then, pick-up columns which has improvement with the post processing.\n\n```\n4. &gt; Freeze half of BertLayer for reducing model complexity   Q. Which BertLayers did you freeze?   \n```\n-&gt; Set trainable as False for first half on the list of TFBertLayer class.\n",
          "votes": 1
        },
        {
          "id": 750537,
          "postDate": "2020-02-19T13:42:28.427Z",
          "content": "<p>Thank you for the quick and detailed answer.\nNow it's clear for me!</p>",
          "rawMarkdown": "Thank you for the quick and detailed answer.\nNow it's clear for me!",
          "votes": 1
        }
      ]
    },
    {
      "id": 742303,
      "postDate": "2020-02-11T08:17:10.937Z",
      "content": "<p>Congratulations!\nThanks for Sharing your Approach &amp; Insights!! <a href=\"/kenmatsu4\">@kenmatsu4</a> </p>",
      "rawMarkdown": "Congratulations!\nThanks for Sharing your Approach &amp; Insights!! @kenmatsu4 ",
      "votes": 1,
      "replies": [
        {
          "id": 742345,
          "postDate": "2020-02-11T08:47:19.600Z",
          "content": "<p>Thanks!</p>",
          "rawMarkdown": "Thanks!"
        }
      ]
    },
    {
      "id": 742186,
      "postDate": "2020-02-11T06:13:20.450Z",
      "content": "<p>You really did a great job, thanks for sharing.</p>",
      "rawMarkdown": "You really did a great job, thanks for sharing.",
      "votes": 1,
      "replies": [
        {
          "id": 742341,
          "postDate": "2020-02-11T08:46:23.430Z",
          "content": "<p>Thanks!</p>",
          "rawMarkdown": "Thanks!"
        }
      ]
    },
    {
      "id": 742278,
      "postDate": "2020-02-11T07:48:25.330Z",
      "content": "<p>Let us continue our learning and exciting journey ! <a href=\"/kenmatsu4\">@kenmatsu4</a> </p>",
      "rawMarkdown": "Let us continue our learning and exciting journey ! @kenmatsu4 ",
      "votes": 2,
      "replies": [
        {
          "id": 742343,
          "postDate": "2020-02-11T08:47:11.823Z",
          "content": "<p>Thanks ratthachat! Let's get gold medal next time!</p>",
          "rawMarkdown": "Thanks ratthachat! Let's get gold medal next time!",
          "votes": 1
        }
      ]
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T19:07:43Z",
  "competition_id": 7968,
  "competition_slug": "google-quest-challenge",
  "team_id": 4034555,
  "solution_url": "/competitions/google-quest-challenge/writeups/kenmatsu4-47th-place-solution"
}