How to automatically adjust algorithm parameters?

Here's the setting:

I have an algorithm that can succeed or fail. I want to be successful with the highest probability. The probability of success depends on some parameters (and some external circumstances):

struct Parameters {
  float param1;
  float param2;
  float param3;
  float param4;
  // ...
};

bool RunAlgorithm (const Parameters& parameters) {
  // ...
  // P(return true) is a function of parameters.
}

      

How to (automatically) find the best parameters with the fewest calls in RunAlgorithm? I would be especially happy with the readl library.

If you need more information on my specific case:

  • The probability of success is a smooth function of the parameters and has one global optimum.
  • There are about 10 parameters, most of which are independently configurable (but some of them are interdependent)
  • I ran the setup overnight, I can handle about 1000 calls to run the algorithm.

Clarification:

The best parameters should be set automatically overnight and used throughout the day. External circumstances change every day, so it is impossible to calculate them once and for all.

Additional explanations:

RunAlgorithm is actually a game algorithm. He plays the whole game (Go or Chess) against a fixed opponent. I can play 1000 games in one night. Every night a different enemy.

I want different opponents to need different parameters.

RunAlgorithm is smooth in the sense that changing the parameter slightly changes the algorithm a little.

The probability of success can be estimated by a large number of samples with the same parameters. But it's too difficult to run so many games without changing the parameters.

I could try to optimize each parameter independently (which would result in 100 runs per parameter), but I think there are some dependencies.

The whole problem is to use limited data intelligently.

The games played are very randomized, no problem.

+2


source to share


6 answers


You may be looking for genetic algorithms .



+3


source


Why not let the program fight itself? Take some vector v (parameters) and let it fight v + (0,1,0,0,0, .., 0), say 15 times. Then take the winner and change another parameter, and so on. With enough luck, you will end up with a strong player who can defeat most others.

Previous answer (most of its problem after editing question) :

With these assumptions and a level of community, you will not achieve anything (except, perhaps, the result of impossibility).

The main question is: can you change the algorithm so that it returns the probability of success, rather than the result of one experiment? Then use the appropriate optimization technique (nobody will tell you what under such general assumptions). In Haskell, you can even modify the code so that it can find the probability in simple cases (the probability of monad instead of giving a single result. The others mentioned above, you can use a genetic algorithm using probability as a fitness function. If you have a formula, use computer algebra to find the maximum value.

The probability of success is a smooth function of the parameters and has one global optimum.

Smooth or continuous? If you're fluent, you can use differential calculus ( Lagrange multipliers? ). You can, even with small changes in your code (provided your programming language is fairly general), automatically compute derivatives using automatic differentiation .



I ran the setup overnight, I can handle about 1000 calls to run the algorithm.

This complex? This will allow you to test two possible values ​​(2 10 = 1024), out of many floats. You won't even define an order of magnitude or even an order of magnitude.

There are about 10 parameters, most of which are independently configurable (but some of them are interdependent)

If you know what is independent, correct some of the settings and change the ones that are independent, for example, in the "Divide and Control" section. It is obviously much better to tune two algorithms with 5 parameters.

I am making a question if you don’t provide more details. It has too much buzz for an academic question and not enough data for a real question.

+2


source


The main problem is that with ten parameters, 1000 runs is almost nothing, given that for each run, all you have is a true / false result, not the P (success) associated with the parameters.

Here is an idea that, on the one hand, can make the best use of your 1000 runs, and on the other hand, also illustrates the insolubility of your problem. Let's assume that ten parameters are really independent. Select two values ​​for each parameter (for example, "high" value and "low" value). There are 1,024 ways to choose unique combinations of these values; run your method for each combination and save the result. When you're done, you have 512 test runs for each value of each parameter; with an assumption of independence that can give you a decent estimate of the conditional probability of success for each value. Analyzing this data should give you a little bit of information on how to tune the settings and may suggest refinements to your "high" and "low "values ​​for future nights. Deep in my mind, we extract ANOVA as a useful statistical tool here.

Very vague advice ... but as noted, this is a rather vague issue.

+2


source


In particular, for setting parameters for game agents, you may be interested in CLOP

http://remi.coulom.free.fr/CLOP/

+1


source


Not sure if I understood correctly ...

If you can choose parameters for your algorithm, does that mean you can choose it once for everyone?

Then you could simply:

  • the developer runs all / many cases only once, finds the best case and replaces the parameters with the best value
  • at runtime for your real user, the algorithm is already parameterized with the best parameters

Or, if the best values ​​change for each run ... Are you looking for the Genetic Algorithms approach type ?

0


source


The answer to this question depends on:

  • Parameter range. Can your parameters have a small or large range of values?
  • Game evaluation. Should it be logical or could it be a smooth function?

One approach that seems natural to this problem is Hill Climbing .

A possible way of doing this is to start with a few items and calculate their "score". Then figure out the favorable direction for the next point and try to "climb".

The main problems I see with this question as you presented it are the huge range of parameter values ​​and the fact that the result of the execution is boolean (not numeric). This will take a lot of runs to find out if the set of selected parameters is really good, but on the other hand, there is a huge set of parameter values ​​still to be tested. Just checking all directions will result in (too?) A lot of runs.

0


source







All Articles