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

Binomial Quiz Example

Boost , Math Toolkit 2.5.0 , Binomial Distribution Examples

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

Тест с множественным выбором имеет четыре возможных ответа на каждый из 16 вопросов. Студент угадывает ответ на каждый вопрос, поэтому вероятность получить правильный ответ на любой заданный вопрос составляет один к четырем, четверть, 1/4, 25% или фракция 0,25. Предполагают, что условия биномиального эксперимента выполнены: n = 16 вопросов составляют испытания; каждый вопрос приводит к одному из двух возможных исходов (правильному или неправильному); вероятность быть правильным равна 0,25 и постоянна, если не предполагается знание предмета; на вопросы отвечают независимо, если ответ студента на вопрос никоим образом не влияет на его ответ на другой вопрос.

Во-первых, мы должны иметь возможность использовать конструктор биномиального распределения (и, конечно, некоторые входные / выходные данные).

#include <boost/math/distributions/binomial.hpp>
  using boost::math::binomial;
#include <iostream>
  using std::cout; using std::endl;
  using std::ios; using std::flush; using std::left; using std::right; using std::fixed;
#include <iomanip>
  using std::setw; using std::setprecision;
#include <exception>

Число правильных ответов, X, распределено как биномиальная случайная величина с параметрами биномиального распределения: вопросы n и вероятность дроби успеха p. Итак, мы строим биномиальное распределение:

int questions = 16; // All the questions in the quiz.
int answers = 4; // Possible answers to each question.
double success_fraction = 1. / answers; // If a random guess, p = 1/4 = 0.25.
binomial quiz(questions, success_fraction);

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

cout << "In a quiz with " << quiz.trials()
  << " questions and with a probability of guessing right of "
  << quiz.success_fraction() * 100 << " %"
  << " or 1 in " << static_cast<int>(1. / quiz.success_fraction()) << endl;

Покажите несколько вероятностей просто угадывания:

cout << "Probability of getting none right is " << pdf(quiz, 0) << endl; // 0.010023
cout << "Probability of getting exactly one right is " << pdf(quiz, 1) << endl;
cout << "Probability of getting exactly two right is " << pdf(quiz, 2) << endl;
int pass_score = 11;
cout << "Probability of getting exactly " << pass_score << " answers right by chance is "
  << pdf(quiz, pass_score) << endl;
cout << "Probability of getting all " << questions << " answers right by chance is "
  << pdf(quiz, questions) << endl;
Probability of getting none right is 0.0100226
Probability of getting exactly one right is 0.0534538
Probability of getting exactly two right is 0.133635
Probability of getting exactly 11 right is 0.000247132
Probability of getting exactly all 16 answers right by chance is 2.32831e-010

Они не дают никакого поощрения гадалкам!

Мы можем вычислить вероятность «получить абсолютно правильно» ( == ) таким образом:

cout << "\n" "Guessed Probability" << right << endl;
for (int successes = 0; successes <= questions; successes++)
{
  double probability = pdf(quiz, successes);
  cout << setw(2) << successes << "      " << probability << endl;
}
cout << endl;
Guessed Probability
 0      0.0100226
 1      0.0534538
 2      0.133635
 3      0.207876
 4      0.225199
 5      0.180159
 6      0.110097
 7      0.0524273
 8      0.0196602
 9      0.00582526
10      0.00135923
11      0.000247132
12      3.43239e-005
13      3.5204e-006
14      2.51457e-007
15      1.11759e-008
16      2.32831e-010

Затем мы можем добавить вероятности некоторого «точно правильного» типа:

cout << "Probability of getting none or one right is " << pdf(quiz, 0) + pdf(quiz, 1) << endl;
Probability of getting none or one right is 0.0634764

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

cout << "Probability of getting none or one right is " << cdf(quiz, 1) << endl;
Probability of getting none or one right is 0.0634764

Поскольку cdf является инклюзивным, мы можем получить вероятность до 10 правых.

cout << "Probability of getting <= 10 right (to fail) is " << cdf(quiz, 10) << endl;
Probability of getting <= 10 right (to fail) is 0.999715

Чтобы получить вероятность получить 11 или более прав (пройти), заманчиво использовать

1 - cdf(quiz, 10)

Вероятность возникновения >10

cout << "Probability of getting > 10 right (to pass) is " << 1 - cdf(quiz, 10) << endl;
Probability of getting > 10 right (to pass) is 0.000285239

Но этому следует противостоять в пользу использованиякомплементов.функция (см.Почему комплементы?.

cout << "Probability of getting > 10 right (to pass) is " << cdf(complement(quiz, 10)) << endl;
Probability of getting > 10 right (to pass) is 0.000285239

И мы можем проверить, что эти два,<= 10 и >10, складываются в единство.

BOOST_ASSERT((cdf(quiz, 10) + cdf(complement(quiz, 10))) == 1.);

Если мы хотим тест, а не тест, потому что CDF включен, мы должны вычесть один из баллов.

cout << "Probability of getting less than " << pass_score
  << " (< " << pass_score << ") answers right by guessing is "
  << cdf(quiz, pass_score -1) << endl;
Probability of getting less than 11 (< 11) answers right by guessing is 0.999715

Точно так же, чтобы получить >=, а не >тест, нам также нужно вычесть один из баллов (и снова проверить сумму - единство). Это потому, что если cdfвключительно, то его дополнение должно бытьисключительным, иначе был бы один возможный результат, подсчитанный дважды!

cout << "Probability of getting at least " << pass_score
  << "(>= " << pass_score << ") answers right by guessing is "
  << cdf(complement(quiz, pass_score-1))
  << ", only 1 in " << 1/cdf(complement(quiz, pass_score-1)) << endl;
BOOST_ASSERT((cdf(quiz, pass_score -1) + cdf(complement(quiz, pass_score-1))) == 1);
Probability of getting at least 11 (>= 11) answers right by guessing is 0.000285239, only 1 in 3505.83

Наконец, мы можем сформулировать некоторые вероятности:

cout << "\n" "At most (<=)""\n""Guessed OK   Probability" << right << endl;
for (int score = 0; score <= questions; score++)
{
  cout << setw(2) << score << "           " << setprecision(10)
    << cdf(quiz, score) << endl;
}
cout << endl;
At most (<=)
Guessed OK   Probability
 0           0.01002259576
 1           0.0634764398
 2           0.1971110499
 3           0.4049871101
 4           0.6301861752
 5           0.8103454274
 6           0.9204427481
 7           0.9728700437
 8           0.9925302796
 9           0.9983555346
10           0.9997147608
11           0.9999618928
12           0.9999962167
13           0.9999997371
14           0.9999999886
15           0.9999999998
16           1
cout << "\n" "At least (>)""\n""Guessed OK   Probability" << right << endl;
for (int score = 0; score <= questions; score++)
{
  cout << setw(2) << score << "           "  << setprecision(10)
    << cdf(complement(quiz, score)) << endl;
}
At least (>)
Guessed OK   Probability
 0           0.9899774042
 1           0.9365235602
 2           0.8028889501
 3           0.5950128899
 4           0.3698138248
 5           0.1896545726
 6           0.07955725188
 7           0.02712995629
 8           0.00746972044
 9           0.001644465374
10           0.0002852391917
11           3.810715862e-005
12           3.783265129e-006
13           2.628657967e-007
14           1.140870154e-008
15           2.328306437e-010
16           0

Теперь мы рассмотрим вероятностидиапазоновправильных догадок.

Во-первых, вычислите вероятность правильного получения диапазона догадок, добавляя точные вероятности каждой из них с низкого ... высокого.

int low = 3; // Getting at least 3 right.
int high = 5; // Getting as most 5 right.
double sum = 0.;
for (int i = low; i <= high; i++)
{
  sum += pdf(quiz, i);
}
cout.precision(4);
cout << "Probability of getting between "
  << low << " and " << high << " answers right by guessing is "
  << sum  << endl; // 0.61323
Probability of getting between 3 and 5 answers right by guessing is 0.6132

Или, как правило, лучше, мы можем вместо этого использовать разницу в Cdfs:

cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
  <<  cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 0.61323
Probability of getting between 3 and 5 answers right by guessing is 0.6132

Мы также можем попробовать несколько комбинаций высокого и низкого выбора:

low = 1; high = 6;
cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
  <<  cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 1 and 6 P= 0.91042
low = 1; high = 8;
cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
  <<  cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 1 <= x 8 P = 0.9825
low = 4; high = 4;
cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
  <<  cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 4 <= x 4 P = 0.22520
Probability of getting between 1 and 6 answers right by guessing is 0.9104
Probability of getting between 1 and 8 answers right by guessing is 0.9825
Probability of getting between 4 and 4 answers right by guessing is 0.2252
Using Binomial distribution moments

Используя моменты распределения, можно сказать больше о распространении результатов от угадывания.

cout << "By guessing, on average, one can expect to get " << mean(quiz) << " correct answers." << endl;
cout << "Standard deviation is " << standard_deviation(quiz) << endl;
cout << "So about 2/3 will lie within 1 standard deviation and get between "
  <<  ceil(mean(quiz) - standard_deviation(quiz))  << " and "
  << floor(mean(quiz) + standard_deviation(quiz)) << " correct." << endl;
cout << "Mode (the most frequent) is " << mode(quiz) << endl;
cout << "Skewness is " << skewness(quiz) << endl;
By guessing, on average, one can expect to get 4 correct answers.
Standard deviation is 1.732
So about 2/3 will lie within 1 standard deviation and get between 3 and 5 correct.
Mode (the most frequent) is 4
Skewness is 0.2887
Quantiles

Квантили (проценты или процентные точки) для нескольких уровней вероятности:

cout << "Quartiles " << quantile(quiz, 0.25) << " to "
  << quantile(complement(quiz, 0.25)) << endl; // Quartiles
cout << "1 standard deviation " << quantile(quiz, 0.33) << " to "
  << quantile(quiz, 0.67) << endl; // 1 sd
cout << "Deciles " << quantile(quiz, 0.1)  << " to "
  << quantile(complement(quiz, 0.1))<< endl; // Deciles
cout << "5 to 95% " << quantile(quiz, 0.05)  << " to "
  << quantile(complement(quiz, 0.05))<< endl; // 5 to 95%
cout << "2.5 to 97.5% " << quantile(quiz, 0.025) << " to "
  <<  quantile(complement(quiz, 0.025)) << endl; // 2.5 to 97.5%
cout << "2 to 98% " << quantile(quiz, 0.02)  << " to "
  << quantile(complement(quiz, 0.02)) << endl; //  2 to 98%
cout << "If guessing then percentiles 1 to 99% will get " << quantile(quiz, 0.01)
  << " to " << quantile(complement(quiz, 0.01)) << " right." << endl;

Обратите внимание, что эти выходные интегральные значения, поскольку политика по умолчанию являетсяinteger_round_outwards.

Quartiles 2 to 5
1 standard deviation 2 to 5
Deciles 1 to 6
5 to 95% 0 to 7
2.5 to 97.5% 0 to 8
2 to 98% 0 to 8

Ценности квантилей контролируютсяпониманием дискретных квантилейвыбранной политики квантиля. По умолчаниюinteger_round_outwards, поэтому нижний квантиль округляется вниз, а верхний квантиль округляется.

Но мы можем верить, что реальные значения говорят нам немного больше — см.дискретные функции.

Мы можем контролировать политику длявсехраспределений.

#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
at the head of the program would make this policy apply

, и только, единица перевода.

Или мы можем теперь создать политику, которая имеет дискретный квантиль (здесь избегая любых заявлений об использовании пространств имен).

using boost::math::policies::policy;
using boost::math::policies::discrete_quantile;
using boost::math::policies::real;
using boost::math::policies::integer_round_outwards; // Default.
typedef boost::math::policies::policy<discrete_quantile<real> > real_quantile_policy;

Добавить пользовательское биномиальное распределение, называемое

real_quantile_binomial

который использует

real_quantile_policy
using boost::math::binomial_distribution;
typedef binomial_distribution<double, real_quantile_policy> real_quantile_binomial;

Постройте объект этого пользовательского распределения:

real_quantile_binomial quiz_real(questions, success_fraction);

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

cout << "Quartiles " << quantile(quiz, 0.25) << " to "
  << quantile(complement(quiz_real, 0.25)) << endl; // Quartiles 2 to 4.6212
cout << "1 standard deviation " << quantile(quiz_real, 0.33) << " to "
  << quantile(quiz_real, 0.67) << endl; // 1 sd 2.6654 4.194
cout << "Deciles " << quantile(quiz_real, 0.1)  << " to "
  << quantile(complement(quiz_real, 0.1))<< endl; // Deciles 1.3487 5.7583
cout << "5 to 95% " << quantile(quiz_real, 0.05)  << " to "
  << quantile(complement(quiz_real, 0.05))<< endl; // 5 to 95% 0.83739 6.4559
cout << "2.5 to 97.5% " << quantile(quiz_real, 0.025) << " to "
  <<  quantile(complement(quiz_real, 0.025)) << endl; // 2.5 to 97.5% 0.42806 7.0688
cout << "2 to 98% " << quantile(quiz_real, 0.02)  << " to "
  << quantile(complement(quiz_real, 0.02)) << endl; //  2 to 98% 0.31311 7.7880
cout << "If guessing, then percentiles 1 to 99% will get " << quantile(quiz_real, 0.01)
  << " to " << quantile(complement(quiz_real, 0.01)) << " right." << endl;
Real Quantiles
Quartiles 2 to 4.621
1 standard deviation 2.665 to 4.194
Deciles 1.349 to 5.758
5 to 95% 0.8374 to 6.456
2.5 to 97.5% 0.4281 to 7.069
2 to 98% 0.3131 to 7.252
If guessing then percentiles 1 to 99% will get 0 to 7.788 right.

binomial_quiz_example.cppдля полного исходного кода и вывода.


PrevUpHomeNext

Статья Binomial Quiz Example раздела Math Toolkit 2.5.0 Binomial Distribution Examples может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Binomial Distribution Examples ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 20:17:36/0.02854585647583/1