Распознать максимальное движение в квазипеременных временных окнах

У меня есть таблица (track_t, Postgresql 9.5) временных меток и измерений скорости и расстояния от футболистов. Отметки времени начинаются до игры, примерно через 30 минут, и заканчиваются до 30 минут после окончания игры. У меня есть запрос, который может определить, какие 45-минутные диапазоны имеют наибольшее движение - avg(скорость) и sum(расстояние) - и, следовательно, вероятно, это будут времена, когда в игру играют.

SELECT
    tt.start_time
    , tt.game_id
    , tt.start_time AT TIME ZONE 'UTC' AT TIME ZONE 'CEST' + interval '45 minute' as end_time_lz
    , sum(aa.distance) as distance
    , avg(aa.speed) as speed
FROM
(
    SELECT
        game_id
        , GENERATE_SERIES(MIN(date_trunc('hour',ts)),max(date_trunc('minute',ts)),'1m') as start_time
    FROM track_t
        GROUP BY game_id
) tt
INNER JOIN
(
    SELECT
        game_id
        , avg(speed) as speed
        , sum(distance) as distance
        , date_trunc('minute',ts) as timestamp
    FROM track_t
    GROUP BY 
        game_id
        , date_trunc('minute',ts)
) aa
ON aa.game_id = tt.game_id
AND aa.timestamp >= tt.start_time 
AND aa.timestamp < tt.start_time + interval '45 minute'

GROUP BY
    tt.start_time
    , tt.game_id

ORDER BY
    SUM(aa.distance) desc
    , AVG(aa.speed) desc
;

Первая часть создает все 45-минутные окна с функцией GENERATE_SERIES(), основываясь на каждой минутной отметке. Итак, если игра началась в 10:00, а данные начинаются в 09:30, то я создаю 45-минутные окна в 09:30, 09:31, 09:32 и т. Д.

Вторая часть вычисляет среднюю скорость и общее расстояние для этого 45-минутного окна.

Затем, чтобы определить, какое 45-минутное окно является наиболее вероятным, я могу отсортировать по сумме (расстояние) и avg(скорость), чтобы определить время начала.

Результаты выглядят так (ограничить 10 упорядоченных строк)

start_time; game_id; end_time; sum(distance); avg(speed)
*"2016-09-03 17:03:00";"a20160903";"2016-09-03 17:48:00";47935.0703622001;1.06124213271675*
"2016-09-03 17:04:00";"a20160903";"2016-09-03 17:49:00";47761.7538393264;1.0572395112247
"2016-09-03 17:02:00";"a20160903";"2016-09-03 17:47:00";47642.3581425403;1.05482864669178
"2016-09-03 17:05:00";"a20160903";"2016-09-03 17:50:00";46949.1297795754;1.03702742158256
"2016-09-03 17:01:00";"a20160903";"2016-09-03 17:46:00";46868.0351728161;1.03604043683709
*"2016-09-03 17:58:00";"a20160903";"2016-09-03 18:43:00";46481.3160240327;1.03470232279402*
"2016-09-03 17:00:00";"a20160903";"2016-09-03 17:45:00";46454.0167265013;1.02557019844115
"2016-09-03 17:59:00";"a20160903";"2016-09-03 18:44:00";46183.0355093333;1.02985443158215
"2016-09-03 17:57:00";"a20160903";"2016-09-03 18:42:00";46059.2319184038;1.02059235291926
"2016-09-03 18:00:00";"a20160903";"2016-09-03 18:45:00";45984.1387791433;1.02661395680708

и два вероятных времени начала для каждой половины отмечены * (например, 17:03 и 17:58).

Это прекрасно работает для создания сортируемого списка, но как я могу автоматически выбрать время начала 1-й и 2-й половины?

Кроме того, половинное время игры обычно составляет более 45 минут из-за травм, которые могут составлять от 0 до 5+ минут на половину. Как я могу автоматически сканировать временные окна, которые включают в себя возможное время травмы, и составляют от 45 до 50 минут, и выбрать "окно максимального движения" из этих комбинаций?

Если вы начертите начальное время по оси x, а sum(расстояние) по оси y, вы увидите хорошее бимодальное искажение, поэтому я подумал о некоторой аналитической функции для распознавания времени полураспада, а также времени травмы.

бимодальное распределение

(часы не совпадают с данными выше из-за преобразования UTC/ местного времени)


Примечание: я бы предпочел сделать это с SQL (Postgres 9.5), но у меня есть оболочка Python, которую я могу использовать, что может дать больше библиотек машинного обучения.

0 ответов

Другие вопросы по тегам