Как рассчитать взвешенное скользящее среднее с пользовательскими весами? - PullRequest
0 голосов
/ 14 февраля 2019

Я работаю с данными о производительности игроков НХЛ и у меня есть фрейм данных со следующими переменными (среди прочих).war_82 - это показатель ценности игрока в течение всего 82 игрового сезона.Данные охватывают 11 сезонов, с 2007-2008 по 2017-2018 гг.

 first_name last_name season    war_82
   <chr>      <chr>     <chr>      <dbl>
 1 5EBASTIAN  AHO       2017-2018 -0.560
 2 AARON      DELL      2016-2017  7.50 
 3 AARON      DELL      2017-2018  1.61 
 4 AARON      DOWNEY    2007-2008 -0.560
 5 AARON      EKBLAD    2014-2015  0.350
 6 AARON      EKBLAD    2015-2016 -0.350
 7 AARON      EKBLAD    2016-2017 -1.39 
 8 AARON      EKBLAD    2017-2018 -0.320
 9 AARON      JOHNSON   2007-2008 -1.42 
10 AARON      JOHNSON   2008-2009 -1.19 

Я бы хотел уменьшить межсезонную изменчивость показателя war_82 и создать новую переменную, которая будет взвешеннойwar_82.В идеале я бы посмотрел на 3 сезона данных, и сезон n (текущий сезон) был бы наиболее сильно взвешенным, а сезоны n-1 и n-2 (два предыдущих сезона) были менее тяжело взвешены по мере уменьшения недавности.Скажем, вес 0,5, 0,3 и 0,2 ради аргумента.

ОБНОВЛЕНИЕ ДЛЯ ЯСНОСТИ: Я надеюсь вычислить взвешенное скользящее среднее.Например;2017-2018_weighted_war Сидни Кросби будет определен к 2017-2018, 2016-2017 и 2015-2016 гг.Его 20162017_weighted_war будет определен к 2016-2017, 2015-2016 и 2014-2015 гг.И так далее.

У меня есть два основных вопроса:

1) Какой метод вы бы порекомендовали для этого?Я посмотрел на weighted.mean (), но некоторые игроки играли больше, чем другие, поэтому я не уверен, как указать аргумент "w" (весовые коэффициенты).Например, Сидни Кросби играл в течение всех 11 сезонов в моем наборе данных, но многие игроки играли только в течение 1 или 2 сезонов.Я не хочу выбрасывать данные об игроках, сыгравших менее 3 сезонов.

2) Как бы вы определили вес для каждого сезона?Самый простой метод - тот, который я упомянул выше, который был вдохновлен методом Марселя (https://www.beyondtheboxscore.com/2016/2/22/11079186/projections-marcel-pecota-zips-steamer-explained-guide-math-is-fun). Полагаю, вы также можете определить, насколько хорошо сезоны n-1 и n-2 предсказывают сезон n, и использоватькак ваши веса?

Как бы вы подошли к этой проблеме? Любое и все руководство очень ценится!

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

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

library(tidyverse)

df <- tribble(
  ~player, ~season, ~y,
  "dell", 2017, 1,
  "dell", 2018, 5,
  "johnson", 2016, 2,
  "johnson", 2017, 4,
  "johnson", 2018, 5,
  "downey", 2014, 3,
  "downey", 2015, 5
)

df %>%
  group_by(player) %>%
  arrange(player, season) %>%
  add_count(player, name = "num_seasons") %>%
  mutate(
    wtd = case_when(
      num_seasons == 1 ~ sum(                                           1.000 * nth(y, -1) ),
      num_seasons == 2 ~ sum(                      0.375 * nth(y, -2) + 0.625 * nth(y, -1) ),
      num_seasons == 3 ~ sum( 0.200 * nth(y, -3) + 0.300 * nth(y, -2) + 0.500 * nth(y, -1) )
    )
  )
#> # A tibble: 7 x 5
#> # Groups:   player [3]
#>   player  season     y num_seasons   wtd
#>   <chr>    <dbl> <dbl>       <int> <dbl>
#> 1 dell      2017     1           2  3.5 
#> 2 dell      2018     5           2  3.5 
#> 3 downey    2014     3           2  4.25
#> 4 downey    2015     5           2  4.25
#> 5 johnson   2016     2           3  4.1 
#> 6 johnson   2017     4           3  4.1 
#> 7 johnson   2018     5           3  4.1
0 голосов
/ 14 февраля 2019

У меня есть аналогичный ответ на JasonAizkalns, но он достаточно отличается, так что я думаю, что это может стоить опубликовать.

Вы можете поиграть с весами для сезонов.

РЕДАКТИРОВАТЬ: Добавлено 'скользящее среднее '

data <- readr::read_table("
first_name last_name season    war_82
5EBASTIAN  AHO       2017-2018 -0.560
AARON      DELL      2016-2017  7.50 
AARON      DELL      2017-2018  1.61 
AARON      DOWNEY    2007-2008 -0.560
AARON      EKBLAD    2014-2015  0.350
AARON      EKBLAD    2015-2016 -0.350
AARON      EKBLAD    2016-2017 -1.39 
AARON      EKBLAD    2017-2018 -0.320
AARON      JOHNSON   2007-2008 -1.42 
AARON      JOHNSON   2008-2009 -1.19")

weigth_war <- function(last3_war) {
    player_season <- as.numeric(stringr::str_split_fixed(last3_war, " ", 3))
    if (is.na(player_season[2]))
        player_season[1]
    else if (is.na(player_season[3]))
        weighted.mean(player_season[1:2], c(0.3, 0.7))
    else
        weighted.mean(player_season, c(0.2, 0.3, 0.5))
}

library(tidyverse)
data %>%
    mutate(name = paste(first_name, last_name)) %>%
    group_by(name) %>%
    arrange(name, season) %>%
    mutate(last3_war = paste(war_82, lag(war_82), lag(war_82, 2))) %>%
    ungroup() %>%
    rowwise() %>%
    mutate(weighted_war_82 = weigth_war(last3_war)) %>%
    select(name, season, war_82, weighted_war_82)
0 голосов
/ 14 февраля 2019

Вы можете использовать weighted.mean () по своему усмотрению и весить по количеству сыгранных сезонов из 11 (1 сезон -> 0,091, 2 -> 0,18 и т. Д.).

...