Оптимизировать сумму квадратов различий (SSD) в NumPy - PullRequest
0 голосов
/ 10 июня 2018

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

**Sample SSD for individual match_i with Final score [0-0]**
xG is unique in each match. 
Team1 and Team2 has the following xG multiplied by arbitrary multiplier M.

Team1 = xG_1*M
Team2 = xG_2*M
prob_1 = [1-(xG_1 + xG_2)/k, xG_1/k, xG_2/k].

, где Prob_1 - постоянная вероятность Draw, Team1 Goal или Team2 Goal для каждого таймслота (k) на match_i, где sum(prob_1) = 1.

Для измерения SSD для match_i.

x1 = [1,0,0] #; prob. of No goal scored per timeslot.
x2 = [0,1,0] #; prob. of Home Team scoring per timeslot.
x3 = [0,0,1] #; prob. of Away Team scoring per timeslot.    
y  = np.array([1-(xG_1 + xG_2)/k, xG_1/k, xG_2/k])
#    Using xG_Team1 and xG_Team2 from table below.

total_timeslot = 180 
Home_Goal = [] # No Goal scored
Away_Goal = [] # Np Goal scored

def sum_squared_diff(x1, x2, x3, y):
    ssd=[]
    for k in range(total_timeslot):
        if k in Home_Goal:
            ssd.append( sum((x2 - y)**2))
        elif k in Away_Goal:
            ssd.append(sum((x3 - y)**2))
        else:
            ssd.append(sum((x1 - y)**2))
    return ssd


SSD_Result =  sum_squared_diff(x1, x2, x3, y)
sum(SSD_Result)

Например, используя xGs из index 0 из таблицы ниже и M = 1

First, for k = 187 timeslot, xG per timeslot becomes    1.4405394105672238/187, 1.3800950382265837/187 
and are constant throughout the match. 
y_0  = np.array([1-(0.007703419308 + 0.007380187370)/187, 0.007703419308/187, 0.007380187370/187])
Using y_0 in the function above, 
SSD_Result for xG at index 0 is  1.8252675137316426e-06.

Поскольку SSD выглядит, это выглядит многообещающе, но с другой стороны совпадениезакончился без цели и у двух команд почти одинаковые xG figure .... Теперь я хочу применить ту же процедуру к xG index 1, xG index 2....xG index 10000. Затем взять общую сумму SSD и, в зависимости от значения, изменить произвольный множитель M до наилучшегорезультат достигнут.

** Вопрос **

How can I convert the xG in each match to prob_1 like array and call it into the function above?
i.e. prob_1...prob_10000. Here's sample of xG. 

individual_match_xG.tail()
     xG_Team1  xG_Team2
0  1.440539  1.380095
1  2.123673  0.946116
2  1.819697  0.921660
3  1.132676  1.375717
4  1.244837  1.269933

Итак, в заключение

* There are 10000 Final Score's with xG that I want to turn into 10000 prob_1. Then get an SSD for each. 
* K is Total timeslote per match and is constant depending on the length of the intervals. For 30 sec timeslots, k is 180. Plus 7/2 mints of injuy time, k=187. 
* Home_Goal, Away_Goal and No_Goal  represents the prob. of a single goal scored per timeslot by the respective Team or No goal being scored. 
* Only one Goal can be scored per timeslot.

1 Ответ

0 голосов
/ 11 июня 2018
import numpy as np
# constants
M = 1.0
k = 180    # number of timeslots
x1 = [1,0,0] # prob. of No goal scored per timeslot.
x2 = [0,1,0] # prob. of Home Team scoring per timeslot.
x3 = [0,0,1] # prob. of Away Team scoring per timeslot.    

# seven scores
final_scores = [[2,1],[3,3],[1,2],[1,1],[2,1],[4,0],[2,3]]

# time slots with goals
Home_Goal = [2, 3]
Away_Goal = [4]

# numpy arrays of the data
final_scores = np.array(final_scores)    # team_1 is [:,0], team_2 is [:,1]
home_goal = np.array(Home_Goal)
away_goal = np.array(Away_Goal)

# fudge factor
adj_scores = final_scores * M    # shape --> (# of scores, 2)

# calculate prob_1
slot_goal_probability = adj_scores / k    # xG_n / k
slot_draw_probability = 1 - slot_goal_probability.sum(axis = 1)    #1-(xG_1+xG_2)/k

# y for all scores
y = np.concatenate((slot_draw_probability[:,None], slot_goal_probability), axis=1)


# ssd for x2, x3, x1
home_ssd = np.sum(np.square(x2 - y), axis=1)
away_ssd = np.sum(np.square(x3 - y), axis=1)
draw_ssd = np.sum(np.square(x1 - y), axis=1)

ssd = np.zeros((y.shape[0],k))
ssd += draw_ssd[:,None]    # all time slices a draw
ssd[:,home_goal] = home_ssd[:,None]    # time slots with goal for home games 
ssd[:,away_goal] = away_ssd[:,None]    # time slots with goal for away games

Сумма вероятностей (в вашем примере prob_1) для каждой оценки:

>>> y.sum(axis=1)
array([1., 1., 1., 1., 1., 1., 1.])

ssd имеет форму (количество оценок, 180) - она ​​содержит вероятность временного интервала длявсе баллы.

>>> ssd.sum(axis=1)
array([5.92222222, 6.        , 5.93333333, 5.93333333, 5.92222222,
       5.95555556, 5.96666667])
>>> for thing in ssd.sum(axis=1):
    print(thing)

5.922222222222222
6.000000000000001
5.933333333333332
5.933333333333337
5.922222222222222
5.955555555555557
5.966666666666663
>>>

Тест y с вашей функцией:

>>> y
array([[0.98333333, 0.01111111, 0.00555556],
       [0.96666667, 0.01666667, 0.01666667],
       [0.98333333, 0.00555556, 0.01111111],
       [0.98888889, 0.00555556, 0.00555556],
       [0.98333333, 0.01111111, 0.00555556],
       [0.97777778, 0.02222222, 0.        ],
       [0.97222222, 0.01111111, 0.01666667]])
>>> for prob in y:
    print(sum(sum_squared_diff(prob, x1, x2, x3)))

5.922222222222252
6.000000000000045
5.933333333333363
5.933333333333391
5.922222222222252
5.955555555555599
5.966666666666613
>>>

Некоторые, надеюсь, незначительные различия.Я приведу их к ошибкам с плавающей запятой или округлению в диапазоне 1e-14.


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


Основы Numpy:
Индексирование
Вещание

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