{
  "id": 2485,
  "title": "\"cap_and_update_priors\" in the benchmark code",
  "url": "/competitions/predict-closed-questions-on-stack-overflow/discussion/2485",
  "author_name": "",
  "post_date": "2012-08-28T21:53:15.403Z",
  "votes": null,
  "comment_count": 7,
  "views": 2837,
  "content": "<p>At first glance, the random forest benchmark seems very straightforward:</p>\r\n<blockquote>\r\n<div id=\"x_x_LC27\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">rf</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">fit</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">fea</span><span class=\"x_x_p\">,</span>\r\n<span class=\"x_x_n\">data</span><span class=\"x_x_p\">[</span><span class=\"x_x_s\">&quot;OpenStatus&quot;</span><span class=\"x_x_p\">])</span></div>\r\n<div id=\"x_x_LC30\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">data</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">get_dataframe</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">test_file</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC31\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">test_features</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">features</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">extract_features</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">feature_names</span><span class=\"x_x_p\">,</span>\r\n<span class=\"x_x_n\">data</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC32\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">probs</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">rf</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">predict_proba</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">test_features</span><span class=\"x_x_p\">)</span></div>\r\n<div class=\"x_x_line\"><span class=\"x_x_p\"><br>\r\n</span></div>\r\n</blockquote>\r\n<div class=\"x_x_line\"><span class=\"x_x_p\">However, my own random forest (implemented in R) has nowhere near the same performance, and this performance gap is probably due to this piece of code:</span></div>\r\n<div class=\"x_x_line\">\r\n<blockquote>\r\n<div id=\"x_x_LC34\" class=\"x_x_line\"><br class=\"x_x_Apple-interchange-newline\">\r\n&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_k\">print</span><span class=\"x_x_p\">(</span><span class=\"x_x_s\">&quot;Calculating priors and updating posteriors&quot;</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC35\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">new_priors</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">get_priors</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">full_train_file</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC36\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">old_priors</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">get_priors</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">train_file</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC37\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">probs</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">cap_and_update_priors</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">old_priors</span><span class=\"x_x_p\">,</span>\r\n<span class=\"x_x_n\">probs</span><span class=\"x_x_p\">,</span> <span class=\"x_x_n\">\r\nnew_priors</span><span class=\"x_x_p\">,</span> <span class=\"x_x_mf\">0.001</span><span class=\"x_x_p\">)</span></div>\r\n</blockquote>\r\n<div class=\"x_x_line\"><span class=\"x_x_p\">I'm not very familiar with python. &nbsp;Could someone please explain what this block of code does, and perhaps help me implement it in R?</span></div>\r\n<div id=\"x_x_LC38\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;</div>\r\n</div>",
  "messages": [
    {
      "id": "13579",
      "postDate": "08/28/2012 21:53:15",
      "content": "<p>At first glance, the random forest benchmark seems very straightforward:</p>\r\n<blockquote>\r\n<div id=\"x_x_LC27\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">rf</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">fit</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">fea</span><span class=\"x_x_p\">,</span>\r\n<span class=\"x_x_n\">data</span><span class=\"x_x_p\">[</span><span class=\"x_x_s\">&quot;OpenStatus&quot;</span><span class=\"x_x_p\">])</span></div>\r\n<div id=\"x_x_LC30\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">data</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">get_dataframe</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">test_file</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC31\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">test_features</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">features</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">extract_features</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">feature_names</span><span class=\"x_x_p\">,</span>\r\n<span class=\"x_x_n\">data</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC32\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">probs</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">rf</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">predict_proba</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">test_features</span><span class=\"x_x_p\">)</span></div>\r\n<div class=\"x_x_line\"><span class=\"x_x_p\"><br>\r\n</span></div>\r\n</blockquote>\r\n<div class=\"x_x_line\"><span class=\"x_x_p\">However, my own random forest (implemented in R) has nowhere near the same performance, and this performance gap is probably due to this piece of code:</span></div>\r\n<div class=\"x_x_line\">\r\n<blockquote>\r\n<div id=\"x_x_LC34\" class=\"x_x_line\"><br class=\"x_x_Apple-interchange-newline\">\r\n&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_k\">print</span><span class=\"x_x_p\">(</span><span class=\"x_x_s\">&quot;Calculating priors and updating posteriors&quot;</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC35\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">new_priors</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">get_priors</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">full_train_file</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC36\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">old_priors</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">get_priors</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">train_file</span><span class=\"x_x_p\">)</span></div>\r\n<div id=\"x_x_LC37\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"x_x_n\">probs</span> <span class=\"x_x_o\">\r\n=</span> <span class=\"x_x_n\">cu</span><span class=\"x_x_o\">.</span><span class=\"x_x_n\">cap_and_update_priors</span><span class=\"x_x_p\">(</span><span class=\"x_x_n\">old_priors</span><span class=\"x_x_p\">,</span>\r\n<span class=\"x_x_n\">probs</span><span class=\"x_x_p\">,</span> <span class=\"x_x_n\">\r\nnew_priors</span><span class=\"x_x_p\">,</span> <span class=\"x_x_mf\">0.001</span><span class=\"x_x_p\">)</span></div>\r\n</blockquote>\r\n<div class=\"x_x_line\"><span class=\"x_x_p\">I'm not very familiar with python. &nbsp;Could someone please explain what this block of code does, and perhaps help me implement it in R?</span></div>\r\n<div id=\"x_x_LC38\" class=\"x_x_line\">&nbsp;&nbsp;&nbsp;&nbsp;</div>\r\n</div>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13583",
      "postDate": "08/28/2012 23:15:48",
      "content": "<p>The first line of basic_benchmark is this:</p>\r\n<pre>import competition_utilities as cu</pre>\r\n<p>which means cu.xyz will be found in competition_utilities.py as <tt>def xyz:</tt></p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13602",
      "postDate": "08/29/2012 12:29:11",
      "content": "<p>Right, I get that. &nbsp;The relevant functions seem to be &quot;<span>get_priors,&quot; &quot;<span>update_prior,&quot; and &quot;<span>cap_and_update_priors.&quot; &nbsp;I'm trying to understand what these functions are actually doing. &nbsp;For example, what is the purpose of these lines?</span></span></span></p>\r\n<div id=\"x_x_x_LC67\" class=\"x_x_x_line\"><span class=\"x_x_x_n\">old_priors</span> <span class=\"x_x_x_o\">\r\n=</span> <span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">kron</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">ones</span><span class=\"x_x_x_p\">((</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">size</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">old_posteriors</span><span class=\"x_x_x_p\">,</span>\r\n<span class=\"x_x_x_mi\">0</span><span class=\"x_x_x_p\">),</span> <span class=\"x_x_x_mi\">\r\n1</span><span class=\"x_x_x_p\">)),</span> <span class=\"x_x_x_n\">old_priors</span><span class=\"x_x_x_p\">)</span></div>\r\n<div id=\"x_x_x_LC68\" class=\"x_x_x_line\"><span class=\"x_x_x_n\">new_priors</span> <span class=\"x_x_x_o\">\r\n=</span> <span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">kron</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">ones</span><span class=\"x_x_x_p\">((</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">size</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">old_posteriors</span><span class=\"x_x_x_p\">,</span>\r\n<span class=\"x_x_x_mi\">0</span><span class=\"x_x_x_p\">),</span> <span class=\"x_x_x_mi\">\r\n1</span><span class=\"x_x_x_p\">)),</span> <span class=\"x_x_x_n\">new_priors</span><span class=\"x_x_x_p\">)</span></div>\r\n<p><span><span><span><br>\r\n</span></span></span></p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13623",
      "postDate": "08/29/2012 19:40:29",
      "content": "<p>Here is my attempt to answer my own question, and port the competition utils to R</p>\r\n<blockquote>\r\n<pre><br>cap_predictions &lt;- function(probs, epsilon=0.001){<br>  probs[probs&gt;1-epsilon] = 1-epsilon<br>  probs[probs&lt;epsilon] = epsilon<br>  probs = probs / rowSums(probs)<br>  return(probs)<br>}<br><br>get_priors &lt;- function(file_name){<br>  closed_reasons = read.csv(file_name,<br>    colClasses=c(rep(&quot;NULL&quot;, 14), &quot;character&quot;), header = TRUE)[,1]<br>  closed_reason_counts = table(closed_reasons)<br>  total = length(closed_reasons)<br>  priors = closed_reason_counts/total<br>  return(priors)<br>}<br><br>update_priors &lt;- function(old_prior,  old_posterior, new_prior){<br>  evidence_ratio = (old_prior*(1-old_posterior)) / <br>    (old_posterior*(1-old_prior))<br>  new_posterior = new_prior / (new_prior &#43; (1-new_prior)*evidence_ratio)<br>  return(new_posterior)<br>}<br><br>cap_and_update_priors &lt;- function(old_priors, old_posteriors, <br>                                  new_priors, epsilon=0.001){<br>  old_posteriors = cap_predictions(old_posteriors, epsilon)<br>  <br>  old_priors = kronecker(<br>    matrix(old_priors, ncol=length(old_priors)), <br>    matrix(rep(1, nrow(old_posteriors))), nrow=nrow(old_posteriors))<br>  <br>  new_priors = kronecker(<br>    matrix(new_priors, ncol=length(new_priors)), <br>    matrix(rep(1, nrow(old_posteriors))), nrow=nrow(old_posteriors))<br>  <br>  evidence_ratio = (old_priors*(1-old_posteriors)) / <br>    (old_posteriors*(1-old_priors))<br>  <br>  new_posteriors = new_priors / (new_priors &#43; (1-new_priors)*evidence_ratio)<br>  new_posteriors = cap_predictions(new_posteriors, epsilon)<br>  return(new_posteriors)<br>}</pre>\r\n</blockquote>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13645",
      "postDate": "08/30/2012 15:02:27",
      "content": "<p>Here is a good article describing the procedure of updating priors:</p>\r\n<p><a href=\"http://www.mpia-hd.mpg.de/Gaia/publications/probcomb_TN.pdf\">http://www.mpia-hd.mpg.de/Gaia/publications/probcomb_TN.pdf</a></p>\r\n<p>See 3 - Replacing prior information. Equation 12 (and Appendix A) is basically what the code in question does.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13650",
      "postDate": "08/30/2012 16:51:43",
      "content": "<p>Ok, its seems that the purpose of updating priors in this specific context is that you've built the model on a stratified sample, of about 50% open and 50% closed questions. However, in reality about 94% of questions are open, so you should adjust your predictions\r\n accordingly.</p>\r\n<p>Does this make sense?</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13695",
      "postDate": "08/31/2012 13:58:58",
      "content": "<p>Yes, correct.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "13697",
      "postDate": "08/31/2012 15:18:37",
      "content": "<p>Thank you. I had already asked about this in an earlier thread, but no one answered for some reason.</p>",
      "rawMarkdown": "",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 13583,
      "author_name": "andysloane",
      "author_url": "",
      "post_date": "08/28/2012 23:15:48",
      "content": "<p>The first line of basic_benchmark is this:</p>\r\n<pre>import competition_utilities as cu</pre>\r\n<p>which means cu.xyz will be found in competition_utilities.py as <tt>def xyz:</tt></p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 13602,
      "author_name": "zachmayer",
      "author_url": "",
      "post_date": "08/29/2012 12:29:11",
      "content": "<p>Right, I get that. &nbsp;The relevant functions seem to be &quot;<span>get_priors,&quot; &quot;<span>update_prior,&quot; and &quot;<span>cap_and_update_priors.&quot; &nbsp;I'm trying to understand what these functions are actually doing. &nbsp;For example, what is the purpose of these lines?</span></span></span></p>\r\n<div id=\"x_x_x_LC67\" class=\"x_x_x_line\"><span class=\"x_x_x_n\">old_priors</span> <span class=\"x_x_x_o\">\r\n=</span> <span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">kron</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">ones</span><span class=\"x_x_x_p\">((</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">size</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">old_posteriors</span><span class=\"x_x_x_p\">,</span>\r\n<span class=\"x_x_x_mi\">0</span><span class=\"x_x_x_p\">),</span> <span class=\"x_x_x_mi\">\r\n1</span><span class=\"x_x_x_p\">)),</span> <span class=\"x_x_x_n\">old_priors</span><span class=\"x_x_x_p\">)</span></div>\r\n<div id=\"x_x_x_LC68\" class=\"x_x_x_line\"><span class=\"x_x_x_n\">new_priors</span> <span class=\"x_x_x_o\">\r\n=</span> <span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">kron</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">ones</span><span class=\"x_x_x_p\">((</span><span class=\"x_x_x_n\">np</span><span class=\"x_x_x_o\">.</span><span class=\"x_x_x_n\">size</span><span class=\"x_x_x_p\">(</span><span class=\"x_x_x_n\">old_posteriors</span><span class=\"x_x_x_p\">,</span>\r\n<span class=\"x_x_x_mi\">0</span><span class=\"x_x_x_p\">),</span> <span class=\"x_x_x_mi\">\r\n1</span><span class=\"x_x_x_p\">)),</span> <span class=\"x_x_x_n\">new_priors</span><span class=\"x_x_x_p\">)</span></div>\r\n<p><span><span><span><br>\r\n</span></span></span></p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 13623,
      "author_name": "zachmayer",
      "author_url": "",
      "post_date": "08/29/2012 19:40:29",
      "content": "<p>Here is my attempt to answer my own question, and port the competition utils to R</p>\r\n<blockquote>\r\n<pre><br>cap_predictions &lt;- function(probs, epsilon=0.001){<br>  probs[probs&gt;1-epsilon] = 1-epsilon<br>  probs[probs&lt;epsilon] = epsilon<br>  probs = probs / rowSums(probs)<br>  return(probs)<br>}<br><br>get_priors &lt;- function(file_name){<br>  closed_reasons = read.csv(file_name,<br>    colClasses=c(rep(&quot;NULL&quot;, 14), &quot;character&quot;), header = TRUE)[,1]<br>  closed_reason_counts = table(closed_reasons)<br>  total = length(closed_reasons)<br>  priors = closed_reason_counts/total<br>  return(priors)<br>}<br><br>update_priors &lt;- function(old_prior,  old_posterior, new_prior){<br>  evidence_ratio = (old_prior*(1-old_posterior)) / <br>    (old_posterior*(1-old_prior))<br>  new_posterior = new_prior / (new_prior &#43; (1-new_prior)*evidence_ratio)<br>  return(new_posterior)<br>}<br><br>cap_and_update_priors &lt;- function(old_priors, old_posteriors, <br>                                  new_priors, epsilon=0.001){<br>  old_posteriors = cap_predictions(old_posteriors, epsilon)<br>  <br>  old_priors = kronecker(<br>    matrix(old_priors, ncol=length(old_priors)), <br>    matrix(rep(1, nrow(old_posteriors))), nrow=nrow(old_posteriors))<br>  <br>  new_priors = kronecker(<br>    matrix(new_priors, ncol=length(new_priors)), <br>    matrix(rep(1, nrow(old_posteriors))), nrow=nrow(old_posteriors))<br>  <br>  evidence_ratio = (old_priors*(1-old_posteriors)) / <br>    (old_posteriors*(1-old_priors))<br>  <br>  new_posteriors = new_priors / (new_priors &#43; (1-new_priors)*evidence_ratio)<br>  new_posteriors = cap_predictions(new_posteriors, epsilon)<br>  return(new_posteriors)<br>}</pre>\r\n</blockquote>",
      "votes": null,
      "replies": []
    },
    {
      "id": 13645,
      "author_name": "chisquared",
      "author_url": "",
      "post_date": "08/30/2012 15:02:27",
      "content": "<p>Here is a good article describing the procedure of updating priors:</p>\r\n<p><a href=\"http://www.mpia-hd.mpg.de/Gaia/publications/probcomb_TN.pdf\">http://www.mpia-hd.mpg.de/Gaia/publications/probcomb_TN.pdf</a></p>\r\n<p>See 3 - Replacing prior information. Equation 12 (and Appendix A) is basically what the code in question does.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 13650,
      "author_name": "zachmayer",
      "author_url": "",
      "post_date": "08/30/2012 16:51:43",
      "content": "<p>Ok, its seems that the purpose of updating priors in this specific context is that you've built the model on a stratified sample, of about 50% open and 50% closed questions. However, in reality about 94% of questions are open, so you should adjust your predictions\r\n accordingly.</p>\r\n<p>Does this make sense?</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 13695,
      "author_name": "chisquared",
      "author_url": "",
      "post_date": "08/31/2012 13:58:58",
      "content": "<p>Yes, correct.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 13697,
      "author_name": "cjauvin",
      "author_url": "",
      "post_date": "08/31/2012 15:18:37",
      "content": "<p>Thank you. I had already asked about this in an earlier thread, but no one answered for some reason.</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "13579": "",
    "13583": "",
    "13602": "",
    "13623": "",
    "13645": "",
    "13650": "",
    "13695": "",
    "13697": ""
  },
  "source": "meta"
}