{
  "id": 703,
  "title": "Code to calculate NormalizedGini",
  "url": "/competitions/ClaimPredictionChallenge/discussion/703",
  "author_name": "",
  "post_date": "2011-07-13T13:49:34.823Z",
  "votes": 36,
  "comment_count": 24,
  "views": 24161,
  "content": "<p>Since this is a new metric to Kaggle, I thought I'd share the code we use to calculate it (in C#):</p>\r\n<pre>public static double Gini(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    if(a.Count != p.Count) {<br>        throw new ArgumentException();<br>    }<br><br>    var all =<br>            p.Zip(a, (pred, actual) =&gt; new { actualValue = actual, predictedValue = pred }) // (actual, prediction)<br>            .Zip(Enumerable.Range(1, a.Count), (ap, i) =&gt; new { ap.actualValue, ap.predictedValue, originalIndex = i })<br>            .OrderByDescending(ap =&gt; ap.predictedValue) // important to sort descending by prediction<br>            .ThenBy(ap =&gt; ap.originalIndex); // secondary sorts to ensure unambigious orders<br>            <br>    var totalActualLosses = a.Sum(); <br><br>    double populationDelta = 1.0/a.Count;<br>    double accumulatedPopulationPercentageSum = 0;<br>    double accumulatedLossPercentageSum = 0;<br><br>    double giniSum = 0.0;<br><br>    foreach(var currentPair in all) {<br>        accumulatedLossPercentageSum &#43;= (currentPair.actualValue/totalActualLosses);<br>        accumulatedPopulationPercentageSum &#43;= populationDelta;<br>        giniSum &#43;= accumulatedLossPercentageSum - accumulatedPopulationPercentageSum;<br>    }<br><br>    var gini = giniSum/a.Count;<br>    return gini;<br>}<br><br>public static double GiniNormalized(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    return a.Gini(p)/(a.Gini(a));<br>}</pre>\r\n<p>Let me know if you have any questions about the code. Feel free to post your own ports of it to the languages of your choice.</p>",
  "messages": [
    {
      "id": "4568",
      "postDate": "07/13/2011 13:49:34",
      "content": "<p>Since this is a new metric to Kaggle, I thought I'd share the code we use to calculate it (in C#):</p>\r\n<pre>public static double Gini(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    if(a.Count != p.Count) {<br>        throw new ArgumentException();<br>    }<br><br>    var all =<br>            p.Zip(a, (pred, actual) =&gt; new { actualValue = actual, predictedValue = pred }) // (actual, prediction)<br>            .Zip(Enumerable.Range(1, a.Count), (ap, i) =&gt; new { ap.actualValue, ap.predictedValue, originalIndex = i })<br>            .OrderByDescending(ap =&gt; ap.predictedValue) // important to sort descending by prediction<br>            .ThenBy(ap =&gt; ap.originalIndex); // secondary sorts to ensure unambigious orders<br>            <br>    var totalActualLosses = a.Sum(); <br><br>    double populationDelta = 1.0/a.Count;<br>    double accumulatedPopulationPercentageSum = 0;<br>    double accumulatedLossPercentageSum = 0;<br><br>    double giniSum = 0.0;<br><br>    foreach(var currentPair in all) {<br>        accumulatedLossPercentageSum &#43;= (currentPair.actualValue/totalActualLosses);<br>        accumulatedPopulationPercentageSum &#43;= populationDelta;<br>        giniSum &#43;= accumulatedLossPercentageSum - accumulatedPopulationPercentageSum;<br>    }<br><br>    var gini = giniSum/a.Count;<br>    return gini;<br>}<br><br>public static double GiniNormalized(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    return a.Gini(p)/(a.Gini(a));<br>}</pre>\r\n<p>Let me know if you have any questions about the code. Feel free to post your own ports of it to the languages of your choice.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4573",
      "postDate": "07/13/2011 18:04:23",
      "content": "<p>Hi Jeff!</p>\r\n<p>I don't know C code, but I tried to read it and made some educated guesses in order to try and make an R function (good practice for me&nbsp; - as I generally hate reading code).</p>\r\n<p>Anyway - can you tell me if I am on the right track:</p>\r\n<p>normalizedGini &lt;- function(aa, pp){<br>\r\nGini &lt;- function(a, p){<br>\r\n&nbsp; if(length(a) !=&nbsp; length(p)) stop(&quot;Actual and Predicted need to be equal lengths!&quot;)<br>\r\n&nbsp; temp.df &lt;- data.frame(actual = a, pred = p, range=c(1:length(a)))<br>\r\n&nbsp; temp.df &lt;- temp.df[order(temp.df$pred, temp.df$range, decreasing=TRUE),]<br>\r\n&nbsp; population.delta &lt;- 1 / length(a)<br>\r\n&nbsp; total.losses &lt;- sum(a)<br>\r\n&nbsp; null.losses &lt;- rep(population.delta, length(a)) # Hopefully is similar to accumulatedPopulationPercentageSum<br>\r\n&nbsp; accum.losses &lt;- temp.df$actual / total.losses # Hopefully is similar to accumulatedLossPercentageSum<br>\r\n&nbsp; gini.sum &lt;- cumsum(accum.losses - null.losses) # Not sure if this is having the same effect or not<br>\r\n&nbsp; sum(gini.sum)<br>\r\n}<br>\r\nGini(aa,pp) / Gini(aa,aa)<br>\r\n}</p>\r\n<p>I get:</p>\r\n<pre class=\"x_GD40030CKR\" style=\"font-family:'Lucida Console'; font-size:10pt!important; outline-style:none; border-style:none; white-space:pre-wrap!important; margin:0px; line-height:1.3\"><span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:1000, 1:1000) </span><br>[1] 1\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:1000, 99001:100000) </span><br>[1] 1\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:1000, 1000:1) <br></span>[1] -1\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:10000, runif(10000)) # Should be close to zero </span><br>[1] 0.01671304\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(cars$Claim_Amount[1:1000000], cars$Var1[1:1000000]) </span>#First million rows of training set<br>[1] -0.03384947<br><br>Thanks!</pre>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4574",
      "postDate": "07/13/2011 18:58:11",
      "content": "<p>Hi Chris,</p>\r\n<p>Two observations:</p>\r\n<ol>\r\n<li>Be sure to sort by predictions <strong>descending</strong> and then in the case of ties, sort by the original order\r\n<strong>ascending</strong>. It looks like you did descending on both. </li><li>Be sure to return the average value gini.Sum / length(a) instead of the sum itself.\r\n</li></ol>\r\n<div>I'm setting up a new machine at the moment, but when it's ready I should be able to create some sample values for you to test against.</div>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4575",
      "postDate": "07/13/2011 19:43:35",
      "content": "<p>You may find this doc helpful.<br>\r\nhttp://www.rhinorisk.com/Publications/Gini%20Coefficients.pdf</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4577",
      "postDate": "07/13/2011 20:02:55",
      "content": "<p>Jeff, where do you get the perfect model?</p>\r\n<p>From the graph, the perfect model should have a gini of 100 or the top left corner.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4578",
      "postDate": "07/13/2011 20:05:39",
      "content": "<p>[quote=Sashi;4577]</p>\r\n<p>Jeff, where do you get the perfect model?</p>\r\n<p>[/quote]</p>\r\n<p>The perfect model is the solution itself.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4579",
      "postDate": "07/13/2011 20:29:32",
      "content": "<p>@Jeff:</p>\r\n<p>Thanks for posting the code. I will wait for the test cases to verify my implementation.</p>\r\n<p>Here is my C&#43;&#43; implementation.</p>\r\n<pre>double Gini(const std::vector &amp;a, decltype(a) &amp;p) {<br>  assert(a.size() == p.size());<br>&nbsp; struct K {double a, p;} k[a.size()];<br>&nbsp; for (auto i = 0; i != a.size(); &#43;&#43;i) k[i] = {a[i], p[i]};<br>&nbsp; std::stable_sort(k, k&#43;a.size(), [](const K &amp;a, const K &amp;b) {return a.p &gt; b.p;});<br>&nbsp; double accPopPercSum=0, accLossPercSum=0, giniSum=0, sum=0;<br>&nbsp; for (auto &amp;i: a) sum &#43;= i;<br>&nbsp; for (auto &amp;i: k) {<br>&nbsp;&nbsp;&nbsp;&nbsp; accLossPercSum &#43;= i.a/sum;<br>&nbsp;&nbsp;&nbsp;&nbsp; accPopPercSum &#43;= 1.0/a.size();<br>&nbsp;&nbsp;&nbsp;&nbsp; giniSum &#43;= accLossPercSum-accPopPercSum;<br>&nbsp; }<br>&nbsp; return giniSum/a.size();<br>}<br>double GiniNormalized(const std::vector &amp;a, decltype(a) &amp;p) {<br>&nbsp; return Gini(a, p)/Gini(a, a);<br>}</pre>\r\n<p>std::cout &lt;&lt; GiniNormalized({3,1,2,4,0}, {3,2,0,4,1}) //returns 0.7</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4580",
      "postDate": "07/13/2011 23:00:06",
      "content": "<p>Here are some test vectors in unit test style:</p>\r\n<pre>[Test]<br>public void GiniTest() {<br>    // Sanity check:<br>    AssertGini(new[] { 1.0, 2, 3 }, new[] { 10.0, 20, 30 }, 0.111111111111111, 1.0);<br>    AssertGini(new[] { 1.0, 2, 3 }, new[] { 30.0, 20, 10 }, -0.111111111111111, -1.0);<br>            <br>    // Verify primary sort is descending on prediction and secondary sort is ascending based on index of original list<br>    AssertGini(new[] { 1.0, 2, 3 }, new[] { 0.0, 0, 0 }, -0.111111111111111, -1.0);<br>    AssertGini(new[] { 3.0, 2, 1 }, new[] { 0.0, 0, 0 }, 0.111111111111111, 1.0);<br><br>    AssertGini(new[] { 1.0, 2, 4, 3 }, new[] { 0.0, 0, 0, 0 }, -0.1, -0.8);<br>    AssertGini(new[] { 2.0, 1, 4, 3 }, new[] { 0.0, 0.0, 2, 1 }, 0.125, 1.0);<br><br>    // Verified against Excel:<br>    AssertGini(new[] { 0.0, 20, 40, 0, 10}, new[] {40.0, 40.0, 10.0, 5, 5}, 0.0, 0.0);<br>    AssertGini(new[] { 40.0, 0, 20, 0, 10 }, new[] { 1000000.0, 40, 40, 5, 5 }, 0.17142857, 0.60 );<br>    AssertGini(new[] { 40.0, 20, 10, 0, 0 }, new[] { 40.0, 20, 10, 0, 0 }, 0.28571429, 1.00);<br>    AssertGini(new[] { 1.0, 1.0, 0.0, 1.0}, new[] {0.86, 0.26, 0.52, 0.32}, -0.04166667, -0.33333333);<br>}<br><br>private const double ErrorTolerance = 1e-6;<br><br>private static void AssertGini(IList&lt;double&gt; actuals, IList&lt;double&gt; predictions, double expectedGini, double expectedNormalizedGini ) {<br>    var gini = actuals.Gini(predictions);<br>    Assert.AreEqual(expectedGini, gini, ErrorTolerance);<br><br>    var normalizedGini = actuals.GiniNormalized(predictions);<br>    Assert.AreEqual(expectedNormalizedGini, normalizedGini, ErrorTolerance);<br>}</pre>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4593",
      "postDate": "07/14/2011 09:28:01",
      "content": "<p>So my implementation was correct. Here is a C&#43;&#43; version for the test code:</p>\r\n<pre>void GiniTest() {<br>&nbsp; auto T = [](const std::vector&lt;double&gt; &amp;a, decltype(a) p, double g, double n) {<br>&nbsp;&nbsp;&nbsp; auto E = [](double a, double b, double e=1e-6) {return fabs(a-b) &lt;= e;};<br>&nbsp;&nbsp;&nbsp; assert(E(Gini(a, p), g) &amp;&amp; E(GiniNormalized(a, p), n));<br>&nbsp; };<br>&nbsp; T({1, 2, 3}, {10, 20, 30}, 0.111111, 1);<br>&nbsp; T({1, 2, 3}, {30, 20, 10}, -0.111111, -1);<br>&nbsp; T({1, 2, 3}, {0, 0, 0}, -0.111111, -1);<br>&nbsp; T({3, 2, 1}, {0, 0, 0}, 0.111111, 1);<br>&nbsp; T({1, 2, 4, 3}, {0, 0, 0, 0}, -0.1, -0.8);<br>&nbsp; T({2, 1, 4, 3}, {0, 0, 2, 1}, 0.125, 1);<br>&nbsp; T({0, 20, 40, 0, 10}, {40, 40, 10, 5, 5}, 0, 0);<br>&nbsp; T({40, 0, 20, 0, 10}, {1000000, 40, 40, 5, 5}, 0.171428, 0.6);<br>&nbsp; T({40, 20, 10, 0, 0}, {40, 20, 10, 0, 0}, 0.285714, 1);<br>&nbsp; T({1, 1, 0, 1}, {0.86, 0.26, 0.52, 0.32}, -0.041666, -0.333333);<br>}</pre>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4622",
      "postDate": "07/15/2011 16:10:57",
      "content": "<p>Don't know if I understand this correctly, but can't you get rid of the accumulatedPopulationPercentageSum term and just subtract 0.5 from the final gini in Gini() function ? Intuitively it makes sense because you're removing the 0.5 area under the diagonal\r\n line.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4623",
      "postDate": "07/15/2011 16:29:28",
      "content": "<p>[quote=B Yang;4622]</p>\r\n<p>Don't know if I understand this correctly, but can't you get rid of the accumulatedPopulationPercentageSum term and just subtract 0.5 from the final gini in Gini() function ? Intuitively it makes sense because you're removing the 0.5 area under the diagonal\r\n line.</p>\r\n<p>[/quote]</p>\r\n<p>Good observation! The inner loop is subtracting each term of this sum:</p>\r\n<p>\\[ \\frac{1}{n} &#43; \\frac{2}{n} &#43; \\ldots &#43; \\frac{n-2}{n} &#43; \\frac{n-1}{n} &#43; \\frac{n}{n} = \\sum_{k=1}^n \\frac{k}{n} = \\frac{n&#43;1}{2}&nbsp;\\]</p>\r\n<p>Thus, if you got rid of that term in the inner loop, you'd have to subtract out \\\\(\\frac{n&#43;1}{2}\\\\) which would give you this equivalent code:</p>\r\n<pre>public static double Gini(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    if(a.Count != p.Count) {<br>        throw new ArgumentException();<br>    }<br><br>    var all =<br>            p.Zip(a, (pred, actual) =&gt; new { actualValue = actual, predictedValue = pred }) // (actual, prediction)<br>            .Zip(Enumerable.Range(1, a.Count), (ap, i) =&gt; new { ap.actualValue, ap.predictedValue, originalIndex = i })<br>            .OrderByDescending(ap =&gt; ap.predictedValue) // important to sort descending by prediction<br>            .ThenBy(ap =&gt; ap.originalIndex); // secondary sorts to ensure unambigious orders<br>            <br>    var totalActualLosses = a.Sum(); <br>            <br>    double accumulatedLossPercentageSum = 0;<br><br>    double giniSum = 0.0;<br><br>    foreach(var currentPair in all) {<br>        accumulatedLossPercentageSum &#43;= (currentPair.actualValue/totalActualLosses);<br>        giniSum &#43;= accumulatedLossPercentageSum;<br>    }<br><br>    // Subtract out the null model<br>    giniSum -= (a.Count &#43; 1.0)/2;<br><br>    var gini = giniSum/a.Count;<br>    return gini;<br>}<br><br>public static double GiniNormalized(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    return a.Gini(p)/(a.Gini(a));<br>}</pre>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4677",
      "postDate": "07/21/2011 08:22:30",
      "content": "<p>Here is Chris' R function updated with Jeff's feedback. Thanks to you both.</p>\r\n<pre><span style=\"font-family:courier new,courier\">normalizedGini &lt;- function(aa, pp) {</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp; Gini &lt;- function(a, p) {</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (length(a) !=&nbsp; length(p)) stop(&quot;Actual and Predicted need to be equal lengths!&quot;)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.df &lt;- data.frame(actual = a, pred = p, range=c(1:length(a)))</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.df &lt;- temp.df[order(-temp.df$pred, temp.df$range),]</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; population.delta &lt;- 1 / length(a)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total.losses &lt;- sum(a)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null.losses &lt;- rep(population.delta, length(a)) # Hopefully is similar to accumulatedPopulationPercentageSum</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accum.losses &lt;- temp.df$actual / total.losses # Hopefully is similar to accumulatedLossPercentageSum</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gini.sum &lt;- cumsum(accum.losses - null.losses) # Not sure if this is having the same effect or not</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum(gini.sum) / length(a)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp; }</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp; Gini(aa,pp) / Gini(aa,aa)</span><br><span style=\"font-family:courier new,courier\">}</span></pre>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4766",
      "postDate": "07/27/2011 13:40:19",
      "content": "<p>Hi Sami,</p>\r\n<p>I was wondering if you could share the whole C&#43;&#43; file (with a main) ? I should probably fill this gap by myself, but I haven't written C&#43;&#43; in more years than I want to acknowledge :P</p>\r\n<p>Thanks,</p>\r\n<p>Jose</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4767",
      "postDate": "07/27/2011 13:45:10",
      "content": "<p>Jeff,&nbsp;what is <em>a</em> and <em>p</em>? :-)</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "4769",
      "postDate": "07/27/2011 14:13:02",
      "content": "<p>[quote=Jose ;4767]</p>\r\n<p>Jeff,&nbsp;what is <em>a</em> and <em>p</em>? :-)</p>\r\n<p>[/quote]</p>\r\n<p>actual values (solution) and predicted values (your submission) respectively</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "5183",
      "postDate": "08/19/2011 16:16:42",
      "content": "<p>which version of Gcc did you use to compile your code?</p>\r\n<p>I could not compile yours with gcc4.5</p>\r\n<p>&nbsp;</p>\r\n<p>Thanks!</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "5344",
      "postDate": "08/28/2011 20:18:32",
      "content": "<p>#include &lt;vector&gt;<br>\r\n#include &lt;algorithm&gt;<br>\r\n#include &lt;assert.h&gt;<br>\r\n<br>\r\ndouble Gini(const std::vector&lt;double&gt; &amp;a, decltype(a) &amp;p) {<br>\r\n&nbsp; assert(a.size() == p.size());<br>\r\n<br>\r\n&nbsp; // k[i] = { a[i],&nbsp; p[i] };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; struct K {double a, p;} k[a.size()];<br>\r\n&nbsp; for (auto i = 0; i != a.size(); &#43;&#43;i) k[i] = {a[i], p[i]};<br>\r\n<br>\r\n&nbsp; // sort(k) by descending p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; std::stable_sort(k, k&#43;a.size(), [](const K &amp;a, const K &amp;b) {return a.p &gt; b.p;});<br>\r\n<br>\r\n&nbsp; double accPopPercSum=0, accLossPercSum=0, giniSum=0, sum=0;<br>\r\n<br>\r\n&nbsp; // sum = accum(a);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; // or total actual sum&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; for (auto &amp;i: a) sum &#43;= i;<br>\r\n<br>\r\n&nbsp; // accLossPercSum = accum(i.a / sum);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n//&nbsp;&nbsp; for (auto &amp;i: k) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; for (unsigned int fu = 0; fu &lt; a.size(); &#43;&#43;fu) {<br>\r\n&nbsp;&nbsp;&nbsp; struct K&amp; i = k[fu];<br>\r\n&nbsp;&nbsp;&nbsp; accLossPercSum &#43;= i.a/sum;<br>\r\n&nbsp;&nbsp;&nbsp; accPopPercSum &#43;= 1.0/a.size();<br>\r\n&nbsp;&nbsp;&nbsp; giniSum &#43;= accLossPercSum - accPopPercSum;<br>\r\n&nbsp; }<br>\r\n<br>\r\n&nbsp; return giniSum/a.size();<br>\r\n}<br>\r\n<br>\r\ndouble GiniNormalized(const std::vector&lt;double&gt; &amp;a, decltype(a) &amp;p) {<br>\r\n&nbsp; return Gini(a, p)/Gini(a, a);<br>\r\n}</p>\r\n<p>void GiniTest() {<br>\r\n&nbsp; auto T = [](const std::vector&lt;double&gt; &amp;a, decltype(a) p, double g, double n) {<br>\r\n&nbsp;&nbsp;&nbsp; auto E = [](double a, double b, double e=1e-6) {return fabs(a-b) &lt;= e;};<br>\r\n&nbsp;&nbsp;&nbsp; assert(E(Gini(a, p), g) &amp;&amp; E(GiniNormalized(a, p), n));<br>\r\n&nbsp; };<br>\r\n&nbsp; T({1, 2, 3}, {10, 20, 30}, 0.111111, 1);<br>\r\n&nbsp; T({1, 2, 3}, {30, 20, 10}, -0.111111, -1);<br>\r\n&nbsp; T({1, 2, 3}, {0, 0, 0}, -0.111111, -1);<br>\r\n&nbsp; T({3, 2, 1}, {0, 0, 0}, 0.111111, 1);<br>\r\n&nbsp; T({1, 2, 4, 3}, {0, 0, 0, 0}, -0.1, -0.8);<br>\r\n&nbsp; T({2, 1, 4, 3}, {0, 0, 2, 1}, 0.125, 1);<br>\r\n&nbsp; T({0, 20, 40, 0, 10}, {40, 40, 10, 5, 5}, 0, 0);<br>\r\n&nbsp; T({40, 0, 20, 0, 10}, {1000000, 40, 40, 5, 5}, 0.171428, 0.6);<br>\r\n&nbsp; T({40, 20, 10, 0, 0}, {40, 20, 10, 0, 0}, 0.285714, 1);<br>\r\n&nbsp; T({1, 1, 0, 1}, {0.86, 0.26, 0.52, 0.32}, -0.041666, -0.333333);<br>\r\n}<br>\r\n<br>\r\nint main(int ac, char** av)<br>\r\n{<br>\r\n&nbsp; GiniTest();<br>\r\n}</p>\r\n<p>compile with:</p>\r\n<p>g&#43;&#43;-4.6 -std=c&#43;&#43;0x gini.cc</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "5345",
      "postDate": "08/28/2011 20:38:23",
      "content": "<p>note that you can move the division outside the loop:</p>\r\n<p>&nbsp; for (unsigned int fu = 0; fu &lt; a.size(); &#43;&#43;fu) {<br>\r\n&nbsp;&nbsp;&nbsp; struct K&amp; i = k[fu];<br>\r\n&nbsp;&nbsp;&nbsp; accLossPercSum &#43;= i.a;<br>\r\n&nbsp;&nbsp;&nbsp; giniSum &#43;= accLossPercSum;<br>\r\n&nbsp; }<br>\r\n<br>\r\n&nbsp; giniSum = giniSum / sum - (a.size() &#43; 1.0) / 2;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "5354",
      "postDate": "08/30/2011 01:07:44",
      "content": "<p>Anyone have a Java version they care to share? I've tried to understand these &quot;foreign&quot; language examples but not getting to far. I fear I will produce my solution but be unable to submit it for consideration....</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "5897",
      "postDate": "10/04/2011 21:25:59",
      "content": "<blockquote>\r\n<pre class=\"x_x_x_prettyprint\">def gini(actual, pred, cmpcol = 0, sortcol = 1):<br> &nbsp;&nbsp;&nbsp; assert( len(actual) == len(pred) )<br> &nbsp;&nbsp;&nbsp; all = np.asarray(np.c_[ actual, pred, np.arange(len(actual)) ], dtype=np.float)<br> &nbsp;&nbsp;&nbsp; all = all[ np.lexsort((all[:,2], -1*all[:,1])) ]<br> &nbsp;&nbsp;&nbsp; totalLosses = all[:,0].sum()<br> &nbsp;&nbsp;&nbsp; giniSum = all[:,0].cumsum().sum() / totalLosses<br> <br> &nbsp;&nbsp;&nbsp; giniSum -= (len(actual) &#43; 1) / 2.<br> &nbsp;&nbsp;&nbsp; return giniSum / len(actual)<br> <br> def gini_normalized(a, p):<br> &nbsp;&nbsp;&nbsp; return gini(a, p) / gini(a, a)<br> <br> def test_gini():<br> &nbsp;&nbsp;&nbsp; def fequ(a,b):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return abs( a -b) &lt; 1e-6<br> &nbsp;&nbsp;&nbsp; def T(a, p, g, n):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert( fequ(gini(a,p), g) )<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert( fequ(gini_normalized(a,p), n) )<br> &nbsp;&nbsp;&nbsp; T([1, 2, 3], [10, 20, 30], 0.111111, 1)<br> &nbsp;&nbsp;&nbsp; T([1, 2, 3], [30, 20, 10], -0.111111, -1)<br> &nbsp;&nbsp;&nbsp; T([1, 2, 3], [0, 0, 0], -0.111111, -1)<br> &nbsp;&nbsp;&nbsp; T([3, 2, 1], [0, 0, 0], 0.111111, 1)<br> &nbsp;&nbsp;&nbsp; T([1, 2, 4, 3], [0, 0, 0, 0], -0.1, -0.8)<br> &nbsp;&nbsp;&nbsp; T([2, 1, 4, 3], [0, 0, 2, 1], 0.125, 1)<br> &nbsp;&nbsp;&nbsp; T([0, 20, 40, 0, 10], [40, 40, 10, 5, 5], 0, 0)<br> &nbsp;&nbsp;&nbsp; T([40, 0, 20, 0, 10], [1000000, 40, 40, 5, 5], 0.171428,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.6)<br> &nbsp;&nbsp;&nbsp; T([40, 20, 10, 0, 0], [40, 20, 10, 0, 0], 0.285714, 1)<br> &nbsp;&nbsp;&nbsp; T([1, 1, 0, 1], [0.86, 0.26, 0.52, 0.32], -0.041666,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.333333)</pre>\r\n</blockquote>\r\n<p>Python code for anyone interested.&nbsp; It assumes you're working in numpy, because if you're not it would probably take forever and a day to finish.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "44646",
      "postDate": "05/16/2014 01:09:13",
      "content": "<p>Has anyone in the community figured out R code to create the plot of the Gini.&nbsp; I have been trying like crazy but I am not sure if I am doing it right.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "226658",
      "postDate": "10/02/2017 22:14:09",
      "content": "",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "235814",
      "postDate": "10/26/2017 04:40:09",
      "content": "<p>You likely would want to use a class to accumulate the values but here is a working Java ver:</p>\n\n<pre><code>    public static double getGini2(List&lt;Double&gt; a, List&lt;Double&gt; p) {\n\n    if(a.size() != p.size())\n        throw new IllegalArgumentException(\"a.sz=\"+a.size()+\" != p.sz=\"+p.size());\n\n    List&lt;double[]&gt; list=new ArrayList&lt;&gt;();\n\n    int sz=a.size();\n    double sum=0;\n    for (int i = 0; i != sz; ++i) {\n        list.add(new double[] {a.get(i), p.get(i)}); // add tuple {act, pred}\n        sum+=a.get(i); // while we're at it...\n    }\n\n    Comparator&lt;double[]&gt; compEstDsc=new Comparator&lt;double[]&gt;() {\n        @Override\n        public int compare(double[] o1, double[] o2) {\n            double v1=o1[1]; // only use prediction\n            double v2=o2[1];\n            return UtilComparator.compareDoubleDesc(v1, v2);\n        }\n    };\n    list.sort(compEstDsc);\n\n    double accPopPercSum=0;\n    double accLossPercSum=0;\n    double giniSum=0;\n\n    for (int i = 0; i &lt; sz; ++i) {\n\n        double[] a0p1 = list.get(i);\n\n        accLossPercSum += a0p1[0]/sum; // only use act\n\n        accPopPercSum += 1.0/sz;\n\n        giniSum += accLossPercSum - accPopPercSum;\n    }\n\n    return giniSum/sz;\n}\n\npublic static double getGini2Normalized(List&lt;Double&gt; a, List&lt;Double&gt; p) {\n    return getGini2(a, p)/getGini2(a, a);\n}\n</code></pre>",
      "rawMarkdown": "You likely would want to use a class to accumulate the values but here is a working Java ver:\n\n    \tpublic static double getGini2(List",
      "votes": null
    },
    {
      "id": "242481",
      "postDate": "11/11/2017 17:33:17",
      "content": "<p>Thanks for posting this! Looks like the parameters cmpcol sortcol are not being used ?</p>",
      "rawMarkdown": "Thanks for posting this! Looks like the parameters cmpcol sortcol are not being used ?",
      "votes": null
    },
    {
      "id": "247248",
      "postDate": "11/22/2017 16:47:25",
      "content": "<p>Here's a Python implementation with TensorFlow. Expects <code>actual</code> and <code>pred</code> to be a (1, N) tensor.</p>\n\n<pre><code>def gini_normalized(actual, pred):\n    n = tf.shape(actual)[1]\n    indices = tf.nn.top_k(pred, k=n)[1][0]\n    actual_sorted = tf.gather(actual[0], indices)\n    cost = tf.reduce_sum(actual_sorted)\n    loss_proportion = tf.cumsum(actual_sorted) / cost\n    null_model = tf.to_float(tf.range(1, n + 1)) / tf.to_float(n)\n    g = tf.subtract(loss_proportion, null_model)\n    g = tf.reduce_sum(g) / tf.to_float(n)\n    g /= (1.0 - tf.reduce_mean(actual)) / 2.0\n    return g\n</code></pre>",
      "rawMarkdown": "Here's a Python implementation with TensorFlow. Expects `actual` and `pred` to be a (1, N) tensor.\n\n    def gini_normalized(actual, pred):\n        n = tf.shape(actual)[1]\n        indices = tf.nn.top_k(pred, k=n)[1][0]\n        actual_sorted = tf.gather(actual[0], indices)\n        cost = tf.reduce_sum(actual_sorted)\n        loss_proportion = tf.cumsum(actual_sorted) / cost\n        null_model = tf.to_float(tf.range(1, n + 1)) / tf.to_float(n)\n        g = tf.subtract(loss_proportion, null_model)\n        g = tf.reduce_sum(g) / tf.to_float(n)\n        g /= (1.0 - tf.reduce_mean(actual)) / 2.0\n        return g",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 4573,
      "author_name": "chrisraimondi",
      "author_url": "",
      "post_date": "07/13/2011 18:04:23",
      "content": "<p>Hi Jeff!</p>\r\n<p>I don't know C code, but I tried to read it and made some educated guesses in order to try and make an R function (good practice for me&nbsp; - as I generally hate reading code).</p>\r\n<p>Anyway - can you tell me if I am on the right track:</p>\r\n<p>normalizedGini &lt;- function(aa, pp){<br>\r\nGini &lt;- function(a, p){<br>\r\n&nbsp; if(length(a) !=&nbsp; length(p)) stop(&quot;Actual and Predicted need to be equal lengths!&quot;)<br>\r\n&nbsp; temp.df &lt;- data.frame(actual = a, pred = p, range=c(1:length(a)))<br>\r\n&nbsp; temp.df &lt;- temp.df[order(temp.df$pred, temp.df$range, decreasing=TRUE),]<br>\r\n&nbsp; population.delta &lt;- 1 / length(a)<br>\r\n&nbsp; total.losses &lt;- sum(a)<br>\r\n&nbsp; null.losses &lt;- rep(population.delta, length(a)) # Hopefully is similar to accumulatedPopulationPercentageSum<br>\r\n&nbsp; accum.losses &lt;- temp.df$actual / total.losses # Hopefully is similar to accumulatedLossPercentageSum<br>\r\n&nbsp; gini.sum &lt;- cumsum(accum.losses - null.losses) # Not sure if this is having the same effect or not<br>\r\n&nbsp; sum(gini.sum)<br>\r\n}<br>\r\nGini(aa,pp) / Gini(aa,aa)<br>\r\n}</p>\r\n<p>I get:</p>\r\n<pre class=\"x_GD40030CKR\" style=\"font-family:'Lucida Console'; font-size:10pt!important; outline-style:none; border-style:none; white-space:pre-wrap!important; margin:0px; line-height:1.3\"><span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:1000, 1:1000) </span><br>[1] 1\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:1000, 99001:100000) </span><br>[1] 1\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:1000, 1000:1) <br></span>[1] -1\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(1:10000, runif(10000)) # Should be close to zero </span><br>[1] 0.01671304\r\n<span class=\"x_GD40030CNR x_ace_keyword\" style=\"white-space:pre; color:blue\">&gt; </span><span class=\"x_GD40030CBR x_ace_keyword\" style=\"color:blue\">normalizedGini(cars$Claim_Amount[1:1000000], cars$Var1[1:1000000]) </span>#First million rows of training set<br>[1] -0.03384947<br><br>Thanks!</pre>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4574,
      "author_name": "jeffmoser",
      "author_url": "",
      "post_date": "07/13/2011 18:58:11",
      "content": "<p>Hi Chris,</p>\r\n<p>Two observations:</p>\r\n<ol>\r\n<li>Be sure to sort by predictions <strong>descending</strong> and then in the case of ties, sort by the original order\r\n<strong>ascending</strong>. It looks like you did descending on both. </li><li>Be sure to return the average value gini.Sum / length(a) instead of the sum itself.\r\n</li></ol>\r\n<div>I'm setting up a new machine at the moment, but when it's ready I should be able to create some sample values for you to test against.</div>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4575,
      "author_name": "sashikanthdareddy",
      "author_url": "",
      "post_date": "07/13/2011 19:43:35",
      "content": "<p>You may find this doc helpful.<br>\r\nhttp://www.rhinorisk.com/Publications/Gini%20Coefficients.pdf</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4577,
      "author_name": "sashikanthdareddy",
      "author_url": "",
      "post_date": "07/13/2011 20:02:55",
      "content": "<p>Jeff, where do you get the perfect model?</p>\r\n<p>From the graph, the perfect model should have a gini of 100 or the top left corner.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4578,
      "author_name": "jeffmoser",
      "author_url": "",
      "post_date": "07/13/2011 20:05:39",
      "content": "<p>[quote=Sashi;4577]</p>\r\n<p>Jeff, where do you get the perfect model?</p>\r\n<p>[/quote]</p>\r\n<p>The perfect model is the solution itself.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4579,
      "author_name": "sami6019",
      "author_url": "",
      "post_date": "07/13/2011 20:29:32",
      "content": "<p>@Jeff:</p>\r\n<p>Thanks for posting the code. I will wait for the test cases to verify my implementation.</p>\r\n<p>Here is my C&#43;&#43; implementation.</p>\r\n<pre>double Gini(const std::vector &amp;a, decltype(a) &amp;p) {<br>  assert(a.size() == p.size());<br>&nbsp; struct K {double a, p;} k[a.size()];<br>&nbsp; for (auto i = 0; i != a.size(); &#43;&#43;i) k[i] = {a[i], p[i]};<br>&nbsp; std::stable_sort(k, k&#43;a.size(), [](const K &amp;a, const K &amp;b) {return a.p &gt; b.p;});<br>&nbsp; double accPopPercSum=0, accLossPercSum=0, giniSum=0, sum=0;<br>&nbsp; for (auto &amp;i: a) sum &#43;= i;<br>&nbsp; for (auto &amp;i: k) {<br>&nbsp;&nbsp;&nbsp;&nbsp; accLossPercSum &#43;= i.a/sum;<br>&nbsp;&nbsp;&nbsp;&nbsp; accPopPercSum &#43;= 1.0/a.size();<br>&nbsp;&nbsp;&nbsp;&nbsp; giniSum &#43;= accLossPercSum-accPopPercSum;<br>&nbsp; }<br>&nbsp; return giniSum/a.size();<br>}<br>double GiniNormalized(const std::vector &amp;a, decltype(a) &amp;p) {<br>&nbsp; return Gini(a, p)/Gini(a, a);<br>}</pre>\r\n<p>std::cout &lt;&lt; GiniNormalized({3,1,2,4,0}, {3,2,0,4,1}) //returns 0.7</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4580,
      "author_name": "jeffmoser",
      "author_url": "",
      "post_date": "07/13/2011 23:00:06",
      "content": "<p>Here are some test vectors in unit test style:</p>\r\n<pre>[Test]<br>public void GiniTest() {<br>    // Sanity check:<br>    AssertGini(new[] { 1.0, 2, 3 }, new[] { 10.0, 20, 30 }, 0.111111111111111, 1.0);<br>    AssertGini(new[] { 1.0, 2, 3 }, new[] { 30.0, 20, 10 }, -0.111111111111111, -1.0);<br>            <br>    // Verify primary sort is descending on prediction and secondary sort is ascending based on index of original list<br>    AssertGini(new[] { 1.0, 2, 3 }, new[] { 0.0, 0, 0 }, -0.111111111111111, -1.0);<br>    AssertGini(new[] { 3.0, 2, 1 }, new[] { 0.0, 0, 0 }, 0.111111111111111, 1.0);<br><br>    AssertGini(new[] { 1.0, 2, 4, 3 }, new[] { 0.0, 0, 0, 0 }, -0.1, -0.8);<br>    AssertGini(new[] { 2.0, 1, 4, 3 }, new[] { 0.0, 0.0, 2, 1 }, 0.125, 1.0);<br><br>    // Verified against Excel:<br>    AssertGini(new[] { 0.0, 20, 40, 0, 10}, new[] {40.0, 40.0, 10.0, 5, 5}, 0.0, 0.0);<br>    AssertGini(new[] { 40.0, 0, 20, 0, 10 }, new[] { 1000000.0, 40, 40, 5, 5 }, 0.17142857, 0.60 );<br>    AssertGini(new[] { 40.0, 20, 10, 0, 0 }, new[] { 40.0, 20, 10, 0, 0 }, 0.28571429, 1.00);<br>    AssertGini(new[] { 1.0, 1.0, 0.0, 1.0}, new[] {0.86, 0.26, 0.52, 0.32}, -0.04166667, -0.33333333);<br>}<br><br>private const double ErrorTolerance = 1e-6;<br><br>private static void AssertGini(IList&lt;double&gt; actuals, IList&lt;double&gt; predictions, double expectedGini, double expectedNormalizedGini ) {<br>    var gini = actuals.Gini(predictions);<br>    Assert.AreEqual(expectedGini, gini, ErrorTolerance);<br><br>    var normalizedGini = actuals.GiniNormalized(predictions);<br>    Assert.AreEqual(expectedNormalizedGini, normalizedGini, ErrorTolerance);<br>}</pre>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4593,
      "author_name": "sami6019",
      "author_url": "",
      "post_date": "07/14/2011 09:28:01",
      "content": "<p>So my implementation was correct. Here is a C&#43;&#43; version for the test code:</p>\r\n<pre>void GiniTest() {<br>&nbsp; auto T = [](const std::vector&lt;double&gt; &amp;a, decltype(a) p, double g, double n) {<br>&nbsp;&nbsp;&nbsp; auto E = [](double a, double b, double e=1e-6) {return fabs(a-b) &lt;= e;};<br>&nbsp;&nbsp;&nbsp; assert(E(Gini(a, p), g) &amp;&amp; E(GiniNormalized(a, p), n));<br>&nbsp; };<br>&nbsp; T({1, 2, 3}, {10, 20, 30}, 0.111111, 1);<br>&nbsp; T({1, 2, 3}, {30, 20, 10}, -0.111111, -1);<br>&nbsp; T({1, 2, 3}, {0, 0, 0}, -0.111111, -1);<br>&nbsp; T({3, 2, 1}, {0, 0, 0}, 0.111111, 1);<br>&nbsp; T({1, 2, 4, 3}, {0, 0, 0, 0}, -0.1, -0.8);<br>&nbsp; T({2, 1, 4, 3}, {0, 0, 2, 1}, 0.125, 1);<br>&nbsp; T({0, 20, 40, 0, 10}, {40, 40, 10, 5, 5}, 0, 0);<br>&nbsp; T({40, 0, 20, 0, 10}, {1000000, 40, 40, 5, 5}, 0.171428, 0.6);<br>&nbsp; T({40, 20, 10, 0, 0}, {40, 20, 10, 0, 0}, 0.285714, 1);<br>&nbsp; T({1, 1, 0, 1}, {0.86, 0.26, 0.52, 0.32}, -0.041666, -0.333333);<br>}</pre>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4622,
      "author_name": "byang1",
      "author_url": "",
      "post_date": "07/15/2011 16:10:57",
      "content": "<p>Don't know if I understand this correctly, but can't you get rid of the accumulatedPopulationPercentageSum term and just subtract 0.5 from the final gini in Gini() function ? Intuitively it makes sense because you're removing the 0.5 area under the diagonal\r\n line.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4623,
      "author_name": "jeffmoser",
      "author_url": "",
      "post_date": "07/15/2011 16:29:28",
      "content": "<p>[quote=B Yang;4622]</p>\r\n<p>Don't know if I understand this correctly, but can't you get rid of the accumulatedPopulationPercentageSum term and just subtract 0.5 from the final gini in Gini() function ? Intuitively it makes sense because you're removing the 0.5 area under the diagonal\r\n line.</p>\r\n<p>[/quote]</p>\r\n<p>Good observation! The inner loop is subtracting each term of this sum:</p>\r\n<p>\\[ \\frac{1}{n} &#43; \\frac{2}{n} &#43; \\ldots &#43; \\frac{n-2}{n} &#43; \\frac{n-1}{n} &#43; \\frac{n}{n} = \\sum_{k=1}^n \\frac{k}{n} = \\frac{n&#43;1}{2}&nbsp;\\]</p>\r\n<p>Thus, if you got rid of that term in the inner loop, you'd have to subtract out \\\\(\\frac{n&#43;1}{2}\\\\) which would give you this equivalent code:</p>\r\n<pre>public static double Gini(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    if(a.Count != p.Count) {<br>        throw new ArgumentException();<br>    }<br><br>    var all =<br>            p.Zip(a, (pred, actual) =&gt; new { actualValue = actual, predictedValue = pred }) // (actual, prediction)<br>            .Zip(Enumerable.Range(1, a.Count), (ap, i) =&gt; new { ap.actualValue, ap.predictedValue, originalIndex = i })<br>            .OrderByDescending(ap =&gt; ap.predictedValue) // important to sort descending by prediction<br>            .ThenBy(ap =&gt; ap.originalIndex); // secondary sorts to ensure unambigious orders<br>            <br>    var totalActualLosses = a.Sum(); <br>            <br>    double accumulatedLossPercentageSum = 0;<br><br>    double giniSum = 0.0;<br><br>    foreach(var currentPair in all) {<br>        accumulatedLossPercentageSum &#43;= (currentPair.actualValue/totalActualLosses);<br>        giniSum &#43;= accumulatedLossPercentageSum;<br>    }<br><br>    // Subtract out the null model<br>    giniSum -= (a.Count &#43; 1.0)/2;<br><br>    var gini = giniSum/a.Count;<br>    return gini;<br>}<br><br>public static double GiniNormalized(this IList&lt;double&gt; a, IList&lt;double&gt; p) {<br>    return a.Gini(p)/(a.Gini(a));<br>}</pre>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4677,
      "author_name": "markwaddle",
      "author_url": "",
      "post_date": "07/21/2011 08:22:30",
      "content": "<p>Here is Chris' R function updated with Jeff's feedback. Thanks to you both.</p>\r\n<pre><span style=\"font-family:courier new,courier\">normalizedGini &lt;- function(aa, pp) {</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp; Gini &lt;- function(a, p) {</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (length(a) !=&nbsp; length(p)) stop(&quot;Actual and Predicted need to be equal lengths!&quot;)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.df &lt;- data.frame(actual = a, pred = p, range=c(1:length(a)))</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.df &lt;- temp.df[order(-temp.df$pred, temp.df$range),]</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; population.delta &lt;- 1 / length(a)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total.losses &lt;- sum(a)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null.losses &lt;- rep(population.delta, length(a)) # Hopefully is similar to accumulatedPopulationPercentageSum</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accum.losses &lt;- temp.df$actual / total.losses # Hopefully is similar to accumulatedLossPercentageSum</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gini.sum &lt;- cumsum(accum.losses - null.losses) # Not sure if this is having the same effect or not</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum(gini.sum) / length(a)</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp; }</span><br><span style=\"font-family:courier new,courier\">&nbsp;&nbsp;&nbsp; Gini(aa,pp) / Gini(aa,aa)</span><br><span style=\"font-family:courier new,courier\">}</span></pre>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4766,
      "author_name": "tropics",
      "author_url": "",
      "post_date": "07/27/2011 13:40:19",
      "content": "<p>Hi Sami,</p>\r\n<p>I was wondering if you could share the whole C&#43;&#43; file (with a main) ? I should probably fill this gap by myself, but I haven't written C&#43;&#43; in more years than I want to acknowledge :P</p>\r\n<p>Thanks,</p>\r\n<p>Jose</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4767,
      "author_name": "tropics",
      "author_url": "",
      "post_date": "07/27/2011 13:45:10",
      "content": "<p>Jeff,&nbsp;what is <em>a</em> and <em>p</em>? :-)</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 4769,
      "author_name": "jeffmoser",
      "author_url": "",
      "post_date": "07/27/2011 14:13:02",
      "content": "<p>[quote=Jose ;4767]</p>\r\n<p>Jeff,&nbsp;what is <em>a</em> and <em>p</em>? :-)</p>\r\n<p>[/quote]</p>\r\n<p>actual values (solution) and predicted values (your submission) respectively</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 5183,
      "author_name": "woshialex",
      "author_url": "",
      "post_date": "08/19/2011 16:16:42",
      "content": "<p>which version of Gcc did you use to compile your code?</p>\r\n<p>I could not compile yours with gcc4.5</p>\r\n<p>&nbsp;</p>\r\n<p>Thanks!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 5344,
      "author_name": "texane",
      "author_url": "",
      "post_date": "08/28/2011 20:18:32",
      "content": "<p>#include &lt;vector&gt;<br>\r\n#include &lt;algorithm&gt;<br>\r\n#include &lt;assert.h&gt;<br>\r\n<br>\r\ndouble Gini(const std::vector&lt;double&gt; &amp;a, decltype(a) &amp;p) {<br>\r\n&nbsp; assert(a.size() == p.size());<br>\r\n<br>\r\n&nbsp; // k[i] = { a[i],&nbsp; p[i] };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; struct K {double a, p;} k[a.size()];<br>\r\n&nbsp; for (auto i = 0; i != a.size(); &#43;&#43;i) k[i] = {a[i], p[i]};<br>\r\n<br>\r\n&nbsp; // sort(k) by descending p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; std::stable_sort(k, k&#43;a.size(), [](const K &amp;a, const K &amp;b) {return a.p &gt; b.p;});<br>\r\n<br>\r\n&nbsp; double accPopPercSum=0, accLossPercSum=0, giniSum=0, sum=0;<br>\r\n<br>\r\n&nbsp; // sum = accum(a);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; // or total actual sum&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; for (auto &amp;i: a) sum &#43;= i;<br>\r\n<br>\r\n&nbsp; // accLossPercSum = accum(i.a / sum);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n//&nbsp;&nbsp; for (auto &amp;i: k) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>\r\n&nbsp; for (unsigned int fu = 0; fu &lt; a.size(); &#43;&#43;fu) {<br>\r\n&nbsp;&nbsp;&nbsp; struct K&amp; i = k[fu];<br>\r\n&nbsp;&nbsp;&nbsp; accLossPercSum &#43;= i.a/sum;<br>\r\n&nbsp;&nbsp;&nbsp; accPopPercSum &#43;= 1.0/a.size();<br>\r\n&nbsp;&nbsp;&nbsp; giniSum &#43;= accLossPercSum - accPopPercSum;<br>\r\n&nbsp; }<br>\r\n<br>\r\n&nbsp; return giniSum/a.size();<br>\r\n}<br>\r\n<br>\r\ndouble GiniNormalized(const std::vector&lt;double&gt; &amp;a, decltype(a) &amp;p) {<br>\r\n&nbsp; return Gini(a, p)/Gini(a, a);<br>\r\n}</p>\r\n<p>void GiniTest() {<br>\r\n&nbsp; auto T = [](const std::vector&lt;double&gt; &amp;a, decltype(a) p, double g, double n) {<br>\r\n&nbsp;&nbsp;&nbsp; auto E = [](double a, double b, double e=1e-6) {return fabs(a-b) &lt;= e;};<br>\r\n&nbsp;&nbsp;&nbsp; assert(E(Gini(a, p), g) &amp;&amp; E(GiniNormalized(a, p), n));<br>\r\n&nbsp; };<br>\r\n&nbsp; T({1, 2, 3}, {10, 20, 30}, 0.111111, 1);<br>\r\n&nbsp; T({1, 2, 3}, {30, 20, 10}, -0.111111, -1);<br>\r\n&nbsp; T({1, 2, 3}, {0, 0, 0}, -0.111111, -1);<br>\r\n&nbsp; T({3, 2, 1}, {0, 0, 0}, 0.111111, 1);<br>\r\n&nbsp; T({1, 2, 4, 3}, {0, 0, 0, 0}, -0.1, -0.8);<br>\r\n&nbsp; T({2, 1, 4, 3}, {0, 0, 2, 1}, 0.125, 1);<br>\r\n&nbsp; T({0, 20, 40, 0, 10}, {40, 40, 10, 5, 5}, 0, 0);<br>\r\n&nbsp; T({40, 0, 20, 0, 10}, {1000000, 40, 40, 5, 5}, 0.171428, 0.6);<br>\r\n&nbsp; T({40, 20, 10, 0, 0}, {40, 20, 10, 0, 0}, 0.285714, 1);<br>\r\n&nbsp; T({1, 1, 0, 1}, {0.86, 0.26, 0.52, 0.32}, -0.041666, -0.333333);<br>\r\n}<br>\r\n<br>\r\nint main(int ac, char** av)<br>\r\n{<br>\r\n&nbsp; GiniTest();<br>\r\n}</p>\r\n<p>compile with:</p>\r\n<p>g&#43;&#43;-4.6 -std=c&#43;&#43;0x gini.cc</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 5345,
      "author_name": "texane",
      "author_url": "",
      "post_date": "08/28/2011 20:38:23",
      "content": "<p>note that you can move the division outside the loop:</p>\r\n<p>&nbsp; for (unsigned int fu = 0; fu &lt; a.size(); &#43;&#43;fu) {<br>\r\n&nbsp;&nbsp;&nbsp; struct K&amp; i = k[fu];<br>\r\n&nbsp;&nbsp;&nbsp; accLossPercSum &#43;= i.a;<br>\r\n&nbsp;&nbsp;&nbsp; giniSum &#43;= accLossPercSum;<br>\r\n&nbsp; }<br>\r\n<br>\r\n&nbsp; giniSum = giniSum / sum - (a.size() &#43; 1.0) / 2;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 5354,
      "author_name": "terry13986",
      "author_url": "",
      "post_date": "08/30/2011 01:07:44",
      "content": "<p>Anyone have a Java version they care to share? I've tried to understand these &quot;foreign&quot; language examples but not getting to far. I fear I will produce my solution but be unable to submit it for consideration....</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 5897,
      "author_name": "patrick7",
      "author_url": "",
      "post_date": "10/04/2011 21:25:59",
      "content": "<blockquote>\r\n<pre class=\"x_x_x_prettyprint\">def gini(actual, pred, cmpcol = 0, sortcol = 1):<br> &nbsp;&nbsp;&nbsp; assert( len(actual) == len(pred) )<br> &nbsp;&nbsp;&nbsp; all = np.asarray(np.c_[ actual, pred, np.arange(len(actual)) ], dtype=np.float)<br> &nbsp;&nbsp;&nbsp; all = all[ np.lexsort((all[:,2], -1*all[:,1])) ]<br> &nbsp;&nbsp;&nbsp; totalLosses = all[:,0].sum()<br> &nbsp;&nbsp;&nbsp; giniSum = all[:,0].cumsum().sum() / totalLosses<br> <br> &nbsp;&nbsp;&nbsp; giniSum -= (len(actual) &#43; 1) / 2.<br> &nbsp;&nbsp;&nbsp; return giniSum / len(actual)<br> <br> def gini_normalized(a, p):<br> &nbsp;&nbsp;&nbsp; return gini(a, p) / gini(a, a)<br> <br> def test_gini():<br> &nbsp;&nbsp;&nbsp; def fequ(a,b):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return abs( a -b) &lt; 1e-6<br> &nbsp;&nbsp;&nbsp; def T(a, p, g, n):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert( fequ(gini(a,p), g) )<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert( fequ(gini_normalized(a,p), n) )<br> &nbsp;&nbsp;&nbsp; T([1, 2, 3], [10, 20, 30], 0.111111, 1)<br> &nbsp;&nbsp;&nbsp; T([1, 2, 3], [30, 20, 10], -0.111111, -1)<br> &nbsp;&nbsp;&nbsp; T([1, 2, 3], [0, 0, 0], -0.111111, -1)<br> &nbsp;&nbsp;&nbsp; T([3, 2, 1], [0, 0, 0], 0.111111, 1)<br> &nbsp;&nbsp;&nbsp; T([1, 2, 4, 3], [0, 0, 0, 0], -0.1, -0.8)<br> &nbsp;&nbsp;&nbsp; T([2, 1, 4, 3], [0, 0, 2, 1], 0.125, 1)<br> &nbsp;&nbsp;&nbsp; T([0, 20, 40, 0, 10], [40, 40, 10, 5, 5], 0, 0)<br> &nbsp;&nbsp;&nbsp; T([40, 0, 20, 0, 10], [1000000, 40, 40, 5, 5], 0.171428,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.6)<br> &nbsp;&nbsp;&nbsp; T([40, 20, 10, 0, 0], [40, 20, 10, 0, 0], 0.285714, 1)<br> &nbsp;&nbsp;&nbsp; T([1, 1, 0, 1], [0.86, 0.26, 0.52, 0.32], -0.041666,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.333333)</pre>\r\n</blockquote>\r\n<p>Python code for anyone interested.&nbsp; It assumes you're working in numpy, because if you're not it would probably take forever and a day to finish.</p>",
      "votes": null,
      "replies": [
        {
          "id": 242481,
          "author_name": "ptolemy",
          "author_url": "",
          "post_date": "11/11/2017 17:33:17",
          "content": "<p>Thanks for posting this! Looks like the parameters cmpcol sortcol are not being used ?</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 44646,
      "author_name": "davidbess0",
      "author_url": "",
      "post_date": "05/16/2014 01:09:13",
      "content": "<p>Has anyone in the community figured out R code to create the plot of the Gini.&nbsp; I have been trying like crazy but I am not sure if I am doing it right.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 226658,
      "author_name": "jacekpoplawski",
      "author_url": "",
      "post_date": "10/02/2017 22:14:09",
      "content": "",
      "votes": null,
      "replies": []
    },
    {
      "id": 235814,
      "author_name": "rgwood",
      "author_url": "",
      "post_date": "10/26/2017 04:40:09",
      "content": "<p>You likely would want to use a class to accumulate the values but here is a working Java ver:</p>\n\n<pre><code>    public static double getGini2(List&lt;Double&gt; a, List&lt;Double&gt; p) {\n\n    if(a.size() != p.size())\n        throw new IllegalArgumentException(\"a.sz=\"+a.size()+\" != p.sz=\"+p.size());\n\n    List&lt;double[]&gt; list=new ArrayList&lt;&gt;();\n\n    int sz=a.size();\n    double sum=0;\n    for (int i = 0; i != sz; ++i) {\n        list.add(new double[] {a.get(i), p.get(i)}); // add tuple {act, pred}\n        sum+=a.get(i); // while we're at it...\n    }\n\n    Comparator&lt;double[]&gt; compEstDsc=new Comparator&lt;double[]&gt;() {\n        @Override\n        public int compare(double[] o1, double[] o2) {\n            double v1=o1[1]; // only use prediction\n            double v2=o2[1];\n            return UtilComparator.compareDoubleDesc(v1, v2);\n        }\n    };\n    list.sort(compEstDsc);\n\n    double accPopPercSum=0;\n    double accLossPercSum=0;\n    double giniSum=0;\n\n    for (int i = 0; i &lt; sz; ++i) {\n\n        double[] a0p1 = list.get(i);\n\n        accLossPercSum += a0p1[0]/sum; // only use act\n\n        accPopPercSum += 1.0/sz;\n\n        giniSum += accLossPercSum - accPopPercSum;\n    }\n\n    return giniSum/sz;\n}\n\npublic static double getGini2Normalized(List&lt;Double&gt; a, List&lt;Double&gt; p) {\n    return getGini2(a, p)/getGini2(a, a);\n}\n</code></pre>",
      "votes": null,
      "replies": []
    },
    {
      "id": 247248,
      "author_name": "poznyakovskiy",
      "author_url": "",
      "post_date": "11/22/2017 16:47:25",
      "content": "<p>Here's a Python implementation with TensorFlow. Expects <code>actual</code> and <code>pred</code> to be a (1, N) tensor.</p>\n\n<pre><code>def gini_normalized(actual, pred):\n    n = tf.shape(actual)[1]\n    indices = tf.nn.top_k(pred, k=n)[1][0]\n    actual_sorted = tf.gather(actual[0], indices)\n    cost = tf.reduce_sum(actual_sorted)\n    loss_proportion = tf.cumsum(actual_sorted) / cost\n    null_model = tf.to_float(tf.range(1, n + 1)) / tf.to_float(n)\n    g = tf.subtract(loss_proportion, null_model)\n    g = tf.reduce_sum(g) / tf.to_float(n)\n    g /= (1.0 - tf.reduce_mean(actual)) / 2.0\n    return g\n</code></pre>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "4568": "",
    "4573": "",
    "4574": "",
    "4575": "",
    "4577": "",
    "4578": "",
    "4579": "",
    "4580": "",
    "4593": "",
    "4622": "",
    "4623": "",
    "4677": "",
    "4766": "",
    "4767": "",
    "4769": "",
    "5183": "",
    "5344": "",
    "5345": "",
    "5354": "",
    "5897": "",
    "44646": "",
    "226658": "",
    "235814": "You likely would want to use a class to accumulate the values but here is a working Java ver:\n\n    \tpublic static double getGini2(List",
    "242481": "Thanks for posting this! Looks like the parameters cmpcol sortcol are not being used ?",
    "247248": "Here's a Python implementation with TensorFlow. Expects `actual` and `pred` to be a (1, N) tensor.\n\n    def gini_normalized(actual, pred):\n        n = tf.shape(actual)[1]\n        indices = tf.nn.top_k(pred, k=n)[1][0]\n        actual_sorted = tf.gather(actual[0], indices)\n        cost = tf.reduce_sum(actual_sorted)\n        loss_proportion = tf.cumsum(actual_sorted) / cost\n        null_model = tf.to_float(tf.range(1, n + 1)) / tf.to_float(n)\n        g = tf.subtract(loss_proportion, null_model)\n        g = tf.reduce_sum(g) / tf.to_float(n)\n        g /= (1.0 - tf.reduce_mean(actual)) / 2.0\n        return g"
  },
  "source": "meta"
}