如何使用自定义权重计算加权移动平均值?

时间:2019-02-14 18:41:03

标签: r moving-average weighted-average

我正在使用NHL播放器性能数据,并具有一个包含以下变量的数据框(以及其他变量)。 war_82是整个82个游戏赛季中玩家价值的衡量标准。数据涵盖了从2007-2008年到2017-2018年的11个季节。

 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。

更新的清晰度:我希望计算加权移动平均值。例如;悉尼·克罗斯比(Sidney Crosby)的20172018_weighted_war将由2017-2018、2016-2017和2015-2016确定。他的20162017_weighted_war将在2016-2017、2015-2016和2014-2015之前确定。依此类推。

我有两个主要问题:

1)您会为此推荐什么方法?我已经看过weighted.mean(),但是有些球员比其他人玩的更多,所以我不确定如何指定“ w”(权重)参数。例如,在我的数据集中,西德尼·克罗斯比(Sidney Crosby)曾在全部11个赛季中踢球,但许多球员只在1或2个赛季中踢球。我真的不想丢掉少于三个赛季的球员数据。

2)您将如何确定每个季节的权重?最简单的方法是我上面提到的方法,该方法受Marcel方法(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 :(得分:2)

我对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)

答案 1 :(得分:1)

我建议每个帖子坚持一个问题。蛮力解决您的第一个问题是根据季节数明确表示权重:

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

答案 2 :(得分:0)

您可以根据自己的建议使用weighted.mean(),并根据11个赛季中的第几个赛季数加权(1个赛季-> 0.091,2-> 0.18,依此类推)。