Статьи

Р: Подумайте о проблеме Байеса с локомотивом, или задних вероятностях для разных априорных значений.

В моем продолжении чтения Think Bayes следующая проблема, которую необходимо решить, — это проблема локомотива, которая определяется следующим образом:

Железная дорога нумерует свои локомотивы в порядке 1..N.

Однажды вы видите локомотив с номером 60. Оцените, сколько локомотивов у железной дороги.

Интересная вещь в этом вопросе заключается в том, что изначально кажется, что у нас недостаточно информации, чтобы найти какой-либо ответ. Тем не менее, мы можем получить оценку, если мы придумали до работы с.

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

Затем мы можем написать такой же код, как и в случае с игрой в кости, чтобы обновить предыдущее на основе поездов, которые мы видели.

Сначала мы создадим фрейм данных, который фиксирует произведение «количества локомотивов» и наблюдений локомотивов, которые мы видели (в данном случае мы видели только один локомотив с номером «60» 🙂

library(dplyr)

possibleValues = 1:1000
observations = c(60)

l = list(value = possibleValues, observation = observations)
df = expand.grid(l) 

> df %>% head()
  value observation
1     1          60
2     2          60
3     3          60
4     4          60
5     5          60
6     6          60

Затем мы хотим добавить столбец, который представляет вероятность того, что наблюдаемый локомотив мог прибыть из определенного парка. Если количество железных дорог меньше 60, то вероятность 0, в противном случае имеем 1 / numberOfRailroadsInFleet:

prior = 1  / length(possibleValues)
df = df %>% mutate(score = ifelse(value < observation, 0, 1/value))

> df %>% sample_n(10)
     value observation       score
179    179          60 0.005586592
1001  1001          60 0.000999001
400    400          60 0.002500000
438    438          60 0.002283105
667    667          60 0.001499250
661    661          60 0.001512859
284    284          60 0.003521127
233    233          60 0.004291845
917    917          60 0.001090513
173    173          60 0.005780347

Чтобы найти вероятность каждого размера флота, мы пишем следующий код:

weightedDf = df %>% 
  group_by(value) %>% 
  summarise(aggScore = prior * prod(score)) %>%
  ungroup() %>%
  mutate(weighted = aggScore / sum(aggScore))

> weightedDf %>% sample_n(10)
Source: local data frame [10 x 3]

   value     aggScore     weighted
1    906 1.102650e-06 0.0003909489
2    262 3.812981e-06 0.0013519072
3    994 1.005031e-06 0.0003563377
4    669 1.493275e-06 0.0005294465
5    806 1.239455e-06 0.0004394537
6    673 1.484400e-06 0.0005262997
7    416 2.401445e-06 0.0008514416
8    624 1.600963e-06 0.0005676277
9     40 0.000000e+00 0.0000000000
10   248 4.028230e-06 0.0014282246

Давайте построим фрейм данных, чтобы увидеть, как изменяется вероятность для каждого размера парка:

library(ggplot2)
ggplot(aes(x = value, y = weighted), data = weightedDf) + 
  geom_line(color="dark blue")

2015 04 25 00 25 47

Наиболее вероятный выбор — размер флота 60, основанный на этой диаграмме, но альтернативой было бы найти среднее значение апостериорного значения, которое мы можем сделать так:

> weightedDf %>% mutate(mean = value * weighted) %>% select(mean) %>% sum()
[1] 333.6561

Теперь давайте создадим функцию со всем этим кодом, чтобы мы могли поиграть с некоторыми другими априорами и наблюдениями:

meanOfPosterior = function(values, observations) {
  l = list(value = values, observation = observations)   
  df = expand.grid(l) %>% mutate(score = ifelse(value < observation, 0, 1/value))

  prior = 1  / length(possibleValues)
  weightedDf = df %>% 
    group_by(value) %>% 
    summarise(aggScore = prior * prod(score)) %>%
    ungroup() %>%
    mutate(weighted = aggScore / sum(aggScore))

  return (weightedDf %>% mutate(mean = value * weighted) %>% select(mean) %>% sum()) 
}

Если мы обновим наши наблюдаемые железные дороги на номера 60, 30 и 90, мы получим следующие средства для постеров, предполагающих разные приоры:

> meanOfPosterior(1:500, c(60, 30, 90))
[1] 151.8496
> meanOfPosterior(1:1000, c(60, 30, 90))
[1] 164.3056
> meanOfPosterior(1:2000, c(60, 30, 90))
[1] 171.3382

На данный момент функция предполагает, что мы всегда хотим иметь одинаковый априор, т. Е. Каждый вариант имеет равную возможность быть выбранным, но мы могли бы изменить априор, чтобы увидеть, как различные допущения влияют на апостериор.

Мы можем реорганизовать функцию для получения значений и априоров вместо вычисления априоров в функции:

meanOfPosterior = function(values, priors, observations) {
  priorDf = data.frame(value = values, prior = priors)
  l = list(value = priorDf$value, observation = observations)

  df = merge(expand.grid(l), priorDf, by.x = "value", by.y = "value") %>% 
    mutate(score = ifelse(value < observation, 0, 1 / value))

  df %>% 
    group_by(value) %>% 
    summarise(aggScore = max(prior) * prod(score)) %>%
    ungroup() %>%
    mutate(weighted = aggScore / sum(aggScore)) %>%
    mutate(mean = value * weighted) %>%
    select(mean) %>%
    sum()
}

Теперь давайте проверим, получаем ли мы одинаковые апостериорные средства для одинаковых приоров:

> meanOfPosterior(1:500,  1/length(1:500), c(60, 30, 90))
[1] 151.8496
> meanOfPosterior(1:1000, 1/length(1:1000), c(60, 30, 90))
[1] 164.3056
> meanOfPosterior(1:2000, 1/length(1:2000), c(60, 30, 90))
[1] 171.3382

Теперь, если вместо единообразного априора мы будем использовать степенной закон, в котором предполагается, что меньшие флоты более вероятны:

> meanOfPosterior(1:500,  sapply(1:500,  function(x) x ** -1), c(60, 30, 90))
[1] 130.7085
> meanOfPosterior(1:1000, sapply(1:1000, function(x) x ** -1), c(60, 30, 90))
[1] 133.2752
> meanOfPosterior(1:2000, sapply(1:2000, function(x) x ** -1), c(60, 30, 90))
[1] 133.9975
> meanOfPosterior(1:5000, sapply(1:5000, function(x) x ** -1), c(60, 30, 90))
[1] 134.212
> meanOfPosterior(1:10000, sapply(1:10000, function(x) x ** -1), c(60, 30, 90))
[1] 134.2435

Теперь мы получаем очень похожие апостериорные средства, которые сходятся на 134, и это наше лучшее предсказание.