Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Understanding Quantiles of Discrete Distributions

Boost , Math Toolkit 2.5.0 , Policy Tutorial

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Дискретные распределения представляют нам проблему при вычислении квантиля: мы начинаем с непрерывной переменной с реальным значением - вероятности - но результат (значение случайной переменной) должен быть действительно дискретным.

Рассмотрим, например, биномиальное распределение с размером выборки 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 вместо.

Other Rounding Policies are Available

Как и следовало ожидать из раздела о политике, вы не удивитесь, узнав, что доступны другие варианты округления:

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>

Далее мы введем необходимые декларации в объем и определим типы распределения для всех доступных политик округления:

// Avoid 
// using namespace std; // and 
// using namespace boost::math;
// to avoid potential ambiguity of names, like binomial.
// using namespace boost::math::policies; is small risk, but
// the necessary items are brought into scope thus:
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; // Not std::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;
   // Test integer_round_outwards:
   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;
   // Test integer_round_inwards:
   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;
   // Test integer_round_down:
   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;
   // Test integer_round_up:
   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;
   // Test integer_round_nearest:
   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;
   // Test real:
   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;
} // int main()

который производит выход программы:

  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

PrevUpHomeNext

Статья Understanding Quantiles of Discrete Distributions раздела Math Toolkit 2.5.0 Policy Tutorial может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Policy Tutorial ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 07:26:14/0.0069680213928223/0