Ejemplo n.º 1
0
        public void Predict()
        {
            EbisuModel m = new EbisuModel(2, 2, 2);
            double     p = Ebisu.PredictRecall(m, 2, true);

            Assert.AreEqual(0.5, p, EPS, "1 + 1 should equal 2");
        }
Ejemplo n.º 2
0
        public void TestAgainstReference()
        {
            try
            {
                // All this boilerplate is just to load JSON

                double   maxTol         = 5e-3;
                string   path           = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"Ebisu/Ebisu_test.json");
                string[] testData       = File.ReadAllLines(path);
                JArray   expectedResult = (JArray)JsonConvert.DeserializeObject(testData[0]);

                foreach (var child in expectedResult)
                {
                    //subtest might be either
                    // a) ["update", [3.3, 4.4, 1.0], [0, 5, 0.1], {"post": [7.333641958415551, 8.949256654818793,
                    // 0.4148304099305316]}] or b) ["predict", [34.4, 34.4, 1.0], [5.5], {"mean": 0.026134289032202798}]
                    //
                    // In both cases, the first two elements are a string and an array of numbers. Then the remaining vary depend on
                    // what that string is. where the numbers are arbitrary. So here we go...
                    String operation = child[0].ToString();

                    JArray     second = (JArray)child[1];
                    EbisuModel ebisu  = new EbisuModel(double.Parse(second[2].ToString()), double.Parse(second[0].ToString()), double.Parse(second[1].ToString()));

                    if (operation.Equals("update"))
                    {
                        int        successes = Convert.ToInt32(child[2][0].ToString());
                        int        total     = Convert.ToInt32(child[2][1].ToString());
                        double     t         = Convert.ToDouble(child[2][2].ToString());
                        JArray     third     = (JArray)child[3].Last.Last;//subtest.get(3).get("post");
                        EbisuModel expected  = new EbisuModel(double.Parse(third[2].ToString()), double.Parse(third[0].ToString()), double.Parse(third[1].ToString()));

                        IEbisu actual = Ebisu.UpdateRecall(ebisu, successes, total, t);

                        Assert.AreEqual(expected.getAlpha(), actual.getAlpha(), maxTol);
                        Assert.AreEqual(expected.getBeta(), actual.getBeta(), maxTol);
                        Assert.AreEqual(expected.getTime(), actual.getTime(), maxTol);
                    }
                    else if (operation.Equals("predict"))
                    {
                        double t        = Convert.ToDouble(child[2][0].ToString());
                        double expected = Convert.ToDouble(child[3].First.Last.ToString());
                        double actual   = Ebisu.PredictRecall(ebisu, t, true);
                        Assert.AreEqual(expected, actual, maxTol);
                    }
                    else
                    {
                        throw new Exception("unknown operation");
                    }
                }
            }
            catch (Exception ex)
            {
                ex.StackTrace.ToString();
                Console.WriteLine("¡¡¡OOOPS SOMETHING BAD HAPPENED!!!");
                Assert.IsTrue(false);
            }
        }
Ejemplo n.º 3
0
        public void TestHalflife()
        {
            double     hl = 20.0;
            EbisuModel m  = new EbisuModel(hl, 2, 2);

            Assert.True(Math.Abs(Ebisu.ModelToPercentileDecay(m, .5, true) - hl) > 1e-2);
            Assert.True(Relerr(Ebisu.ModelToPercentileDecay(m, .5, 1e-6), hl) < 1e-3);
            //Assert.Throws<Exception>(() => Ebisu.ModelToPercentileDecay(m, 0.5, 1e-150));
        }
Ejemplo n.º 4
0
        /**
         * Actual worker method that calculates the posterior memory model at the same
         * time in the future as the prior, and rebalances as necessary.
         */
        private static IEbisu UpdateRecall(IEbisu prior, int successes, int total, double tnow,
                                           bool rebalance, double tback)
        {
            double alpha = prior.getAlpha();
            double beta  = prior.getBeta();
            double t     = prior.getTime();
            double dt    = tnow / t;
            double et    = tback / tnow;

            double[] binomlns = Enumerable.Range(0, total - successes + 1).Select(i => LogBinom(total - successes, i)).ToArray();
            double[] logs     =
                Enumerable.Range(0, 3)
                .Select(m =>
            {
                List <Double> a =
                    Enumerable.Range(0, total - successes + 1)
                    .Select(i => binomlns[i] + LogBeta(beta, alpha + dt * (successes + i) + m * dt * et)).ToList();
                //.boxed()
                //.collect(Collectors.toList());
                List <Double> b = Enumerable.Range(0, total - successes + 1)
                                  .Select(i => Math.Pow(-1.0, i)).ToList();
                //.boxed()
                //.collect(Collectors.toList());
                return(LogSumExp(a, b)[0]);
            }).ToArray();

            double logDenominator = logs[0];
            double logMeanNum     = logs[1];
            double logM2Num       = logs[2];

            double mean   = Math.Exp(logMeanNum - logDenominator);
            double m2     = Math.Exp(logM2Num - logDenominator);
            double meanSq = Math.Exp(2 * (logMeanNum - logDenominator));
            double sig2   = m2 - meanSq;

            if (mean <= 0)
            {
                throw new Exception("invalid mean found");
            }
            if (m2 <= 0)
            {
                throw new Exception("invalid second moment found");
            }
            if (sig2 <= 0)
            {
                throw new Exception("invalid variance found " +
                                    String.Format("a=%g, b=%g, t=%g, k=%d, n=%d, tnow=%g, mean=%g, m2=%g, sig2=%g", alpha,
                                                  beta, t, successes, total, tnow, mean, m2, sig2));
            }
            List <Double> newAlphaBeta = MeanVarToBeta(mean, sig2);
            EbisuModel    proposed     = new EbisuModel(tback, newAlphaBeta[0], newAlphaBeta[1]);

            return(rebalance ? Rebalance(prior, successes, total, tnow, proposed) : proposed);
        }
Ejemplo n.º 5
0
        public void Update()
        {
            IEbisu m       = new EbisuModel(2, 2, 2);
            IEbisu success = Ebisu.UpdateRecall(m, 1, 1, 2.0);
            IEbisu failure = Ebisu.UpdateRecall(m, 0, 1, 2.0);

            Assert.AreEqual(3.0, success.getAlpha(), 500 * EPS, "success/alpha");
            Assert.AreEqual(2.0, success.getBeta(), 500 * EPS, "success/beta");

            Assert.AreEqual(2.0, failure.getAlpha(), 500 * EPS, "failure/alpha");
            Assert.AreEqual(3.0, failure.getBeta(), 500 * EPS, "failure/beta");
        }