Diversity prediction theorem: Difference between revisions
m (→{{header|REXX}}: added version 2.) |
m (fixed HTML tags) |
||
Line 276: | Line 276: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
==version 1== |
===version 1=== |
||
<lang rexx>/* REXX */ |
<lang rexx>/* REXX */ |
||
Numeric Digits 20 |
Numeric Digits 20 |
||
Line 317: | Line 317: | ||
diversity=10.5</pre> |
diversity=10.5</pre> |
||
==version 2== |
===version 2=== |
||
<lang rexx>/*REXX program calculates the average error, crowd error, and prediction diversity. */ |
<lang rexx>/*REXX program calculates the average error, crowd error, and prediction diversity. */ |
||
numeric digits 50 /*50 dec digs; show 6 fractional digits*/ |
numeric digits 50 /*50 dec digs; show 6 fractional digits*/ |
Revision as of 01:30, 15 January 2017
The wisdom of the crowd is the collective opinion of a group of individuals rather than that of a single expert.
Wisdom-of-the-crowds research routinely attributes the superiority of crowd averages over individual judgments to the elimination of individual noise, an explanation that assumes independence of the individual judgments from each other. Thus the crowd tends to make its best decisions if it is made up of diverse opinions and ideologies.
Scott E. Page introduced the diversity prediction theorem: "The squared error of the collective prediction equals the average squared error minus the predictive diversity". Therefore, when the diversity in a group is large, the error of the crowd is small.
- Average Individual Error: Average of the individual squared errors
- Collective Error: Squared error of the collective prediction
- Prediction Diversity: Average squared distance from the individual predictions to the collective prediction
So, The Diversity Prediction Theorem: Given a crowd of predictive models
Collective Error = Average Individual Error - Prediction Diversity
C++
<lang C++>
- include <iostream>
- include <vector>
- include <numeric>
float sum(const std::vector<float> &array) {
return std::accumulate(array.begin(), array.end(), 0.0);
}
float square(float x) {
return x * x;
}
float mean(const std::vector<float> &array) {
return sum(array) / array.size();
}
float averageSquareDiff(float a, const std::vector<float> &predictions) {
std::vector<float> results; for (float x : predictions) results.push_back(square(x - a)); return mean(results);
}
void diversityTheorem(float truth, const std::vector<float> &predictions) {
float average = mean(predictions); std::cout << "average-error: " << averageSquareDiff(truth, predictions) << "\n" << "crowd-error: " << square(truth - average) << "\n" << "diversity: " << averageSquareDiff(average, predictions) << std::endl;
}
int main() {
diversityTheorem(49, {48,47,51}); diversityTheorem(49, {48,47,51,42}); return 0;
} </lang>
- Output:
average-error: 3 crowd-error: 0.11111 diversity: 2.88889 average-error: 14.5 crowd-error: 4 diversity: 10.5
C#
<lang csharp> using System; using System.Linq; using System.Collections.Generic;
public class MainClass {
static double Square(double x) => x * x;
static double AverageSquareDiff(double a, IEnumerable<double> predictions) => predictions.Select(x => Square(x - a)).Average();
static void DiversityTheorem(double truth, IEnumerable<double> predictions) { var average = predictions.Average(); Console.WriteLine($@"average-error: {AverageSquareDiff(truth, predictions)}
crowd-error: {Square(truth - average)} diversity: {AverageSquareDiff(average, predictions)}");
}
public static void Main() {
DiversityTheorem(49, new []{48d,47,51});
DiversityTheorem(49, new []{48d,47,51,42}); }
}</lang>
- Output:
average-error: 3 crowd-error: 0.11111 diversity: 2.88889 average-error: 14.5 crowd-error: 4 diversity: 10.5
Clojure
John Lawrence Aspden's code posted on Diversity Prediction Theorem. <lang Clojure> (defn diversity-theorem [truth predictions]
(let [square (fn[x] (* x x)) mean (/ (reduce + predictions) (count predictions)) avg-sq-diff (fn[a] (/ (reduce + (for [x predictions] (square (- x a)))) (count predictions)))] {:average-error (avg-sq-diff truth) :crowd-error (square (- truth mean)) :diversity (avg-sq-diff mean)}))
(println (diversity-theorem 49 '(48 47 51))) (println (diversity-theorem 49 '(48 47 51 42))) </lang>
- Output:
{:average-error 3, :crowd-error 1/9, :diversity 26/9} {:average-error 29/2, :crowd-error 4, :diversity 21/2}
JavaScript
ES5
<lang JavaScript>'use strict';
function sum(array) {
return array.reduce(function (a, b) { return a + b; });
}
function square(x) {
return x * x;
}
function mean(array) {
return sum(array) / array.length;
}
function averageSquareDiff(a, predictions) {
return mean(predictions.map(function (x) { return square(x - a); }));
}
function diversityTheorem(truth, predictions) {
var average = mean(predictions); return { 'average-error': averageSquareDiff(truth, predictions), 'crowd-error': square(truth - average), 'diversity': averageSquareDiff(average, predictions) };
}
console.log(diversityTheorem(49, [48,47,51])) console.log(diversityTheorem(49, [48,47,51,42])) </lang>
- Output:
{ 'average-error': 3, 'crowd-error': 0.11111111111111269, diversity: 2.888888888888889 } { 'average-error': 14.5, 'crowd-error': 4, diversity: 10.5 }
ES6
<lang JavaScript>(() => {
'use strict';
// mean :: Num a => [a] -> b const mean = xs => { const lng = xs.length;
return lng > 0 ? ( xs.reduce((a, b) => a + b, 0) / lng ) : undefined; }
// meanErrorSquared :: Num a => a -> [a] -> b const meanErrorSquared = (observed, predictions) => mean(predictions.map(x => Math.pow(x - observed, 2)));
// diversityValues :: Num a => a -> [a] -> // {mean-Error :: b, crowd-error :: b, diversity :: b} const diversityValues = (observed, predictions) => { const predictionMean = mean(predictions);
return { 'mean-error': meanErrorSquared(observed, predictions), 'crowd-error': Math.pow(observed - predictionMean, 2), 'diversity': meanErrorSquared(predictionMean, predictions) }; }
// TEST
// show :: a -> String const show = x => JSON.stringify(x, null, 2);
return show([{ observed: 49, predictions: [48, 47, 51] }, { observed: 49, predictions: [48, 47, 51, 42] }].map(x => { const dctData = diversityValues(x.observed, x.predictions), dct = {};
return ( Object.keys(dctData) .forEach(k => dct[k] = dctData[k].toPrecision(3)), dct ); }));
})();</lang>
- Output:
[ { "mean-error": "3.00", "crowd-error": "0.111", "diversity": "2.89" }, { "mean-error": "14.5", "crowd-error": "4.00", "diversity": "10.5" } ]
Perl 6
<lang perl6>sub diversity-calc($truth, @pred) { my $ae = avg-error($truth, @pred); # average individual error my $cp = ([+] @pred)/+@pred; # collective prediction my $ce = ($cp - $truth)**2; # collective error my $pd = avg-error($cp, @pred); # prediction diversity return $ae, $ce, $pd; }
sub avg-error ($m, @v) { ([+] (@v X- $m) X**2) / +@v }
sub diversity-format (@stats) { gather {
for <average-error crowd-error diversity> Z @stats -> ($label,$value) { take $label.fmt("%13s") ~ ':' ~ $value.fmt("%7.3f"); }
} }
.say for diversity-format diversity-calc(49, <48 47 51>); .say for diversity-format diversity-calc(49, <48 47 51 42>);</lang>
- Output:
average-error: 3.000 crowd-error: 0.111 diversity: 2.889 average-error: 14.500 crowd-error: 4.000 diversity: 10.500
REXX
version 1
<lang rexx>/* REXX */ Numeric Digits 20 Call diversityTheorem 49,'48 47 51' Say '--------------------------------------' Call diversityTheorem 49,'48 47 51 42' Exit
diversityTheorem:
Parse Arg truth,list average=average(list) Say 'average-error='averageSquareDiff(truth,list) Say 'crowd-error='||(truth-average)**2 Say 'diversity='averageSquareDiff(average,list) Return
average: Procedure
Parse Arg list res=0 Do i=1 To words(list) res=res+word(list,i) /* accumulate list elements */ End Return res/words(list) /* return the average */
averageSquareDiff: Procedure
Parse Arg a,list res=0 Do i=1 To words(list) x=word(list,i) res=res+(x-a)**2 /* accumulate square of differences */ End Return res/words(list) /* return the average */</lang>
- Output:
average-error=3 crowd-error=0.11111111111111111089 diversity=2.8888888888888888889 -------------------------------------- average-error=14.5 crowd-error=4 diversity=10.5
version 2
<lang rexx>/*REXX program calculates the average error, crowd error, and prediction diversity. */ numeric digits 50 /*50 dec digs; show 6 fractional digits*/ call diversity 49, 48 47 51 /*true value, and crowd predictions. */ call diversity 49, 48 47 51 42 /* " " " " " */ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ avg: $=0; do j=1 for #; $=$ + word(nums,j); end /*j*/; return $/# avgSD: $=0; do j=1 for #; $=$ + (word(nums,j)-arg(1))**2; end /*j*/; return $/# /*──────────────────────────────────────────────────────────────────────────────────────*/ diversity: parse arg true, nums; #=words(nums) /*obtain args; calculate crowd number.*/
say ' the true value:' true '════════════════════ crowd estimates:' nums avg=avg() /* [↓] avgDF=avg of squared difference*/ say ' the average error:' format( avgSD(true) , , 6) / 1 say ' the crowd error:' format( (true-avg)**2 , , 6) / 1 say 'prediction diversity:' format( avgSD(avg) , , 6) / 1; say return /* [↑] format and normalize numbers.*/</lang>
output when using the default inputs:
the true value: 49 ════════════════════ crowd estimates: 48 47 51 the average error: 3 the crowd error: 0.111111 prediction diversity: 2.888889 the true value: 49 ════════════════════ crowd estimates: 48 47 51 42 the average error: 14.5 the crowd error: 4 prediction diversity: 10.5
Sidef
<lang ruby>func avg_error(m, v) {
v.map { (_ - m)**2 }.sum / v.len
}
func diversity_calc(truth, pred) {
var ae = avg_error(truth, pred) var cp = pred.sum/pred.len var ce = (cp - truth)**2 var pd = avg_error(cp, pred) return [ae, ce, pd]
}
func diversity_format(stats) {
gather { for t,v in (%w(average-error crowd-error diversity) ~Z stats) { take(("%13s" % t) + ':' + ('%7.3f' % v)) } }
}
diversity_format(diversity_calc(49, [48, 47, 51])).each{.say} diversity_format(diversity_calc(49, [48, 47, 51, 42])).each{.say}</lang>
- Output:
average-error: 3.000 crowd-error: 0.111 diversity: 2.889 average-error: 14.500 crowd-error: 4.000 diversity: 10.500
TypeScript
<lang TypeScript> function sum(array: Array<number>): number {
return array.reduce((a, b) => a + b)
}
function square(x : number) :number {
return x * x
}
function mean(array: Array<number>): number {
return sum(array) / array.length
}
function averageSquareDiff(a: number, predictions: Array<number>): number {
return mean(predictions.map(x => square(x - a)))
}
function diversityTheorem(truth: number, predictions: Array<number>): Object {
const average: number = mean(predictions) return { "average-error": averageSquareDiff(truth, predictions), "crowd-error": square(truth - average), "diversity": averageSquareDiff(average, predictions) }
}
console.log(diversityTheorem(49, [48,47,51])) console.log(diversityTheorem(49, [48,47,51,42])) </lang>
- Output:
{ 'average-error': 3, 'crowd-error': 0.11111111111111269, diversity: 2.888888888888889 } { 'average-error': 14.5, 'crowd-error': 4, diversity: 10.5 }