1

I'm trying to minimise a value in Java usingcommons-math. I've had a look at their documentation but I don't really get how to implement it.

Basically, in my code below, I have a Double which has the expected goals in a soccer match and I'd like to optimise the probability value of under 3 goals occurring in a game to 0.5.


import org.apache.commons.math3.distribution.PoissonDistribution;
public class Solver {
 public static void main(String[] args) {
 final Double expectedGoals = 2.9d;
 final PoissonDistribution poissonGoals = new PoissonDistribution(expectedGoals);
 Double probabilityUnderThreeGoals = 0d;
 for (int score = 0; score < 15; score++) {
 final Double probability =
 poissonGoals.probability(score);
 if (score < 3) {
 probabilityUnderThreeGoals = probabilityUnderThreeGoals + probability;
 }
 }
 System.out.println(probabilityUnderThreeGoals); //prints 0.44596319855718064, I want to optimise this to 0.5
 }
}
asked Oct 27, 2021 at 16:40
2
  • How about expectedGoals = 2.67406 (if I understand correctly)? Also, note you can use cumulativeProbability(2) and don't need the loop. Commented Oct 27, 2021 at 16:57
  • @Sweeper yes, 2.67406 is the correct value- but I was wondering how to implement the optimization algorithm for future cases when trial and error isn't so straightforward. Commented Oct 27, 2021 at 17:03

1 Answer 1

1

The cumulative probability (<= x) of a Poisson random variable can be calculated by:

enter image description here

In your case, x is 2 and you want to find lambda (the mean) such that this is 0.5. You can type this into WolframAlpha and have it solve it for you. So rather than an optimisation problem, this is just a root-finding problem (though one could argue that optimisation problems are just finding roots.)

You can also do this with Apache Commons Maths, with one of the root finders.

int maximumGoals = 2;
double expectedProbability = 0.5;
UnivariateFunction f = x -> {
 double sum = 0;
 for (int i = 0; i <= maximumGoals; i++) {
 sum += Math.pow(x, i) / CombinatoricsUtils.factorialDouble(i);
 }
 return sum * Math.exp(-x) - expectedProbability;
};
// the four parameters that "solve" takes are:
// the number of iterations, the function to solve, min and max of the root
// I've put some somewhat sensible values as an example. Feel free to change them
double answer = new BisectionSolver().solve(Integer.MAX_VALUE, f, 0, maximumGoals / expectedProbability);
System.out.println("Solved: " + answer);
System.out.println("Cumulative Probability: " + new PoissonDistribution(answer).cumulativeProbability(maximumGoals));

This prints:

Solved: 2.674060344696045
Cumulative Probability: 0.4999999923623868
answered Oct 27, 2021 at 17:59

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.