MATLAB: функция для расчета истинного рейтинга производительности Elo - PullRequest
0 голосов
/ 03 октября 2018

Я хочу создать функцию, которая вычисляет истинный рейтинг производительности Эло по отношению к играм в шахматы.

Для этого потребуется:

  1. Векторof game_results, например, [1 0 0,5], который указывает, что игрок выиграл первую игру, проиграл вторую игру и вытянул третью.Из этого мы получили бы другую переменную оценка, которая здесь равна 1,5, и другую переменную num_games, которая здесь равна 3.

  2. Вектор оппонентов, например, [1200 1400 1350], который указывает напервый оппонент получил рейтинг 1200, второй 1400 и третий 1350.

Я знаю, что истинный рейтинг производительности равен x в следующем уравнении:

for i = 1:num_games        
    score = score + (1/(1+10^((opp_ratings(i)-x)/400)));        
end

Что нужно, так это найти правильное значение x, чтобы сделать здесь оценку в сумме до фактической оценки 1,5.

Здесь я знаю, что x=1317.55 даст примерно правильный ответ.

Мне кажется, что мне нужно было бы передать анонимную функцию, содержащую этот код выше, какой-то другой оптимизирующей функции.Однако:

  1. Я понимаю из этого ответа , что анонимные функции не могут содержать циклы.

  2. Я неуверен, что оптимизирующая функция будет уместной.У MATLAB, похоже, нет собственной функции деления пополам.

1 Ответ

0 голосов
/ 03 октября 2018

Вы можете использовать решатель нелинейных уравнений, такой как fsolve.

fsolve найдет значение x для уравнения f(x) == 0.

Таким образом, вы можете создать функцию f(x) и запустить fsolve:

opp_ratings = [1200 1400 1350];
tot_score   = 1.5
f           = @(x) sum(1./(1+10.^((opp_ratings-x)/400)))-tot_score; 
res         = fsolve(f,0) %the second argument is the initial point x0

% res       =  1317.6

Заметил, что я линеаризовал ваш цикл for, используя операторы .^ (поэлементный оператор мощности) и ./ (поэлементное деление).Теперь стало проще определять однострочное уравнение f(x).

Кроме того, это деталь, но для улучшения производительности fsolve (уменьшения необходимого количества итераций) вы можете, например, установить начальноеЗначение x0 равно «среднему рейтингу ELO», скажем, 1000. Таким образом, fsolve(f,1000) будет статистически сходиться быстрее.

Не рекомендуется:

Если ваше уравнение не могло бытьлинеаризованный, вы действительно могли бы написать f(x) так:

f = @(x) sum(arrayfun(@(opp_ratings) (1/(1+10^((opp_ratings-x)/400))),opp_ratings))-tot_score  

используя arrayfun.Но по возможности избегайте этого решения (потому что оно уродливо и немного медленнее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...