如何创建具有条件概率的数据集?

机器算法验证 r 可能性 条件概率
2022-03-14 07:02:11

假设某种疾病 ( ) 的流行率为还假设某种症状()的患病率(在一般人群中=患有该疾病D 的人和没有该疾病的人 [可能患有其他疾病,但这并不重要])为在之前的研究中,发现条件概率 (在疾病的情况下出现症状的概率为)。D31000S51000P(S|D)=30%SD30%

第一个问题:是否可以将解释为等同于患有疾病的患病率?P(S|D)SD

第二个问题:我想在 R 中创建一个数据集,它表明:

P(D|S)=P(S|D)P(D)P(S)
使用我的虚构数据,我们可以计算,以这种方式解释的患者的概率P(D|S)=0.18SD18%

这该怎么做?如果我只使用该sample函数,我的数据集缺少的信息:P(S|D)=30%

symptom <- sample(c("yes","no"), 1000, prob=c(0.005, 0.995), rep=T)
disease <- sample(c("yes","no"), 1000, prob=c(0.002, 0.998), rep=T)

所以我的问题是:如何创建一个好的数据集,包括我想要的条件概率?

编辑:我也在stackoverflow.com(https://stackoverflow.com/questions/7291935/how-to-create-a-dataset-with-conditional-probability)上发布了同样的问题,因为在我看来,我的问题继承了R语言程序,也继承了统计理论。

4个回答

你知道以下边际概率

                Symptom        Total
                Yes     No
Disease Yes      a       b     0.003
        No       c       d     0.997  
Total           0.005   0.995  1.000

这样a/(a+b) = 0.3就变成了

                Symptom        Total
                Yes     No
Disease Yes     0.0009  0.0021 0.003
        No      0.0041  0.9929 0.997  
Total           0.005   0.995  1.000

确实a/(a+c) = 0.18如你所说。

所以在R中你可以编写类似的代码

diseaserate <- 3/1000
symptomrate <- 5/1000
symptomgivendisease <- 0.3

status  <- sample(c("SYDY", "SNDY", "SYDN", "SNDN"), 1000, 
            prob=c(diseaserate * symptomgivendisease,
                   diseaserate * (1-symptomgivendisease),
                   symptomrate - diseaserate * symptomgivendisease,
                   1 - symptomrate - diseaserate * (1-symptomgivendisease)),
            rep=TRUE)
symptom <- status %in% c("SYDY","SYDN")
disease <- status %in% c("SYDY","SNDY")

尽管您应该注意,当其中一个事件发生的概率为 0.0009 时,1000 是一个小样本。

table函数返回一个类似矩阵的对象:

> symptom <- sample(c("yes","no"), 100, prob=c(0.2, 0.8), rep=TRUE)
> disease <- sample(c("yes","no"), 100, prob=c(0.2, 0.8), rep=TRUE)
> dataset <- data.frame(symptom, disease)
> dst_S_D <-with(dataset, table(symptom, disease))
> dst_S_D
       disease
symptom no yes
    no  65  13
    yes 17   5

所以 Pr(D|S="yes") =

> probD_Sy <- dst_S_D[2, 2]/sum(dst_S_D[2, ] )
> probD_Sy
[1] 0.2272727

我改变了问题,因为我第一次使用您的参数运行它时,我得到了:

> dst_S_D <-with(dataset, table(symptom, disease)); dst_S_D
       disease
symptom   no  yes
    no  9954   22
    yes   24    0

而且我认为 0 的 Pr(D|S="yes") 相当无聊。如果您要运行多次,您应该构造一个函数并将该函数与该函数一起使用replicate

这是一种构建数据集的方法,该数据集在有症状组中应用不同的疾病概率,该概率比在无症状组中使用的高 3 倍:

symptom <- sample(c("yes","no"), 10000, prob=c(0.02, 0.98), rep=TRUE)
dataset <- data.frame(symptom, disease=NA)
dataset$disease[dataset$symptom == "yes"] <- 
       sample(c("yes","no"), sum(dataset$symptom == "yes"), prob=c(0.15, 1-0.15), rep=TRUE)
dataset$disease[dataset$symptom == "no"] <- 
        sample(c("yes","no"), sum(dataset$symptom == "no"), prob=c(0.05, 1-0.05), rep=TRUE)
 dst_S_D <-with(dataset, table(symptom, disease)); dst_S_D
#       disease
symptom   no  yes
    no  9284  509
    yes  176   31

我认为你的问题并不是真的那么严重依赖于 R 语言,在这里更合适,因为 - 坦率地说 - 像这样的数据的生成主要是一项统计任务,而不是编程任务。

第一个问题:p(S|D) 是在患有疾病 D 的人群中出现症状 S 的风险。它可以与某些警告的患病率直接比较,例如症状对疾病持续时间没有影响。考虑以下示例:超级埃博拉病毒的症状之一是即时死亡,p(Death | Super Ebola) = 0.99。在这里,您的症状患病率实际上会非常低(实际上是 0.00),因为您可以对患有该疾病的任何人进行采样都没有症状。

第二个问题:我会以一种逐步的方式回到这个问题。首先,计算您需要在整个人群中获得 0.15 的症状的基线风险,考虑到您的 0.03% 的人群将处于更高的比率。然后基本上产生两个概率:

  • 疾病风险 = 0.003
  • 症状风险 = 计算的基线风险 + 疾病引起的相对增加 * 疾病状态的二元指标

然后生成两个统一的随机数。如果第一个小于 0.003,他们就得了病。然后将其输入到第二个风险计算中,如果每个人的随机数小于他们的风险,他们就有了症状。

这是一种乏味、不优雅的做事方式,很可能有人会采用更有效的方法。但我发现在模拟研究中,拼写代码中的每一步,并使其尽可能接近我在现实世界中看到的数据集是有用的。

第一个问题:

是的,当然这几乎是定义,尽管您会有一些与样本量相关的错误。即这仅在无限样本量下是完全正确的。

第二个问题:

这称为贝叶斯定理,但我想你已经知道了。现在根据您提供的信息,我得到 P(D|S) 的概率为 0.18 或 18%:

P(S|D)P(D)
----------
   P(S)

  0.3*(3/1000)
= ------------
    (5/1000)

= 0.18

现在不幸的是,我对 R 不太熟悉,所以不能真正帮助你提供一个确切的程序。但是,每个组的人数肯定很容易计算:

对于您的 10000 个样本集,您需要:

  1. 50 人有症状(人口*P(S))
  2. 9 人应有症状和疾病 (50*P(D|S))
  3. 21 人患病且无症状(人口*P(D)=30,我们已经有 9 人)

这应该使产生合适的人口相当微不足道。