R语言 计算季后赛系列赛的预期(剩余)胜利,给定系列赛的当前状态

00jrzges  于 2023-04-09  发布在  其他
关注(0)|答案(2)|浏览(108)

考虑一个篮球系列赛,7局4胜。在R中,我们有以下函数来计算一支球队在这样一个系列赛中的预期获胜次数,该球队具有一定的单场获胜概率wp_a

get_expected_wins <- function(wp_a = 0.50, num_games = 7, to_win = 4) {
  # compute expected wins for team_a
  # wp_a: a team's odds to win a single game
  # num_games: the maximum number of possible games remaining in the series
  # to_win: how many more games a team needs to win the series
  # 7,4 correspond to winning a best 4 out of 7 series
  
  # expected wins for the team
  prob_to_win_n_games <- dbinom(x = 0:num_games, size = num_games, prob = wp_a)
  num_wins <- c(0:to_win, rep(to_win, num_games - to_win))
  ewins <- sum(prob_to_win_games_a * num_wins)
  
  # and return
  return(ewins)
}

在函数中,prob_to_win_n_games应该是球队赢得0、1、2直到num_games场比赛的概率。考虑一个季后赛系列赛,其中一支球队以0-3落后,我们试图计算他们在系列赛中的预期剩余胜利次数。请记住,球队再输一场就结束了系列赛。我们要调用get_expected_wins(0.5, 4, 4)
在这个系列赛中,这支球队有50%的机会再赢得0场比赛。(输掉下一场比赛),25%赢得1场比赛(赢,然后输),12.5%赢得2场比赛(赢,赢,然后输),6.25%赢得3场比赛(赢,赢,赢,然后输)和6.25%赢得4场比赛(赢4x)。他们在系列赛中的预期胜利是0.5*0 + 0.25*1 + 0.125*2 + 0.0625*3 + 0.0625*4 = .9375
在本例中,num_games = 4to_win = 4,以及prob_to_win_n_games被错误地计算为0.0625 0.2500 0.3750 0.2500 0.0625。二项式无法考虑在额外损失之后的系列结束。它基于(4 choose 3) * (0.5 ^ 4)的计算计算25% 3次获胜的机会,但是4个可能的序列中的3个(L W W WW L W WW W L W)在我们理论上的季后赛系列赛中是不可能的,球队再输一场就结束了系列赛。只有W W W L才能让球队取得3胜。
我们如何更新这个函数,以正确计算球队赢得一定数量比赛的概率,给定我们为季后赛系列赛设置的参数。

bakd9h0s

bakd9h0s1#

如果获胜的次数小于to_win,则必须从dbinom给予的二项式系数(choose的第一个参数)中的顶部数字减去1。
这是因为输掉系列赛的唯一方式是输掉系列赛的最后一场比赛。对于输家的赢/输顺序没有其他限制。这意味着系列赛输家的胜利可以分配给除了最后一场比赛之外的所有比赛,这就是为什么我们必须从二项式系数中的顶部数字减去1。
这将返回看到0:to_win获胜的概率:

get_expected_wins <- function(wp_a = 0.50, num_games = 7, to_win = 4) {
  i <- to_win:1
  wins <- choose(num_games - i, to_win - i)*wp_a^(to_win - i)*(1 - wp_a)^(num_games - to_win + 1)
  setNames(c(wins, 1 - sum(wins)), 0:to_win)
}

get_expected_wins(0.5, 7, 4)
#>       0       1       2       3       4 
#> 0.06250 0.12500 0.15625 0.15625 0.50000
get_expected_wins(0.5, 6, 3)
#>       0       1       2       3 
#> 0.06250 0.12500 0.15625 0.65625
get_expected_wins(0.5, 4, 4)
#>      0      1      2      3      4 
#> 0.5000 0.2500 0.1250 0.0625 0.0625

或者,

get_expected_wins <- function(wp_a = 0.50, num_games = 7L, to_win = 4L) {
  k <- 0:(to_win - 1L)
  n <- (num_games - to_win + 1L):num_games
  wins <- dbinom(k, n, wp_a)*(n - k)/n
  setNames(c(wins, 1 - sum(wins)), 0:to_win)
}
zbdgwd5y

zbdgwd5y2#

df_approach <- function(p, num_games, to_win) {
  to_lose <- num_games - to_win + 1
  
  rows <- 2^num_games
  games_df <- data.frame(rows = 1:rows, wp = 1, wins = 0, loss = 0)
  for (i in 1:num_games) {
    games_df[paste0('gm', i)] <- c(rep(1, 2^(i-1)), rep(0, 2^(i-1)))
    games_df[paste0('p', i)] <- c(rep(p, 2^(i-1)), rep(1-p, 2^(i-1)))
    if (i == 1) {
      games_df$wp <- c(rep(p, 2^(i-1)), rep(1-p, 2^(i-1)))
    } else {
      games_df$wp <- zed$wp * c(rep(p, 2^(i-1)), rep(1-p, 2^(i-1)))
    }
  }
  
  for (i in 1:num_games) {
    col_key <- paste0('gm', i)
    games_df <- games_df %>%
      dplyr::mutate(wins = ifelse(wins == to_win | loss == to_lose, wins, wins + !!sym(col_key) )) %>%
      dplyr::mutate(loss = ifelse(wins == to_win | loss == to_lose, loss, loss + (1 - !!sym(col_key)) ))
  }
  
  ewins <- sum(games_df$wp * games_df$wins)
  return(ewins)
}

在@jblood94发布他的解决方案之前,我尝试了一种蛮力方法,该方法用每个可能的季后赛序列构建一个 Dataframe ,计算每个季后赛序列发生的几率,将胜利与季后赛系列在4胜/4负之后结束的约束相加,并计算每个序列中胜利的总和 * 每个序列的几率。
我刚刚比较了df_approach()get_expected_wins(),对于我尝试过的每一组不同的参数,输出都是相同的。

相关问题