Дискретные распределения представляют нам проблему при вычислении квантиля: мы начинаем с непрерывной переменной с реальным значением - вероятности - но результат (значение случайной переменной) должен быть действительно дискретным.
Рассмотрим, например, биномиальное распределение с размером выборки 50 и долей успеха 0,5. Существует множество способов построения дискретного дистрибутива, но если мы создаем PDF-файл в качестве пошаговой функции, то он выглядит примерно так:

Теперь предположим, что пользователь запрашивает квантиль, который соответствует вероятности 0,05, если мы увеличим CDF для этой области, вот что мы видим:

Как видно, нет случайной величины, которая соответствует вероятности ровно 0,05, поэтому у нас остается два варианта, как показано на рисунке:
- Мы могли бы округлить результат до 18.
- Мы могли бы округлить результат до 19.
На самом деле есть и третий вариант: мы могли бы «притвориться», что распределение было непрерывным, и вернуть реальный ценный результат: в этом случае мы бы вычислили результат примерно 18,701 (это точно отражает тот факт, что результат ближе к 19, чем к 18).
Используя политику, мы можем предложить любой из вышеперечисленных вариантов, но это все еще оставляет вопрос:Что в действительности является правильным?
В частности:Какую политику мы должны использовать по умолчанию?
Придя к ответу, мы должны понять, что:
- Вычисление целочисленного результата часто намного быстрее, чем вычисление реального результата: на самом деле в наших тестах он был в 20 раз быстрее.
- Обычно люди вычисляют квантили так, чтобы они могли выполнить тест какого-то рода:«Если случайная величина меньше N, то мы можем отклонить нашу нулевую гипотезу с 90% уверенностью».
Таким образом, действительно полезно вычислить целочисленный результат, а также то, что с философской точки зрения это «правильно». Более того, если кто-то просит квантиль на уровне 0,05, то мы обычно можем предположить, что они просятпо меньшей мере95% вероятности справа от выбранного значения ине более5% вероятности слева от выбранного значения.
В приведенном выше биномиальном примере мы бы округлили результат до 18.
Обратное относится к верхним квантилям: Если вероятность больше 0,5, мы хотели бы округлить квантиль вверх,так, чтобыпо меньшей мерезапрашиваемая вероятность находилась слева от возвращаемого значения, ане более1 — запрашиваемая вероятность находится справа от возвращаемого значения.
Аналогично для двухсторонних интервалов мы бы округлили нижние квантиля вниз, а верхние — вверх. Это гарантирует, что у нас естьпо крайней мере запрашиваемая вероятность в центральной областиине более 1 минус запрашиваемая вероятность в хвостовых областях.
Например, если мы возьмем наше 50-образное биномиальное распределение с долей успеха 0,5, если мы хотим двухсторонний 90%-й доверительный интервал, то мы попросим 0,05 и 0,95-й квантили с результатами, округленными наружу, так чтопо крайней мере 90% вероятностинаходится в центральной области:

Пока так хорошо, но на самом деле здесь есть ловушка, ожидающая неосторожных:
quantile(binomial(50, 0.5), 0.05);
В результате получается 18, что мы и ожидали бы от приведенного выше графика, и в действительности нет х больше 18, для которых:
cdf(binomial(50, 0.5), x) <= 0.05;
Однако:
quantile(binomial(50, 0.5), 0.95);
Возвращается 31, и в то же время не менее 31, для которого:
cdf(binomial(50, 0.5), x) >= 0.95;
Мы могли бы наивно ожидать, что для этого симметричного распределения результат будет 32 (поскольку 32 = 50 - 18), но мы должны помнить, что cdf биномиала составляетвключительнослучайной переменной. Таким образом, в то время как левая область хвоставключаетвозвращенный квантиль, правая область хвоста всегда исключает верхнее значение квантиля: поскольку это «принадлежит» центральной области.
Посмотрите на график выше, чтобы увидеть, что здесь происходит: нижний квантиль 18 принадлежит левому хвосту, поэтому любое значение<= 18 находится в левом хвосте. Верхний квантиль 31, с другой стороны, относится к центральной области, поэтому площадь хвоста фактически начинается с 32, поэтому любое значение >31 находится в правом хвосте.
Следовательно, если U и L — верхний и нижний квантили соответственно, то случайная величина X находится в области хвоста — где мы отвергли бы нулевую гипотезу, если бы:
X <= L || X > U
И переменная X находится внутри центральной области, если:
L < X <= U
Мораль здесь заключается в том, чтобывсегда быть очень осторожными с вашими сравнениями при работе с дискретным распределением, и, если сомневаетесь,основывайте свои сравнения на CDF вместо.
Как и следовало ожидать из раздела о политике, вы не удивитесь, узнав, что доступны другие варианты округления:
- integer_round_outwards
-
Это политика по умолчанию, как описано выше: нижние квантили округляются (вероятность< 0,5), а верхние квантили (вероятность >0,5) округляются.
Это даетне болеезапрашиваемой вероятности в хвостах, ипо меньшей мерезапрашиваемой вероятности в центральной области.
- integer_round_inwards
-
Это полная противоположность политики дефолта: нижние квантили округляются (вероятность< 0,5), а верхние квантили (вероятность >0,5) округляются вниз.
Это даетпо меньшей мерезапрашиваемую вероятность в хвостах, ине болеезапрашиваемой вероятности в центральной области.
- integer_round_down
Эта политика всегда будет округлять результат вниз независимо от того, является ли это верхним или нижним квантилем.
- integer_round_up
Эта политика всегда округляет результат, независимо от того, является ли он верхним или нижним квантилем.
- integer_round_nearest
Эта политика всегда округляет результат до ближайшего целого числа независимо от того, является ли это верхним или нижним квантилем.
- real
Эта политика даст реальный ценный результат для квантиля дискретного распределения: это, как правило, намного медленнее, чем поиск целого результата, но позволяет проводить более сложную политику округления.
Чтобы понять, как можно использовать политику округления дискретных распределений, мы снова используем биномиальное распределение 50 образцов с долей успеха 0,5 и вычислим все возможные квантили в 0,05 и 0,95.
Начните с включения необходимых заголовков (а некоторые используют утверждения для краткости):
#include <iostream>
using std::cout; using std::endl;
using std::left; using std::fixed; using std::right; using std::scientific;
#include <iomanip>
using std::setw;
using std::setprecision;
#include <boost/math/distributions/binomial.hpp>
Далее мы введем необходимые декларации в объем и определим типы распределения для всех доступных политик округления:
using boost::math::binomial_distribution;
using boost::math::policies::policy;
using boost::math::policies::discrete_quantile;
using boost::math::policies::integer_round_outwards;
using boost::math::policies::integer_round_down;
using boost::math::policies::integer_round_up;
using boost::math::policies::integer_round_nearest;
using boost::math::policies::integer_round_inwards;
using boost::math::policies::real;
using boost::math::binomial_distribution;
typedef binomial_distribution<
double,
policy<discrete_quantile<integer_round_outwards> > >
binom_round_outwards;
typedef binomial_distribution<
double,
policy<discrete_quantile<integer_round_inwards> > >
binom_round_inwards;
typedef binomial_distribution<
double,
policy<discrete_quantile<integer_round_down> > >
binom_round_down;
typedef binomial_distribution<
double,
policy<discrete_quantile<integer_round_up> > >
binom_round_up;
typedef binomial_distribution<
double,
policy<discrete_quantile<integer_round_nearest> > >
binom_round_nearest;
typedef binomial_distribution<
double,
policy<discrete_quantile<real> > >
binom_real_quantile;
Теперь давайте приступим к работе, называя эти квантили:
int main()
{
cout <<
"Testing rounding policies for a 50 sample binomial distribution,\n"
"with a success fraction of 0.5.\n\n"
"Lower quantiles are calculated at p = 0.05\n\n"
"Upper quantiles at p = 0.95.\n\n";
cout << setw(25) << right
<< "Policy"<< setw(18) << right
<< "Lower Quantile" << setw(18) << right
<< "Upper Quantile" << endl;
cout << setw(25) << right
<< "integer_round_outwards"
<< setw(18) << right
<< quantile(binom_round_outwards(50, 0.5), 0.05)
<< setw(18) << right
<< quantile(binom_round_outwards(50, 0.5), 0.95)
<< endl;
cout << setw(25) << right
<< "integer_round_inwards"
<< setw(18) << right
<< quantile(binom_round_inwards(50, 0.5), 0.05)
<< setw(18) << right
<< quantile(binom_round_inwards(50, 0.5), 0.95)
<< endl;
cout << setw(25) << right
<< "integer_round_down"
<< setw(18) << right
<< quantile(binom_round_down(50, 0.5), 0.05)
<< setw(18) << right
<< quantile(binom_round_down(50, 0.5), 0.95)
<< endl;
cout << setw(25) << right
<< "integer_round_up"
<< setw(18) << right
<< quantile(binom_round_up(50, 0.5), 0.05)
<< setw(18) << right
<< quantile(binom_round_up(50, 0.5), 0.95)
<< endl;
cout << setw(25) << right
<< "integer_round_nearest"
<< setw(18) << right
<< quantile(binom_round_nearest(50, 0.5), 0.05)
<< setw(18) << right
<< quantile(binom_round_nearest(50, 0.5), 0.95)
<< endl;
cout << setw(25) << right
<< "real"
<< setw(18) << right
<< quantile(binom_real_quantile(50, 0.5), 0.05)
<< setw(18) << right
<< quantile(binom_real_quantile(50, 0.5), 0.95)
<< endl;
}
который производит выход программы:
policy_eg_10.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\policy_eg_10.exe
Testing rounding policies for a 50 sample binomial distribution,
with a success fraction of 0.5.
Lower quantiles are calculated at p = 0.05
Upper quantiles at p = 0.95.
Policy Lower Quantile Upper Quantile
integer_round_outwards 18 31
integer_round_inwards 19 30
integer_round_down 18 30
integer_round_up 19 31
integer_round_nearest 19 30
real 18.701 30.299