Diversity prediction theorem

From Rosetta Code
Diversity prediction theorem is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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.


Definitions
  •   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
  •   Diversity Prediction Theorem:   Given a crowd of predictive models,     then
  Collective Error   =   Average Individual Error   ─   Prediction Diversity
Task

For a given   true   value and a number of number of estimates (from a crowd),   show   (here on this page):

  •   the true value   and   the crowd estimates
  •   the average error
  •   the crowd error
  •   the prediction diversity


Use   (at least)   these two examples:

  •   a true value of   49   with crowd estimates of:   48   47   51
  •   a true value of   49   with crowd estimates of:   48   47   51   42


Also see
  •   Wikipedia entry:   Wisdom of the crowd
  •   University of Michigan: PDF paper         (exists on a web archive,   the Wayback Machine).



11l

Translation of: C++

<lang 11l>F average_square_diff(a, predictions)

  R sum(predictions.map(x -> (x - @a) ^ 2)) / predictions.len

F diversity_theorem(truth, predictions)

  V average = sum(predictions) / predictions.len
  print(‘average-error: ’average_square_diff(truth, predictions)"\n"‘’
        ‘crowd-error:   ’((truth - average) ^ 2)"\n"‘’
        ‘diversity:     ’average_square_diff(average, predictions))

diversity_theorem(49.0, [Float(48), 47, 51]) diversity_theorem(49.0, [Float(48), 47, 51, 42])</lang>

Output:
average-error: 3
crowd-error:   0.111111111
diversity:     2.888888889
average-error: 14.5
crowd-error:   4
diversity:     10.5

C

Accepts inputs from command line, prints out usage on incorrect invocation. <lang C>

  1. include<string.h>
  2. include<stdlib.h>
  3. include<stdio.h>

float mean(float* arr,int size){ int i = 0; float sum = 0;

while(i != size) sum += arr[i++];

return sum/size; }

float variance(float reference,float* arr, int size){ int i=0; float* newArr = (float*)malloc(size*sizeof(float));

for(;i<size;i++) newArr[i] = (reference - arr[i])*(reference - arr[i]);

return mean(newArr,size); }

float* extractData(char* str, int *len){ float* arr; int i=0,count = 1; char* token;

while(str[i]!=00){ if(str[i++]==',') count++; }

arr = (float*)malloc(count*sizeof(float)); *len = count;

token = strtok(str,",");

i = 0;

while(token!=NULL){ arr[i++] = atof(token); token = strtok(NULL,","); }

return arr; }

int main(int argC,char* argV[]) { float* arr,reference,meanVal; int len; if(argC!=3) printf("Usage : %s <reference value> <observations separated by commas>"); else{ arr = extractData(argV[2],&len);

reference = atof(argV[1]);

meanVal = mean(arr,len);

printf("Average Error : %.9f\n",variance(reference,arr,len)); printf("Crowd Error : %.9f\n",(reference - meanVal)*(reference - meanVal)); printf("Diversity : %.9f",variance(meanVal,arr,len)); }

return 0; } </lang> Invocation and Output :

C:\rosettaCode>diversityTheorem.exe 49 48,47,51
Average Error : 3.000000000
Crowd Error : 0.111110263
Diversity : 2.888888597
C:\rosettaCode>diversityTheorem.exe 49 48,47,51,42
Average Error : 14.500000000
Crowd Error : 4.000000000
Diversity : 10.500000000

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

C++

<lang Cpp>

  1. include <iostream>
  2. include <vector>
  3. 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

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}

D

Translation of: C#

<lang d>import std.algorithm; import std.stdio;

auto square = (real x) => x * x;

auto meanSquareDiff(R)(real a, R predictions) {

   return predictions.map!(x => square(x - a)).mean;

}

void diversityTheorem(R)(real truth, R predictions) {

   auto average = predictions.mean;
   writeln("average-error: ", meanSquareDiff(truth, predictions));
   writeln("crowd-error: ", square(truth - average));
   writeln("diversity: ", meanSquareDiff(average, predictions));
   writeln;

}

void main() {

   diversityTheorem(49.0, [48.0, 47.0, 51.0]);
   diversityTheorem(49.0, [48.0, 47.0, 51.0, 42.0]);

}</lang>

Output:
average-error: 3
crowd-error: 0.111111
diversity: 2.88889

average-error: 14.5
crowd-error: 4
diversity: 10.5

Factor

Works with: Factor version 0.99 2020-01-23

<lang factor>USING: kernel math math.statistics math.vectors prettyprint ;

TUPLE: div avg-err crowd-err diversity ;

diversity ( x seq -- obj )
   [ n-v dup v* mean ] [ mean swap - sq ]
   [ nip dup mean v-n dup v* mean ] 2tri div boa ;

49 { 48 47 51 } diversity . 49 { 48 47 51 42 } diversity .</lang>

Output:
T{ div { avg-err 3 } { crowd-err 1/9 } { diversity 2+8/9 } }
T{ div { avg-err 14+1/2 } { crowd-err 4 } { diversity 10+1/2 } }

Fōrmulæ

In this page you can see the solution of this task.

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text (more info). Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for transportation effects more than visualization and edition.

The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.

Go

<lang go>package main

import "fmt"

func averageSquareDiff(f float64, preds []float64) (av float64) {

   for _, pred := range preds {
       av += (pred - f) * (pred - f)
   }
   av /= float64(len(preds))
   return

}

func diversityTheorem(truth float64, preds []float64) (float64, float64, float64) {

   av := 0.0
   for _, pred := range preds {
       av += pred
   }
   av /= float64(len(preds))
   avErr := averageSquareDiff(truth, preds)
   crowdErr := (truth - av) * (truth - av)
   div := averageSquareDiff(av, preds)
   return avErr, crowdErr, div

}

func main() {

   predsArray := [2][]float64{{48, 47, 51}, {48, 47, 51, 42}}
   truth := 49.0
   for _, preds := range predsArray {
       avErr, crowdErr, div := diversityTheorem(truth, preds)
       fmt.Printf("Average-error : %6.3f\n", avErr)
       fmt.Printf("Crowd-error   : %6.3f\n", crowdErr)
       fmt.Printf("Diversity     : %6.3f\n\n", div)
   }

}</lang>

Output:
Average-error :  3.000
Crowd-error   :  0.111
Diversity     :  2.889

Average-error : 14.500
Crowd-error   :  4.000
Diversity     : 10.500

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';
   // diversityValues :: [Num] -> {
   //      mean-error ::  Float, 
   //     crowd-error :: Float, 
   //       diversity :: Float
   // }
   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
               )
           };
       };
   // meanErrorSquared :: Num a => a -> [a] -> b
   const meanErrorSquared = observed =>
       predictions => mean(
           predictions.map(x => Math.pow(x - observed, 2))
       );
   // mean :: Num a => [a] -> b
   const mean = xs => {
       const lng = xs.length;
       return lng > 0 ? (
           xs.reduce((a, b) => a + b, 0) / lng
       ) : undefined;
   };


   // ----------------------- TEST ------------------------
   const main = () =>
       JSON.stringify([{
           observed: 49,
           predictions: [48, 47, 51]
       }, {
           observed: 49,
           predictions: [48, 47, 51, 42]
       }].map(x => dictionaryAtPrecision(3)(
           diversityValues(x.observed)(
               x.predictions
           )
       )), null, 2);


   // ---------------------- GENERIC ----------------------
   // dictionaryAtPrecision :: Int -> Dict -> Dict
   const dictionaryAtPrecision = n =>
       // A dictionary of Float values, with 
       // all Floats adjusted to a given precision.
       dct => Object.keys(dct).reduce(
           (a, k) => Object.assign(
               a, {
                   [k]: dct[k].toPrecision(n)
               }
           ), {}
       );
   // MAIN ---
   return main()

})();</lang>

Output:
[
  {
    "mean-error": "3.00",
    "crowd-error": "0.111",
    "diversity": "2.89"
  },
  {
    "mean-error": "14.5",
    "crowd-error": "4.00",
    "diversity": "10.5"
  }
]

Jsish

From Typescript entry. <lang javascript>/* Diverisity Prediction Theorem, in Jsish */ "use strict";

function sum(arr:array):number {

   return arr.reduce(function(acc, cur, idx, arr) { return acc + cur; });

}

function square(x:number):number {

   return x * x;

}

function mean(arr:array):number {

   return sum(arr) / arr.length;

}

function averageSquareDiff(a:number, predictions:array):number {

   return mean(predictions.map(function(x:number):number { return square(x - a); }));

}

function diversityTheorem(truth:number, predictions:array):object {

   var average = mean(predictions);
   return {
       "average-error": averageSquareDiff(truth, predictions),
       "crowd-error": square(truth - average),
       "diversity": averageSquareDiff(average, predictions)
   };

}

diversityTheorem(49, [48,47,51]);
diversityTheorem(49, [48,47,51,42]);

/*

!EXPECTSTART!

diversityTheorem(49, [48,47,51]) ==> { "average-error":3, "crowd-error":0.1111111111111127, diversity:2.888888888888889 } diversityTheorem(49, [48,47,51,42]) ==> { "average-error":14.5, "crowd-error":4, diversity:10.5 }

!EXPECTEND!

  • /</lang>
Output:
prompt$ jsish -u diversityPrediction.jsi
[PASS] diversityPrediction.jsi

Julia

Works with: Julia version 1.2

<lang julia>import Statistics: mean

function diversitytheorem(truth::T, pred::Vector{T}) where T<:Number

   μ = mean(pred)
   avgerr = mean((pred .- truth) .^ 2)
   crderr = (μ - truth) ^ 2
   divers = mean((pred .- μ) .^ 2)
   avgerr, crderr, divers

end

for (t, s) in [(49, [48, 47, 51]),

              (49, [48, 47, 51, 42])]
   avgerr, crderr, divers = diversitytheorem(t, s)
   println("""
   average-error : $avgerr
   crowd-error   : $crderr
   diversity     : $divers
   """)

end</lang>

Output:
average-error : 3.0
crowd-error   : 0.11111111111111269
diversity     : 2.888888888888889

average-error : 14.5
crowd-error   : 4.0
diversity     : 10.5

Kotlin

Translation of: TypeScript

<lang scala>// version 1.1.4-3

fun square(d: Double) = d * d

fun averageSquareDiff(d: Double, predictions: DoubleArray) =

   predictions.map { square(it - d) }.average()

fun diversityTheorem(truth: Double, predictions: DoubleArray): String {

   val average = predictions.average()
   val f = "%6.3f"
   return "average-error : ${f.format(averageSquareDiff(truth, predictions))}\n" +
          "crowd-error   : ${f.format(square(truth - average))}\n" +
          "diversity     : ${f.format(averageSquareDiff(average, predictions))}\n"

}

fun main(args: Array<String>) {

   println(diversityTheorem(49.0, doubleArrayOf(48.0, 47.0, 51.0)))
   println(diversityTheorem(49.0, doubleArrayOf(48.0, 47.0, 51.0, 42.0)))

}</lang>

Output:
average-error :  3.000
crowd-error   :  0.111
diversity     :  2.889

average-error : 14.500
crowd-error   :  4.000
diversity     : 10.500

Lua

Translation of: C++

<lang lua>function square(x)

   return x * x

end

function mean(a)

   local s = 0
   local c = 0
   for i,v in pairs(a) do
       s = s + v
       c = c + 1
   end
   return s / c

end

function averageSquareDiff(a, predictions)

   local results = {}
   for i,x in pairs(predictions) do
       table.insert(results, square(x - a))
   end
   return mean(results)

end

function diversityTheorem(truth, predictions)

   local average = mean(predictions)
   print("average-error: " .. averageSquareDiff(truth, predictions))
   print("crowd-error: " .. square(truth - average))
   print("diversity: " .. averageSquareDiff(average, predictions))

end

function main()

   diversityTheorem(49, {48, 47, 51})
   diversityTheorem(49, {48, 47, 51, 42})

end

main()</lang>

Output:
average-error: 3
crowd-error: 0.11111111111111
diversity: 2.8888888888889
average-error: 14.5
crowd-error: 4
diversity: 10.5

Perl

<lang perl>sub diversity {

   my($truth, @pred) = @_;
   my($ae,$ce,$cp,$pd,$stats);
   $cp += $_/@pred for @pred;      # collective prediction
   $ae = avg_error($truth, @pred); # average individual error
   $ce = ($cp - $truth)**2;        # collective error
   $pd = avg_error($cp, @pred);    # prediction diversity
   my $fmt = "%13s: %6.3f\n";
   $stats  = sprintf $fmt, 'average-error', $ae;
   $stats .= sprintf $fmt, 'crowd-error',   $ce;
   $stats .= sprintf $fmt, 'diversity',     $pd;

}

sub avg_error {

   my($m, @v) = @_;
   my($avg_err);
   $avg_err += ($_ - $m)**2 for @v;
   $avg_err/@v;

}

print diversity(49, qw<48 47 51>) . "\n"; print diversity(49, qw<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

Phix

<lang Phix>function mean(sequence s)

   return sum(s)/length(s)

end function

function variance(sequence s, atom d)

   return mean(sq_power(sq_sub(s,d),2))

end function

function diversity_theorem(atom reference, sequence observations)

   atom average_error = variance(observations,reference),
        average = mean(observations),
        crowd_error = power(reference-average,2),
        diversity = variance(observations,average)
   return {{"average_error",average_error},
           {"crowd_error",crowd_error},
           {"diversity",diversity}}

end function

procedure test(atom reference, sequence observations)

   sequence res = diversity_theorem(reference, observations)
   for i=1 to length(res) do
       printf(1," %14s : %g\n",res[i])
   end for

end procedure test(49, {48, 47, 51}) test(49, {48, 47, 51, 42})</lang>

Output:
  average_error : 3
    crowd_error : 0.111111
      diversity : 2.88889
  average_error : 14.5
    crowd_error : 4
      diversity : 10.5

Python

By composition of pure functions:

Works with: Python version 3.7

<lang python>Diversity prediction theorem

from itertools import chain from functools import reduce


  1. main :: IO ()

def main():

   Observed value: 49,
      prediction lists: various.
   
   print(unlines(map(
       showDiversityValues(49),
       [
           [48, 47, 51],
           [48, 47, 51, 42],
           [50, '?', 50, {}, 50],  # Non-numeric values.
           []                      # Missing predictions.
       ]
   )))
   print(unlines(map(
       showDiversityValues('49'),  # String in place of number.
       [
           [50, 50, 50],
           [40, 35, 40],
       ]
   )))


  1. meanErrorSquared :: Num -> [Num] -> Num

def meanErrorSquared(x):

   The mean of the squared differences
      between the observed value x and
      a non-empty list of predictions ps.
   
   return lambda ps: mean(list(map(
       lambda y: pow(y - x, 2),
       ps
   )))


  1. diversityValues :: Num a => a -> [a] ->
  2. {mean-Error :: a, crowd-error :: a, diversity :: a}

def diversityValues(x):

   The mean error, crowd error and
      diversity, for a given observation x
      and a non-empty list of predictions ps.
   
   def go(ps):
       mp = mean(ps)
       return {
           'mean-error': meanErrorSquared(x)(ps),
           'crowd-error': pow(x - mp, 2),
           'diversity': meanErrorSquared(mp)(ps)
       }
   return lambda ps: go(ps)


  1. FORMATTING ----------------------------------------------
  1. showDiversityValues :: Num -> [Num] -> Either String String

def showDiversityValues(x):

   Formatted string representation
      of diversity values for a given
      observation x and a non-empty
      list of predictions p.
   
   def go(x, ps):
       def showDict(dct):
           w = 4 + max(map(len, dct.keys()))
           def showKV(a, kv):
               k, v = kv
               return a + k.rjust(w, ' ') + (
                   ' : ' + showPrecision(3)(v) + '\n'
               )
           return 'Predictions: ' + showList(ps) + ' ->\n' + (
               reduce(showKV, dct.items(), )
           )
       def showProblem(e):
           return (
               unlines(map(indent(1), e)) if (
                   isinstance(e, list)
               ) else indent(1)(repr(e))
           ) + '\n'
       return 'Observation:  ' + repr(x) + '\n' + (
           either(showProblem)(showDict)(
               bindLR(numLR(x))(
                   lambda n: bindLR(numsLR(ps))(
                       compose(Right)(diversityValues(n))
                   )
               )
           )
       )
   return lambda ps: go(x, ps)


  1. GENERIC -------------------------------------------------
  1. Right :: b -> Either a b

def Right(x):

   Constructor for a populated Either (option type) value
   return {'type': 'Either', 'Left': None, 'Right': x}


  1. Left :: a -> Either a b

def Left(x):

   Constructor for an empty Either (option type) value
      with an associated string.
   return {'type': 'Either', 'Right': None, 'Left': x}


  1. bindLR (>>=) :: Either a -> (a -> Either b) -> Either b

def bindLR(m):

   Either monad injection operator.
      Two computations sequentially composed,
      with any value produced by the first
      passed as an argument to the second.
   return lambda mf: (
       mf(m.get('Right')) if None is m.get('Left') else m
   )


  1. compose (<<<) :: (b -> c) -> (a -> b) -> a -> c

def compose(g):

   Right to left function composition.
   return lambda f: lambda x: g(f(x))


  1. concatMap :: (a -> [b]) -> [a] -> [b]

def concatMap(f):

   Concatenated list over which a function has been mapped.
      The list monad can be derived by using a function f which
      wraps its output in a list,
      (using an empty list to represent computational failure).
   return lambda xs: list(
       chain.from_iterable(
           map(f, xs)
       )
   )


  1. either :: (a -> c) -> (b -> c) -> Either a b -> c

def either(fl):

   The application of fl to e if e is a Left value,
      or the application of fr to e if e is a Right value.
   return lambda fr: lambda e: fl(e['Left']) if (
       None is e['Right']
   ) else fr(e['Right'])


  1. indent :: Int -> String -> String

def indent(n):

   String indented by n multiples
      of four spaces
   return lambda s: (n * 4 * ' ') + s


  1. mean :: [Num] -> Float

def mean(xs):

   Arithmetic mean of a list
      of numeric values.
   
   return sum(xs) / float(len(xs))


  1. numLR :: a -> Either String Num

def numLR(x):

   Either Right x if x is a float or int,
      or a Left explanatory message.
   return Right(x) if (
       isinstance(x, (float, int))
   ) else Left('Expected number, saw: ' + str(type(x)) + ' ' + repr(x))


  1. numsLR :: [a] -> Either String [Num]

def numsLR(xs):

   Either Right xs if all xs are float or int,
      or a Left explanatory message.
   def go(ns):
       ls, rs = partitionEithers(map(numLR, ns))
       return Left(ls) if ls else Right(rs)
   return bindLR(
       Right(xs) if (
           bool(xs) and isinstance(xs, list)
       ) else Left(
           'Expected a non-empty list, saw: ' + (
               str(type(xs)) + ' ' + repr(xs)
           )
       )
   )(go)


  1. partitionEithers :: [Either a b] -> ([a],[b])

def partitionEithers(lrs):

   A list of Either values partitioned into a tuple
      of two lists, with all Left elements extracted
      into the first list, and Right elements
      extracted into the second list.
   
   def go(a, x):
       ls, rs = a
       r = x.get('Right')
       return (ls + [x.get('Left')], rs) if None is r else (
           ls, rs + [r]
       )
   return reduce(go, lrs, ([], []))


  1. showList :: [a] -> String

def showList(xs):

   Compact string representation of a list
   return '[' + ','.join(str(x) for x in xs) + ']'


  1. showPrecision Int -> Float -> String

def showPrecision(n):

   A string showing a floating point number
      at a given degree of precision.
   return lambda x: str(round(x, n))


  1. unlines :: [String] -> String

def unlines(xs):

   A single string derived by the intercalation
      of a list of strings with the newline character.
   return '\n'.join(xs)


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
Observation:  49
Predictions: [48,47,51] ->
     mean-error : 3.0
    crowd-error : 0.111
      diversity : 2.889

Observation:  49
Predictions: [48,47,51,42] ->
     mean-error : 14.5
    crowd-error : 4.0
      diversity : 10.5

Observation:  49
    Expected number, saw: <class 'str'> '?'
    Expected number, saw: <class 'dict'> {}

Observation:  49
    "Expected a non-empty list, saw: <class 'list'> []"

Observation:  '49'
    "Expected number, saw: <class 'str'> '49'"

Observation:  '49'
    "Expected number, saw: <class 'str'> '49'"

Raku

(formerly 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

Uses greater precision, but rounds the output to six decimal digits past the decimal point   (see the last comment in the program). <lang rexx>/*REXX program calculates the average error, crowd error, and prediction diversity. */

                              numeric digits 50 /*use precision of fifty decimal digits*/

call diversity 49, 48 47 51 /*true value and the crowd predictions.*/ call diversity 49, 48 47 51 42 /* " " " " " " */ exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ avg: $=0; do j=1 for #; $= $ + word(x, j)  ; end; return $ / # avgSD: $=0; arg y; do j=1 for #; $= $ + (word(x, j) - y)**2; end; return $ / # /*──────────────────────────────────────────────────────────────────────────────────────*/ diversity: parse arg true, x; #= words(x); a= avg() /*get args; count #est; avg*/

          say '   the  true   value: '   true  copies("═", 20)  'crowd estimates: '   x
          say '   the average error: '   format( avgSD(true) , , 6) / 1
          say '   the  crowd  error: '   format( (true-a)**2 , , 6) / 1
          say 'prediction diversity: '   format( avgSD(a)    , , 6) / 1;        say;  say
          return                                            /*   └─── show 6 dec. digs.*/</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

Ruby

Translation of: D

<lang ruby>def square(x)

   return x * x

end

def mean(a)

   return a.sum(0.0) / a.size

end

def meanSquareDiff(a, predictions)

   return mean(predictions.map { |x| square(x - a) })

end

def diversityTheorem(truth, predictions)

   average = mean(predictions)
   print "average-error: ", meanSquareDiff(truth, predictions), "\n"
   print "crowd-error: ", square(truth - average), "\n"
   print "diversity: ", meanSquareDiff(average, predictions), "\n"
   print "\n"

end

def main

   diversityTheorem(49.0, [48.0, 47.0, 51.0])
   diversityTheorem(49.0, [48.0, 47.0, 51.0, 42.0])

end

main()</lang>

Output:
average-error: 3.0
crowd-error: 0.11111111111111269
diversity: 2.888888888888889

average-error: 14.5
crowd-error: 4.0
diversity: 10.5

Scala

Translation of: Kotlin

<lang scala>object DiversityPredictionTheorem {

 def square(d: Double): Double
 = d * d
 def average(a: Array[Double]): Double
 = a.sum / a.length
 def averageSquareDiff(d: Double, predictions: Array[Double]): Double
 = average(predictions.map(it => square(it - d)))
 def diversityTheorem(truth: Double, predictions: Array[Double]): String = {
   val avg = average(predictions)
   f"average-error : ${averageSquareDiff(truth, predictions)}%6.3f\n" +
   f"crowd-error   : ${square(truth - avg)}%6.3f\n"+
   f"diversity     : ${averageSquareDiff(avg, predictions)}%6.3f\n"
 }
 def main(args: Array[String]): Unit = {
   println(diversityTheorem(49.0, Array(48.0, 47.0, 51.0)))
   println(diversityTheorem(49.0, Array(48.0, 47.0, 51.0, 42.0)))
 }

}</lang>

Output:
average-error :  3.000
crowd-error   :  0.111
diversity     :  2.889

average-error : 14.500
crowd-error   :  4.000
diversity     : 10.500

Sidef

Translation of: Raku

<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 }

Wren

Translation of: Go

<lang ecmascript>import "/fmt" for Fmt

var averageSquareDiff = Fn.new { |f, preds|

   var av = 0
   for (pred in preds) av = av + (pred-f)*(pred-f)
   return av/preds.count

}

var diversityTheorem = Fn.new { |truth, preds|

   var av = (preds.reduce { |sum, pred| sum + pred }) / preds.count
   var avErr = averageSquareDiff.call(truth, preds)
   var crowdErr = (truth-av) * (truth-av)
   var div = averageSquareDiff.call(av, preds)
   return [avErr, crowdErr, div]

}

var predsList = [ [48, 47, 51], [48, 47, 51, 42] ] var truth = 49 for (preds in predsList) {

   var res = diversityTheorem.call(truth, preds)
   Fmt.print("Average-error : $6.3f", res[0])
   Fmt.print("Crowd-error   : $6.3f", res[1])
   Fmt.print("Diversity     : $6.3f\n", res[2])

}</lang>

Output:
Average-error :  3.000
Crowd-error   :  0.111
Diversity     :  2.889

Average-error : 14.500
Crowd-error   :  4.000
Diversity     : 10.500

zkl

Translation of: Sidef

<lang zkl>fcn avgError(m,v){ v.apply('wrap(n){ (n - m).pow(2) }).sum(0.0)/v.len() }

fcn diversityCalc(truth,pred){ //(Float,List of Float)

  ae,cp := avgError(truth,pred), pred.sum(0.0)/pred.len();
  ce,pd := (cp - truth).pow(2),  avgError(cp, pred);
  return(ae,ce,pd)

}

fcn diversityFormat(stats){ // ( (averageError,crowdError,diversity) )

  T("average-error","crowd-error","diversity").zip(stats)
  .pump(String,Void.Xplode,"%13s :%7.3f\n".fmt)

}</lang> <lang zkl>diversityCalc(49.0, T(48.0,47.0,51.0)) : diversityFormat(_).println(); diversityCalc(49.0, T(48.0,47.0,51.0,42.0)) : diversityFormat(_).println();</lang>

Output:
average-error :  3.000
  crowd-error :  0.111
    diversity :  2.889

average-error : 14.500
  crowd-error :  4.000
    diversity : 10.500