Что происходит, когда аргумент prob в образце сумм меньше / больше 1? - PullRequest
7 голосов
/ 26 января 2020

Мы знаем, что аргумент prob в sample используется для присвоения вероятности весов.

Например,

table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.4, 0.3, 0.1)))/1e6

#  1   2   3   4 
#0.2 0.4 0.3 0.1 


table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.4, 0.3, 0.1)))/1e6

#    1     2     3     4 
#0.200 0.400 0.299 0.100 

В этом примере сумма вероятности равна ровно 1 (0,2 + 0,4 + 0,3 + 0,1), следовательно, она дает ожидаемое соотношение, но что если вероятность не равняется 1? Какой выход это даст? Я думал, что это приведет к ошибке, но это дает некоторую ценность.

Когда вероятность составляет более 1 *

table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.5, 0.5, 0.1)))/1e6

#     1      2      3      4 
#0.1544 0.3839 0.3848 0.0768 

table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.5, 0.5, 0.1)))/1e6

#     1      2      3      4 
#0.1544 0.3842 0.3848 0.0767 

Когда вероятность составляет менее 1

table(sample(1:4, 1e6, replace = TRUE, prob = c(0.1, 0.1, 0.5, 0.1)))/1e6

#    1     2     3     4 
#0.124 0.125 0.625 0.125 

table(sample(1:4, 1e6, replace = TRUE, prob = c(0.1, 0.1, 0.5, 0.1)))/1e6

#    1     2     3     4 
#0.125 0.125 0.625 0.125 

Как мы видим, выполнение кратно times дает результат, который не равен prob, но результаты также не случайны. Как распределяются числа в этом случае? Где это задокументировано?

Я попытался выполнить поиск по inte rnet, но не нашел нужной информации. Я просмотрел документацию по ?sample, в которой есть

Необязательный аргумент prob можно использовать для получения вектора весов для получения элементов вектора выборки. Их не нужно суммировать с одним, но они должны быть неотрицательными и не равными нулю. Если replace true, метод псевдонима Уокера (Ripley, 1987) используется, когда существует более 200 разумно вероятных значений: это дает результаты, несовместимые с результатами из R <2.2.0. </p>

. что аргумент prob не обязательно должен быть равен 1, но не говорит, что ожидается, когда он не равен 1? Я не уверен, что мне не хватает какой-либо части документации. У кого-нибудь есть идеи?

Ответы [ 2 ]

6 голосов
/ 26 января 2020

Хороший вопрос. Документы по этому вопросу неясны, но на вопрос можно ответить, просмотрев исходный код.

Если вы посмотрите на код R, sample всегда вызывает другую функцию R, sample.int Если вы передаете одно число от x до sample, оно будет использовать sample.int для создания вектора целых чисел, меньшего или равного этому числу, тогда как, если x является вектором, оно использует sample.int для создания выборки целых чисел меньше или равно length(x), затем использует это для подмножества x.

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

function (n, size = n, replace = FALSE, prob = NULL, useHash = (!replace && 
    is.null(prob) && size <= n/2 && n > 1e+07)) 
{
    if (useHash) 
        .Internal(sample2(n, size))
    else .Internal(sample(n, size, replace, prob))
}

.Internal означает, что любая выборка выполняется путем вызова скомпилированного кода, записанного в C: в данном случае это функция do_sample, определенная здесь в src / main / random. c.

Если вы посмотрите на этот код C, do_sample проверяет, прошел ли он вектор prob. Если нет, то производится выборка в предположении равных весов. Если существует prob, функция гарантирует, что это число c, а не NA. Если prob проходит эти проверки, генерируется указатель на базовый массив значений типа double и передается другой функции в произвольном порядке. c называется FixUpProbs, здесь определяется .

This Функция проверяет каждый элемент prob и выдает ошибку, если какие-либо элементы prob не являются положительными конечными числами. Затем он нормализует числа путем деления каждого на сумму всех. Поэтому нет никакого предпочтения для суммирования prob с 1, присущего коду. То есть, даже если prob суммирует с 1 на вашем входе, функция все равно вычислит сумму и поделит на нее каждое число.

Следовательно, параметр имеет неправильное имя. Это должны быть «веса», как указали другие. Справедливости ради, в документах говорится только, что prob должен быть вектором весов, а не абсолютных вероятностей.

Таким образом, поведение параметра prob из моего чтения кода должно быть:

  1. prob может вообще отсутствовать, и в этом случае выборка по умолчанию равна равным весам.
  2. Если любое из чисел prob меньше нуля или бесконечно, или NA, функция скинет.
  3. Должна быть выдана ошибка, если любое из значений prob не является числовым c, так как они будут интерпретироваться как NA в SEXP, переданном в код C.
  4. prob должен иметь ту же длину, что и x или число C кодов
  5. Вы можете передать нулевую вероятность как один или несколько элементов prob, если вы указали replace=T До тех пор, пока у вас есть хотя бы одна ненулевая вероятность.
  6. Если вы укажете replace=F, количество запрашиваемых сэмплов должно быть меньше или равно количеству ненулевых элементов в prob. По сути, FixUpProbs скинет, если вы попросите его сделать выборку с нулевой вероятностью.
  7. Действительный вектор prob будет нормализован для суммирования до 1 и использован в качестве весов выборки.

Как интересный побочный эффект этого поведения, это позволяет вместо этого использовать коэффициенты вероятностей, если вы выбираете между 2 альтернативами, устанавливая пробники = c(1, odds)

6 голосов
/ 26 января 2020

Как уже упоминалось, веса нормированы на сумму 1, что может быть продемонстрировано:

> x/sum(x)
[1] 0.15384615 0.38461538 0.38461538 0.07692308

Это соответствует вашим смоделированным табличным данным:

#     1      2      3      4 
#0.1544 0.3839 0.3848 0.0768 
...