在 R 中创建概率树

Creating Probability Trees in R

我正在使用 R 编程语言。

假设我有以下设置:

我想知道(精确解):

目前,我不知道该怎么做 - 我试图通过模拟“大量组合”来做到这一点,并希望我充分了解每种组合以推断出正确的概率:

library(dplyr)


results <- list()

 for (i in 1:100) {

iteration = i 
sample_i = sample(c("A", "B", "C", "D", "E"), size =5, replace = T, prob= c( 0.2, 0.3, 0.1, 0.3, 0.1))


my_data_i = data.frame(iteration, sample_i )

results[[i]] <- my_data_i

}

results_df <- data.frame(do.call(rbind.data.frame, results))

但这看起来是解决此问题的一种非常复杂的方法。最后,我会寻找这样的东西:

有人可以告诉我怎么做吗?

谢谢!

编辑:此解决方案适用于该示例,但对于具有更多有效数字的概率,很快就会耗尽内存。

  1. 创建与给定概率相对应的对象标签向量。
  2. 使用 expand.grid 生成所有可能的长度为 5 的组合。
  3. 结果中的唯一行数 == 可能的组合数。
  4. 每个组合占结果的比例==每个组合的概率
objs <- c(
  rep("A", 2),
  rep("B", 3),
  "C",
  rep("D", 3),
  "E"
)
combos <- expand.grid(
  p1 = objs,
  p2 = objs,
  p3 = objs,
  p4 = objs,
  p5 = objs
)
combos <- paste0(
  combos$p1, 
  combos$p2,
  combos$p3,
  combos$p4,
  combos$p5
)
n_combos <- length(combos)
combos_unique <- unique(combos)

# number of combinations
length(combos_unique)
# 3125

# probability of each combination
setNames(
  sapply(combos_unique, \(x) sum(combos == x) / n_combos),
  combos_unique
)

#   AAAAA   BAAAA   CAAAA   DAAAA   EAAAA   ABAAA   BBAAA   CBAAA   DBAAA   EBAAA 
# 0.00032 0.00048 0.00016 0.00048 0.00016 0.00048 0.00072 0.00024 0.00072 0.00024 
#   ACAAA   BCAAA   CCAAA   DCAAA   ECAAA   ADAAA   BDAAA   CDAAA   DDAAA   EDAAA 
# 0.00016 0.00024 0.00008 0.00024 0.00008 0.00048 0.00072 0.00024 0.00072 0.00024 
...

此解决方案的问题在于,行数将迅速增加,不仅对象更多或组合长度更长,而且有效数字的概率也会增加。例如,我只需要 3 个“B”来模拟 0.3 的概率,但需要 325 个才能模拟 0.325 的概率。

每个排列的总体概率是每个选定元素的概率的乘积。

library(RcppAlgos)

# Probabilities
probs <- setNames(c(0.2, 0.3, 0.1, 0.3, 0.1), LETTERS[1:5])

# Generate permutations
perms <- permuteGeneral(names(probs), repetition = TRUE)

# Collapse permutations
perm_res <- do.call(paste, c(asplit(perms, 2), sep = ""))

# Replace with probability values and coerce to numeric
perms[] <- probs[perms]
class(perms) <- "numeric"

# Calculate products
res <- data.frame(perm_res, prob = exp(rowSums(log(perms))))
head(res)

  perm_res    prob
1    AAAAA 0.00032
2    AAAAB 0.00048
3    AAAAC 0.00016
4    AAAAD 0.00048
5    AAAAE 0.00016
6    AAABA 0.00048

# Check total sums to 1
sum(res$prob)
[1] 1