{
  "id": 12476,
  "title": "Vowpal Wabbit lessons",
  "url": "/competitions/avazu-ctr-prediction/discussion/12476",
  "author_name": "",
  "post_date": "2015-02-11T09:03:29.427Z",
  "votes": 6,
  "comment_count": 12,
  "views": 8927,
  "content": "<p>Having used it for the first time here, I think I'll remember this competition for properly introducing me to Vowpal Wabbit. And thanks again to Triskelion for all the valuable Kaggle posts and blog entries.</p>\n<p>With that in mind, would anyone care to share what did and didn't work for them with vw? I'm not really thinking of top-of-the-leaderboard scores. It would just be useful&nbsp;to know more about the different vw parameters or data preparation steps&nbsp;that helped and which approaches were easier to implement.</p>\n<p>In my case, I found it too difficult (impossible?) to just throw in all quadratic interactions and rely on regularisation. So I created separate namespaces for each variable and used a small sample to identify the most promising interactions to add manually (I also needed to remove the pesky hidden line endings in the raw data files).</p>\n<p>Which meant my code amounted to:</p>\n<p><code>tr -d '\\r' &lt; Data/train.csv &gt; Data/train_clean.csv</code></p>\n<p><code>awk -F, 'NR &gt; 1 {print ($2*2)-1, &quot;|a&quot;, &quot;a_&quot;$4, &quot;|b&quot;, &quot;b_&quot;$5, &quot;|c&quot;, &quot;c_&quot;$6, &quot;|d&quot;, &quot;d_&quot;$7, &quot;|e&quot;, &quot;e_&quot;$8, &quot;|f&quot;, &quot;f_&quot;$9, &quot;|g&quot;, &quot;g_&quot;$10, &quot;|h&quot;, &quot;h_&quot;$11, &quot;|i&quot;, &quot;i_&quot;$12, &quot;|j&quot;, &quot;j_&quot;$13, &quot;|k&quot;, &quot;k_&quot;$14, &quot;|l&quot;, &quot;l_&quot;$15, &quot;|m&quot;, &quot;m_&quot;$16, &quot;|n&quot;, &quot;n_&quot;$17, &quot;|o&quot;, &quot;o_&quot;$18, &quot;|p&quot;, &quot;p_&quot;$19, &quot;|q&quot;, &quot;q_&quot;$20, &quot;|r&quot;, &quot;r_&quot;$21, &quot;|s&quot;, &quot;s_&quot;$22, &quot;|t&quot;, &quot;t_&quot;$23, &quot;|u&quot;, &quot;u_&quot;$24, &quot;|v&quot;, &quot;v_&quot;substr($3, 7, 2)}' Data/train_clean.csv &gt; Vowpal/train.vw</code></p>\n<p><code>vw -d Vowpal/train.vw -f Vowpal/model_sub3.vw --loss_function logistic -l 0.07 -c -k --passes 4 -b 25 --holdout_after 32377421 --hash all --l1 1e-8 --l2 1e-8 -q d: -q f: -q bk --cubic bdk --cubic bfk --ignore l --ignore v</code></p>\n<p>Which gave a public leaderboard score of 0.3918 after re-running with holdout_off. The interactions relied mainly on site_domain (d) and app_id (f).</p>\n<p>Not sure if I made a mistake, but feature_mask didn't work for me. And after re-categorising rare features into 'other', I found the neural network option on vw to be too slow on my hardware.</p>",
  "messages": [
    {
      "id": "64007",
      "postDate": "02/11/2015 09:03:29",
      "content": "<p>Having used it for the first time here, I think I'll remember this competition for properly introducing me to Vowpal Wabbit. And thanks again to Triskelion for all the valuable Kaggle posts and blog entries.</p>\n<p>With that in mind, would anyone care to share what did and didn't work for them with vw? I'm not really thinking of top-of-the-leaderboard scores. It would just be useful&nbsp;to know more about the different vw parameters or data preparation steps&nbsp;that helped and which approaches were easier to implement.</p>\n<p>In my case, I found it too difficult (impossible?) to just throw in all quadratic interactions and rely on regularisation. So I created separate namespaces for each variable and used a small sample to identify the most promising interactions to add manually (I also needed to remove the pesky hidden line endings in the raw data files).</p>\n<p>Which meant my code amounted to:</p>\n<p><code>tr -d '\\r' &lt; Data/train.csv &gt; Data/train_clean.csv</code></p>\n<p><code>awk -F, 'NR &gt; 1 {print ($2*2)-1, &quot;|a&quot;, &quot;a_&quot;$4, &quot;|b&quot;, &quot;b_&quot;$5, &quot;|c&quot;, &quot;c_&quot;$6, &quot;|d&quot;, &quot;d_&quot;$7, &quot;|e&quot;, &quot;e_&quot;$8, &quot;|f&quot;, &quot;f_&quot;$9, &quot;|g&quot;, &quot;g_&quot;$10, &quot;|h&quot;, &quot;h_&quot;$11, &quot;|i&quot;, &quot;i_&quot;$12, &quot;|j&quot;, &quot;j_&quot;$13, &quot;|k&quot;, &quot;k_&quot;$14, &quot;|l&quot;, &quot;l_&quot;$15, &quot;|m&quot;, &quot;m_&quot;$16, &quot;|n&quot;, &quot;n_&quot;$17, &quot;|o&quot;, &quot;o_&quot;$18, &quot;|p&quot;, &quot;p_&quot;$19, &quot;|q&quot;, &quot;q_&quot;$20, &quot;|r&quot;, &quot;r_&quot;$21, &quot;|s&quot;, &quot;s_&quot;$22, &quot;|t&quot;, &quot;t_&quot;$23, &quot;|u&quot;, &quot;u_&quot;$24, &quot;|v&quot;, &quot;v_&quot;substr($3, 7, 2)}' Data/train_clean.csv &gt; Vowpal/train.vw</code></p>\n<p><code>vw -d Vowpal/train.vw -f Vowpal/model_sub3.vw --loss_function logistic -l 0.07 -c -k --passes 4 -b 25 --holdout_after 32377421 --hash all --l1 1e-8 --l2 1e-8 -q d: -q f: -q bk --cubic bdk --cubic bfk --ignore l --ignore v</code></p>\n<p>Which gave a public leaderboard score of 0.3918 after re-running with holdout_off. The interactions relied mainly on site_domain (d) and app_id (f).</p>\n<p>Not sure if I made a mistake, but feature_mask didn't work for me. And after re-categorising rare features into 'other', I found the neural network option on vw to be too slow on my hardware.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64010",
      "postDate": "02/11/2015 09:22:47",
      "content": "<p>I've got 0.3893116 on public and 0.3871975 on private with single VW model. It was a fork of VW with several my improvements some of which I'm now trying to contribute back to VW master. They are described in my feedback on vw's github page: https://github.com/JohnLangford/vowpal_wabbit/issues/510</p>\n<p>If you be able (it's really long) to read suggestions #1-6 and 9 that mostly describe my model design flow. And final VW commands become understandable: http://pastebin.com/SnGwiCRi</p>\n<p>sed is used due to #5</p>\n<p>train_freq.vw looks like that http://pastebin.com/ZEZec0eL</p>\n<p>where x_freq_y features are rond(log(count_of_this_feature_in_dataset)).</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64013",
      "postDate": "02/11/2015 10:33:18",
      "content": "<p>Wow - that's more than I expected and I'm sure the vw team will appreciate all the feedback. I can see the case for more powerful approaches to namespaces and interaction terms, and the record of time taken would certainly come in handy.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64015",
      "postDate": "02/11/2015 10:54:52",
      "content": "<p>I can't recall exactly, but training on full dataset and prediction (2 passes + testing) shall took about 15-17 hours and 5 Gb RAM. There is no improvement with more passes or regularization applied. I also don't expect significant improvements with more memory (-b &gt; 28). I tried it on my laptop with Intel i7 2.9GHz 4-cores, 8Gb RAM and Kubuntu 14.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64017",
      "postDate": "02/11/2015 11:02:25",
      "content": "<p>Hi All, after using SGDClassifier in scikit-learn and reaching the 0.397 score on Public LB, I moved to VW obtaining on public LB 0.3939311 and private 0.3919883 (which I suspect is the VW entry and not the scikit one).</p>\n<p>I combined the features in preparing the data for VW format creating new features per 'categories': app, site, domain, id...that is something like this:</p>\n<p>app=app_id+app_domain+app_category</p>\n<p>....</p>\n<p>then I run vw with the following command line:</p>\n<p>vw train.vw.gz -f model.vw.gz --loss_function=logistic --hash strings -b 26 --learning_rate=0.6 --compressed --ftrl --ftrl_alpha=0.1 --ftrl_beta=1.0 --nn=10</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64021",
      "postDate": "02/11/2015 12:42:40",
      "content": "<p>[quote=truf;64010]</p>\n<p>I've got 0.3893116 on public and 0.3871975 on private with single VW model. It was a fork of VW with several my improvements some of which I'm now trying to contribute back to VW master.&nbsp;[/quote]</p>\n<p>You get this result by tweaking VW or by custom features? Can you explain your approach, please?</p>\n\n<p>I also have a lot of troubles with VW, especially with --rank option</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64025",
      "postDate": "02/11/2015 13:59:53",
      "content": "<p>[quote=Mikhail Trofimov;64021]</p>\n<p>You get this result by tweaking VW or by custom features? Can you explain your approach, please?</p>\n<p>I also have a lot of troubles with VW, especially with --rank option</p>\n<p>[/quote]</p>\n<p>Both. As for tweaks, they are described in my&nbsp;<a href=\"https://github.com/JohnLangford/vowpal_wabbit/issues/510\">github</a> post. As for feature engineering - it looks like i used that Mr. Gert&nbsp;<a href=\"https://www.kaggle.com/c/avazu-ctr-prediction/forums/t/12460/congrats-to-the-winners/63908#post63908\">means</a> by 'logtransformed counts'. I suspect our solutions are similar as I used high degrees of interaction between selected features too. For some even more than 3 (which is --cubic in vw).</p>\n\n<p>As for --rank - it didn't helped me, but I spent some time investigating its implementation. If VWs behavior didn't change much since my fork was done then --rank by itself is pretty useless as it launches the code in gd_mf.cc This implementation overwrites gradient descent parameters and use it without adaptive, normalazed and other enhancements which is ON by default for regular GD in VW. You can try VW's GD without them - it's much worse than default one. So if you just add --rank to your command line you'll get significantly worse results. There is a better implementation of matrix factorization in VW in mf.cc which is triggered if you add --new_mf key <strong>together</strong> with --rank. That implementation sits on top of your existing GD. So it just reuse GD you already use with all its parameters and modes.&nbsp; Thus --new_mf --rank behaves much better.</p>\n<p>And using --new_mf --rank you might face with problem which I described on github in I.12 - random values used for feature weights initialization might be too big for your dataset. In this case you need to initialize them with smaller value with --initial_weight.</p>\n<p>Anyway, I couldn't improve my model with MF. Perhaps I would get better results if I ensembled it with my solution.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64029",
      "postDate": "02/11/2015 14:22:39",
      "content": "<p>[quote=Elena Cuoco;64017]</p>\n<p>Hi All, after using SGDClassifier in scikit-learn and reaching the 0.397 score on Public LB, I moved to VW obtaining on public LB 0.3939311 and private 0.3919883 (which I suspect is the VW entry and not the scikit one).</p>\n<p>[/quote]</p>\n<p>On the competition site under &quot;my submissions&quot; you can check both the public and private LB score for each of your submissions (provided you can map your submissions to your attempts by filename, comment or timestamp).</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64034",
      "postDate": "02/11/2015 15:06:00",
      "content": "<p>[quote=Toby Cheese;64029]</p>\n<p>On the competition site under &quot;my submissions&quot; you can check both the public and private LB score for each of your submissions (provided you can map your submissions to your attempts by filename, comment or timestamp).</p>\n<p>[/quote]</p>\n<p>Thanks a lot Toby! I relized that I have a better result for VW (but just on the last decimal digit) than the one I selected and that all my attempts with scikit were not so bad, reaching a private score around 0.396 with best result of 0.3961003.</p>\n<p>&nbsp;I will put my scikit solution on github as soon as I have free time.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "64036",
      "postDate": "02/11/2015 15:12:20",
      "content": "<p>This doesn't really give insight into the various parameters available in vw, but I found the vw-hypersearch utility for tuning&nbsp;pretty useful. It needs data for cross-validation, otherwise parameter values are determined based on progressive validation, which underperforms.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "65406",
      "postDate": "03/04/2015 13:22:56",
      "content": "<p>The competition&nbsp; exposed me to Vowpal Wabbit. After some experiments in which I finally scored 0.3976030 (post closure), I wrote a <a href=\"https://ashokharnal.wordpress.com/2015/03/03/click-through-rate-prediction-using-neural-network-in-vowpal-wabbit-a-to-z/\">blog explaining all my steps</a>. VW is indeed fast and uses less resources.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "79893",
      "postDate": "05/24/2015 09:05:30",
      "content": "<p>Hi pals!</p>\n<p>Sorry for reanimate this dead thread. Just want to say that most of VW improvements I made during this competition were finally merged into VW master codebase.&nbsp; So it may worth to `git pull` these changes. The changes are:</p>\n<p>* --redefine param to rename/group namespaces on fly</p>\n<p>* --interactions param for interactions of any length (not only 2 in -q and 3 in --cubic)</p>\n<p>* simple combinations instead of permutations of interacting features of the same namespace allows to generate less new features making model train faster. For example `-q aa` where a holds 3 features will generate only 3 new features instead of 9.</p>\n<p>* Slightly better hash function for interacting features</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "79898",
      "postDate": "05/24/2015 11:17:06",
      "content": "<p>Truf, thanks a lot for adding to VW and the extensive user feedback! Much appreciated.</p>",
      "rawMarkdown": "",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 64010,
      "author_name": "trufanov",
      "author_url": "",
      "post_date": "02/11/2015 09:22:47",
      "content": "<p>I've got 0.3893116 on public and 0.3871975 on private with single VW model. It was a fork of VW with several my improvements some of which I'm now trying to contribute back to VW master. They are described in my feedback on vw's github page: https://github.com/JohnLangford/vowpal_wabbit/issues/510</p>\n<p>If you be able (it's really long) to read suggestions #1-6 and 9 that mostly describe my model design flow. And final VW commands become understandable: http://pastebin.com/SnGwiCRi</p>\n<p>sed is used due to #5</p>\n<p>train_freq.vw looks like that http://pastebin.com/ZEZec0eL</p>\n<p>where x_freq_y features are rond(log(count_of_this_feature_in_dataset)).</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64013,
      "author_name": "cartographic",
      "author_url": "",
      "post_date": "02/11/2015 10:33:18",
      "content": "<p>Wow - that's more than I expected and I'm sure the vw team will appreciate all the feedback. I can see the case for more powerful approaches to namespaces and interaction terms, and the record of time taken would certainly come in handy.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64015,
      "author_name": "trufanov",
      "author_url": "",
      "post_date": "02/11/2015 10:54:52",
      "content": "<p>I can't recall exactly, but training on full dataset and prediction (2 passes + testing) shall took about 15-17 hours and 5 Gb RAM. There is no improvement with more passes or regularization applied. I also don't expect significant improvements with more memory (-b &gt; 28). I tried it on my laptop with Intel i7 2.9GHz 4-cores, 8Gb RAM and Kubuntu 14.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64017,
      "author_name": "elenacuoco",
      "author_url": "",
      "post_date": "02/11/2015 11:02:25",
      "content": "<p>Hi All, after using SGDClassifier in scikit-learn and reaching the 0.397 score on Public LB, I moved to VW obtaining on public LB 0.3939311 and private 0.3919883 (which I suspect is the VW entry and not the scikit one).</p>\n<p>I combined the features in preparing the data for VW format creating new features per 'categories': app, site, domain, id...that is something like this:</p>\n<p>app=app_id+app_domain+app_category</p>\n<p>....</p>\n<p>then I run vw with the following command line:</p>\n<p>vw train.vw.gz -f model.vw.gz --loss_function=logistic --hash strings -b 26 --learning_rate=0.6 --compressed --ftrl --ftrl_alpha=0.1 --ftrl_beta=1.0 --nn=10</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64021,
      "author_name": "mikhailtrofimov",
      "author_url": "",
      "post_date": "02/11/2015 12:42:40",
      "content": "<p>[quote=truf;64010]</p>\n<p>I've got 0.3893116 on public and 0.3871975 on private with single VW model. It was a fork of VW with several my improvements some of which I'm now trying to contribute back to VW master.&nbsp;[/quote]</p>\n<p>You get this result by tweaking VW or by custom features? Can you explain your approach, please?</p>\n\n<p>I also have a lot of troubles with VW, especially with --rank option</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64025,
      "author_name": "trufanov",
      "author_url": "",
      "post_date": "02/11/2015 13:59:53",
      "content": "<p>[quote=Mikhail Trofimov;64021]</p>\n<p>You get this result by tweaking VW or by custom features? Can you explain your approach, please?</p>\n<p>I also have a lot of troubles with VW, especially with --rank option</p>\n<p>[/quote]</p>\n<p>Both. As for tweaks, they are described in my&nbsp;<a href=\"https://github.com/JohnLangford/vowpal_wabbit/issues/510\">github</a> post. As for feature engineering - it looks like i used that Mr. Gert&nbsp;<a href=\"https://www.kaggle.com/c/avazu-ctr-prediction/forums/t/12460/congrats-to-the-winners/63908#post63908\">means</a> by 'logtransformed counts'. I suspect our solutions are similar as I used high degrees of interaction between selected features too. For some even more than 3 (which is --cubic in vw).</p>\n\n<p>As for --rank - it didn't helped me, but I spent some time investigating its implementation. If VWs behavior didn't change much since my fork was done then --rank by itself is pretty useless as it launches the code in gd_mf.cc This implementation overwrites gradient descent parameters and use it without adaptive, normalazed and other enhancements which is ON by default for regular GD in VW. You can try VW's GD without them - it's much worse than default one. So if you just add --rank to your command line you'll get significantly worse results. There is a better implementation of matrix factorization in VW in mf.cc which is triggered if you add --new_mf key <strong>together</strong> with --rank. That implementation sits on top of your existing GD. So it just reuse GD you already use with all its parameters and modes.&nbsp; Thus --new_mf --rank behaves much better.</p>\n<p>And using --new_mf --rank you might face with problem which I described on github in I.12 - random values used for feature weights initialization might be too big for your dataset. In this case you need to initialize them with smaller value with --initial_weight.</p>\n<p>Anyway, I couldn't improve my model with MF. Perhaps I would get better results if I ensembled it with my solution.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64029,
      "author_name": "tobycheese",
      "author_url": "",
      "post_date": "02/11/2015 14:22:39",
      "content": "<p>[quote=Elena Cuoco;64017]</p>\n<p>Hi All, after using SGDClassifier in scikit-learn and reaching the 0.397 score on Public LB, I moved to VW obtaining on public LB 0.3939311 and private 0.3919883 (which I suspect is the VW entry and not the scikit one).</p>\n<p>[/quote]</p>\n<p>On the competition site under &quot;my submissions&quot; you can check both the public and private LB score for each of your submissions (provided you can map your submissions to your attempts by filename, comment or timestamp).</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64034,
      "author_name": "elenacuoco",
      "author_url": "",
      "post_date": "02/11/2015 15:06:00",
      "content": "<p>[quote=Toby Cheese;64029]</p>\n<p>On the competition site under &quot;my submissions&quot; you can check both the public and private LB score for each of your submissions (provided you can map your submissions to your attempts by filename, comment or timestamp).</p>\n<p>[/quote]</p>\n<p>Thanks a lot Toby! I relized that I have a better result for VW (but just on the last decimal digit) than the one I selected and that all my attempts with scikit were not so bad, reaching a private score around 0.396 with best result of 0.3961003.</p>\n<p>&nbsp;I will put my scikit solution on github as soon as I have free time.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 64036,
      "author_name": "jwjohnson314",
      "author_url": "",
      "post_date": "02/11/2015 15:12:20",
      "content": "<p>This doesn't really give insight into the various parameters available in vw, but I found the vw-hypersearch utility for tuning&nbsp;pretty useful. It needs data for cross-validation, otherwise parameter values are determined based on progressive validation, which underperforms.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 65406,
      "author_name": "harnalashok",
      "author_url": "",
      "post_date": "03/04/2015 13:22:56",
      "content": "<p>The competition&nbsp; exposed me to Vowpal Wabbit. After some experiments in which I finally scored 0.3976030 (post closure), I wrote a <a href=\"https://ashokharnal.wordpress.com/2015/03/03/click-through-rate-prediction-using-neural-network-in-vowpal-wabbit-a-to-z/\">blog explaining all my steps</a>. VW is indeed fast and uses less resources.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 79893,
      "author_name": "trufanov",
      "author_url": "",
      "post_date": "05/24/2015 09:05:30",
      "content": "<p>Hi pals!</p>\n<p>Sorry for reanimate this dead thread. Just want to say that most of VW improvements I made during this competition were finally merged into VW master codebase.&nbsp; So it may worth to `git pull` these changes. The changes are:</p>\n<p>* --redefine param to rename/group namespaces on fly</p>\n<p>* --interactions param for interactions of any length (not only 2 in -q and 3 in --cubic)</p>\n<p>* simple combinations instead of permutations of interacting features of the same namespace allows to generate less new features making model train faster. For example `-q aa` where a holds 3 features will generate only 3 new features instead of 9.</p>\n<p>* Slightly better hash function for interacting features</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 79898,
      "author_name": "triskelion",
      "author_url": "",
      "post_date": "05/24/2015 11:17:06",
      "content": "<p>Truf, thanks a lot for adding to VW and the extensive user feedback! Much appreciated.</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "64007": "",
    "64010": "",
    "64013": "",
    "64015": "",
    "64017": "",
    "64021": "",
    "64025": "",
    "64029": "",
    "64034": "",
    "64036": "",
    "65406": "",
    "79893": "",
    "79898": ""
  },
  "source": "meta"
}