Task: Diversity prediction theorem







Python: 

from itertools import chain
from functools import reduce




def diversityValues(x):
    
    def go(ps):
        mp = mean(ps)
        return {
            'mean-error': meanErrorSquared(x)(ps),
            'crowd-error': pow(x - mp, 2),
            'diversity': meanErrorSquared(mp)(ps)
        }
    return go



def meanErrorSquared(x):
    
    def go(ps):
        return mean([
            pow(p - x, 2) for p in ps
        ])
    return go




def main():
    

    print(unlines(map(
        showDiversityValues(49),
        [
            [48, 47, 51],
            [48, 47, 51, 42],
            [50, '?', 50, {}, 50],  
            []                      
        ]
    )))
    print(unlines(map(
        showDiversityValues('49'),  
        [
            [50, 50, 50],
            [40, 35, 40],
        ]
    )))





def showDiversityValues(x):
    
    def go(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(indented(1), e)) if (
                    isinstance(e, list)
                ) else indented(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 go





def Left(x):
    
    return {'type': 'Either', 'Right': None, 'Left': x}



def Right(x):
    
    return {'type': 'Either', 'Left': None, 'Right': x}



def bindLR(m):
    
    def go(mf):
        return (
            mf(m.get('Right')) if None is m.get('Left') else m
        )
    return go



def compose(*fs):
    
    def go(f, g):
        def fg(x):
            return f(g(x))
        return fg
    return reduce(go, fs, identity)



def concatMap(f):
    
    def go(xs):
        return chain.from_iterable(map(f, xs))
    return go



def either(fl):
    
    return lambda fr: lambda e: fl(e['Left']) if (
        None is e['Right']
    ) else fr(e['Right'])



def identity(x):
    
    return x



def indented(n):
    
    return lambda s: (4 * ' ' * n) + s


def mean(xs):
    
    return sum(xs) / float(len(xs))



def numLR(x):
    
    return Right(x) if (
        isinstance(x, (float, int))
    ) else Left(
        'Expected number, saw: ' + (
            str(type(x)) + ' ' + repr(x)
        )
    )



def numsLR(xs):
    
    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)



def partitionEithers(lrs):
    
    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, ([], []))



def showList(xs):
    
    return '[' + ','.join(str(x) for x in xs) + ']'



def showPrecision(n):
    
    def go(x):
        return str(round(x, n))
    return go



def unlines(xs):
    
    return '\n'.join(xs)



if __name__ == '__main__':
    main()





Ada: with Ada.Text_IO;
with Ada.Command_Line;

procedure Diversity_Prediction is

   type Real is new Float;
   type Real_Array is array (Positive range <>) of Real;

   package Real_IO is new Ada.Text_Io.Float_IO (Real);
   use Ada.Text_IO, Ada.Command_Line, Real_IO;

   function Mean (Data : Real_Array) return Real is
      Sum : Real := 0.0;
   begin
      for V of Data loop
         Sum := Sum + V;
      end loop;
      return Sum / Real (Data'Length);
   end Mean;

   function Variance (Reference : Real; Data : Real_Array) return Real is
      Res : Real_Array (Data'Range);
   begin
      for A in Data'Range loop
         Res (A) := (Reference - Data (A)) ** 2;
      end loop;
      return Mean (Res);
   end Variance;

   procedure Diversity (Truth : Real; Estimates : Real_Array)
   is
      Average       : constant Real := Mean (Estimates);
      Average_Error : constant Real := Variance (Truth, Estimates);
      Crowd_Error   : constant Real := (Truth - Average) ** 2;
      Diversity     : constant Real := Variance (Average, Estimates);
   begin
      Real_IO.Default_Exp := 0;
      Real_IO.Default_Aft := 5;
      Put ("average-error : "); Put (Average_Error);  New_Line;
      Put ("crowd-error   : "); Put (Crowd_Error);    New_Line;
      Put ("diversity     : "); Put (Diversity);      New_Line;
   end Diversity;

begin
   if Argument_Count <= 1 then
      Put_Line ("Usage: diversity_prediction <truth> <data_1> <data_2> ...");
      return;
   end if;

   declare
      Truth     : constant Real := Real'Value (Argument (1));
      Estimates : Real_Array (2 .. Argument_Count);
   begin
      for A in 2 .. Argument_Count loop
         Estimates (A) := Real'Value (Argument (A));
      end loop;

      Diversity (Truth, Estimates);
   end;
end Diversity_Prediction;