![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Negative Binomial Sales Quota Example.Boost , Math Toolkit 2.5.0 , Negative Binomial Distribution Examples
|
![]() |
Caution |
---|---|
Важно, чтобы #включить распределения и т. д.послевышеописанных #определений |
И, конечно, нам нужна библиотека iostream.
#include <boost/math/distributions/negative_binomial.hpp> // for negative_binomial_distribution using boost::math::negative_binomial; // typedef provides default type is double. using ::boost::math::pdf; // Probability mass function. using ::boost::math::cdf; // Cumulative density function. using ::boost::math::quantile; #include <iostream> using std::cout; using std::endl; using std::noshowpoint; using std::fixed; using std::right; using std::left; #include <iomanip> using std::setprecision; using std::setw; #include <limits> using std::numeric_limits;
Всегда разумно использовать блоки, потому что политика по умолчанию заключается в том, чтобы сделать исключение, если что-то пойдет не так.
Простой блок улова (см. ниже) гарантирует, что вы получите полезное сообщение об ошибке вместо резкого прерывания программы.
try {
Продажа пяти конфет означает получение пяти успехов, поэтому успехи r = 5. Таким образом, общее количество испытаний (n, в данном случае посещаемых домов) составляет = успехи + неудачи или k + r = k + 5.
double sales_quota = 5; // Pat's sales quota - successes (r).
В каждом доме есть 0,4 вероятность (40%) продажи одного конфетного батончика и 0,6 вероятность (60%) продажи ничего.
double success_fraction = 0.4; // success_fraction (p) - so failure_fraction is 0.6.
Отрицательное биномиальное (r, p) распределение описывает вероятность k неудач и r успехов в k+r испытаниях Бернулли (p) с успехом в последнем испытании.Испытание Бернулли— это испытание, в котором возможны только два исхода, успех неудачи и р — вероятность успеха.
Поэтому мы начинаем с построения отрицательного биномиального распределения с параметрами sales_quota (необходимые успехи) и вероятностью успеха.
negative_binomial nb(sales_quota, success_fraction); // type double by default.
Для подтверждения отображаются параметры success_fraction & successes дистрибутива.
cout << "Pat has a sales per house success rate of " << success_fraction << ".\nTherefore he would, on average, sell " << nb.success_fraction() * 100 << " bars after trying 100 houses." << endl; int all_houses = 30; // The number of houses on the estate. cout << "With a success rate of " << nb.success_fraction() << ", he might expect, on average,\n" "to need to visit about " << success_fraction * all_houses << " houses in order to sell all " << nb.successes() << " bars. " << endl;
Pat has a sales per house success rate of 0.4. Therefore he would, on average, sell 40 bars after trying 100 houses. With a success rate of 0.4, he might expect, on average, to need to visit about 12 houses in order to sell all 5 bars.
Случайная переменная процента — это количество домов, которые необходимо посетить, чтобы продать пять конфетных батончиков, поэтому мы заменяем k = n — 5 на отрицательный биномиальный (5, 0,4) и получаемфункцию плотности вероятностираспределения посещенных домов. Очевидно, что лучший возможный случай - это то, что Пэт делает продажи на всех первых пяти домах.
Вычисляем это с помощью функции pdf:
cout << "Probability that Pat finishes on the " << sales_quota << "th house is " << pdf(nb, 5 - sales_quota) << endl; // == pdf(nb, 0)
Конечно, он не мог закончить на менее чем 5 домах, потому что он должен продать 5 шоколадных батончиков. Так что 5-й дом - это первый, на котором он может закончить.
Чтобы закончить на или до 8-го дома, Пат должен закончить в 5-м, 6-м, 7-м или 8-м доме. Вероятность того, что он закончит наровно( == ) на любом доме, является функцией плотности вероятности (pdf).
cout << "Probability that Pat finishes on the 6th house is " << pdf(nb, 6 - sales_quota) << endl; cout << "Probability that Pat finishes on the 7th house is " << pdf(nb, 7 - sales_quota) << endl; cout << "Probability that Pat finishes on the 8th house is " << pdf(nb, 8 - sales_quota) << endl;
Probability that Pat finishes on the 6th house is 0.03072 Probability that Pat finishes on the 7th house is 0.055296 Probability that Pat finishes on the 8th house is 0.077414
Сумма вероятностей для этих домов — кумулятивная функция распределения (cdf). Вычислить ее можно, добавив индивидуальные вероятности.
cout << "Probability that Pat finishes on or before the 8th house is sum " "\n" << "pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = " // Sum each of the mass/density probabilities for houses sales_quota = 5, 6, 7, & 8. << pdf(nb, 5 - sales_quota) // 0 failures. + pdf(nb, 6 - sales_quota) // 1 failure. + pdf(nb, 7 - sales_quota) // 2 failures. + pdf(nb, 8 - sales_quota) // 3 failures. << endl;
pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = 0.17367
Или, как правило, лучше, используя отрицательную биномиальнуюкумулятивнуюфункцию распределения.
cout << "\nProbability of selling his quota of " << sales_quota << " bars\non or before the " << 8 << "th house is " << cdf(nb, 8 - sales_quota) << endl;
Probability of selling his quota of 5 bars on or before the 8th house is 0.17367
cout << "\nProbability that Pat finishes exactly on the 10th house is " << pdf(nb, 10 - sales_quota) << endl; cout << "\nProbability of selling his quota of " << sales_quota << " bars\non or before the " << 10 << "th house is " << cdf(nb, 10 - sales_quota) << endl;
Probability that Pat finishes exactly on the 10th house is 0.10033 Probability of selling his quota of 5 bars on or before the 10th house is 0.3669
cout << "Probability that Pat finishes exactly on the 11th house is " << pdf(nb, 11 - sales_quota) << endl; cout << "\nProbability of selling his quota of " << sales_quota << " bars\non or before the " << 11 << "th house is " << cdf(nb, 11 - sales_quota) << endl;
Probability that Pat finishes on the 11th house is 0.10033 Probability of selling his quota of 5 candy bars on or before the 11th house is 0.46723
cout << "Probability that Pat finishes exactly on the 12th house is " << pdf(nb, 12 - sales_quota) << endl; cout << "\nProbability of selling his quota of " << sales_quota << " bars\non or before the " << 12 << "th house is " << cdf(nb, 12 - sales_quota) << endl;
Probability that Pat finishes on the 12th house is 0.094596 Probability of selling his quota of 5 candy bars on or before the 12th house is 0.56182
Наконец, рассмотрим риск того, что Пэт не продаст свою квоту в 5 баров даже после посещения всех домов. Вычислите вероятность того, что онбудетпродавать на или до последнего дома: Вычислите вероятность того, что он продаст всю свою квоту на самый последний дом.
cout << "Probability that Pat finishes on the " << all_houses << " house is " << pdf(nb, all_houses - sales_quota) << endl;
Вероятность продажи его квоты в 5 баров на 30-й дом есть
Probability that Pat finishes on the 30 house is 0.00069145
Когда ему действительно не повезло!
Какова вероятность того, что Пэт исчерпает все 30 домов по соседству, авсе ещене продает необходимые 5 конфет?
cout << "\nProbability of selling his quota of " << sales_quota << " bars\non or before the " << all_houses << "th house is " << cdf(nb, all_houses - sales_quota) << endl;
Probability of selling his quota of 5 bars on or before the 30th house is 0.99849
<Sothe
riskof
failingeven
aftervisiting
allthe
housesis
1-thisprobability,
><1
-cdf(nb,all_houses
-sales_quota
><
Butusing
thisexpression
maycause
seriousinaccuracy,soitwould
bemuch
betterto
usethe
complementof
thecdf:Sotherisk
offailing
evenat,orafter,the31th(non-existent)
housesis
1-thisprobability,
><1
-cdf(nb,all_houses
-sales_quota)
>Но использование этого выражения может вызвать серьезную неточность. Так что было бы гораздо лучше использовать __комплемент cdf (см.Почему комплементы?.
cout << "\nProbability of failing to sell his quota of " << sales_quota << " bars\neven after visiting all " << all_houses << " houses is " << cdf(complement(nb, all_houses - sales_quota)) << endl;
Probability of failing to sell his quota of 5 bars even after visiting all 30 houses is 0.0015101
Мы также можем использовать квантиль (процентиль), обратный cdf, чтобы предсказать, на каком доме будет заканчиваться Пэт. Для 8-го дома:
double p = cdf(nb, (8 - sales_quota)); cout << "Probability of meeting sales quota on or before 8th house is "<< p << endl;
Probability of meeting sales quota on or before 8th house is 0.174
cout << "If the confidence of meeting sales quota is " << p << ", then the finishing house is " << quantile(nb, p) + sales_quota << endl; cout<< " quantile(nb, p) = " << quantile(nb, p) << endl;
If the confidence of meeting sales quota is 0.17367, then the finishing house is 8
Требование абсолютной уверенности в том, что все 5 будут проданы, подразумевает бесконечное количество испытаний. (Конечно, в поместье всего 30 домов, поэтому он никогда не может быть уверенв продаже своей квоты).
cout << "If the confidence of meeting sales quota is " << 1. << ", then the finishing house is " << quantile(nb, 1) + sales_quota << endl; // 1.#INF == infinity.
If the confidence of meeting sales quota is 1, then the finishing house is 1.#INF
И так же для некоторых других вероятностей:
cout << "If the confidence of meeting sales quota is " << 0. << ", then the finishing house is " << quantile(nb, 0.) + sales_quota << endl; cout << "If the confidence of meeting sales quota is " << 0.5 << ", then the finishing house is " << quantile(nb, 0.5) + sales_quota << endl; cout << "If the confidence of meeting sales quota is " << 1 - 0.00151 // 30 th << ", then the finishing house is " << quantile(nb, 1 - 0.00151) + sales_quota << endl;
If the confidence of meeting sales quota is 0, then the finishing house is 5 If the confidence of meeting sales quota is 0.5, then the finishing house is 11.337 If the confidence of meeting sales quota is 0.99849, then the finishing house is 30
Обратите внимание, что, поскольку мы выбрали дискретную квантильную политику реального, результатом может быть «нереальный» дробный дом.
Если верно обратное, мы не хотим принимать какую-либо уверенность, то это равносильно предположению, что все первые испытания продаж будут успешными.
cout << "If confidence of meeting quota is zero\n(we assume all houses are successful sales)" ", then finishing house is " << sales_quota << endl;
If confidence of meeting quota is zero (we assume all houses are successful sales), then finishing house is 5 If confidence of meeting quota is 0, then finishing house is 5
Мы можем перечислить квантили для нескольких вероятностей:
double ps[] = {0., 0.001, 0.01, 0.05, 0.1, 0.5, 0.9, 0.95, 0.99, 0.999, 1.}; // Confidence as fraction = 1-alpha, as percent = 100 * (1-alpha[i]) % cout.precision(3); for (int i = 0; i < sizeof(ps)/sizeof(ps[0]); i++) { cout << "If confidence of meeting quota is " << ps[i] << ", then finishing house is " << quantile(nb, ps[i]) + sales_quota << endl; }
If confidence of meeting quota is 0, then finishing house is 5 If confidence of meeting quota is 0.001, then finishing house is 5 If confidence of meeting quota is 0.01, then finishing house is 5 If confidence of meeting quota is 0.05, then finishing house is 6.2 If confidence of meeting quota is 0.1, then finishing house is 7.06 If confidence of meeting quota is 0.5, then finishing house is 11.3 If confidence of meeting quota is 0.9, then finishing house is 17.8 If confidence of meeting quota is 0.95, then finishing house is 20.1 If confidence of meeting quota is 0.99, then finishing house is 24.8 If confidence of meeting quota is 0.999, then finishing house is 31.1 If confidence of meeting quota is 1, then finishing house is 1.#INF
Мы могли бы применить функцию потолка, чтобы получить целочисленное значение «худшего случая» для дома.
ceil(quantile(nb, ps[i]))
Или, если бы мы использовали дискретную политику квантиля по умолчанию, integer_outside, опустив
#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
Мы бы добились такого же эффекта.
Реальный результат дает некоторое представление о том, какой дом наиболее вероятен. Например, сравните реальное и целое_вне для 95% уверенности.
If confidence of meeting quota is 0.95, then finishing house is 20.1 If confidence of meeting quota is 0.95, then finishing house is 21
Реальное значение 20.1 намного ближе к 20, чем 21, поэтому integer_outside пессимистично. Мы могли бы также использовать политику integer_round_nearest, чтобы предположить, что 20 более вероятны.
Наконец, мы можем подсчитать вероятность того, что последняя продажа будет именно на каждом доме.
cout << "\nHouse for " << sales_quota << "th (last) sale. Probability (%)" << endl; cout.precision(5); for (int i = (int)sales_quota; i < all_houses+1; i++) { cout << left << setw(3) << i << " " << setw(8) << cdf(nb, i - sales_quota) << endl; } cout << endl;
House for 5 th (last) sale. Probability (%) 5 0.01024 6 0.04096 7 0.096256 8 0.17367 9 0.26657 10 0.3669 11 0.46723 12 0.56182 13 0.64696 14 0.72074 15 0.78272 16 0.83343 17 0.874 18 0.90583 19 0.93039 20 0.94905 21 0.96304 22 0.97342 23 0.98103 24 0.98655 25 0.99053 26 0.99337 27 0.99539 28 0.99681 29 0.9978 30 0.99849
Как отмечалось выше, использование блок-уловки всегда хорошая идея, даже если вы не ожидаете ее использования.
} catch(const std::exception& e) { // Since we have set an overflow policy of ignore_error, // an overflow exception should never be thrown. std::cout << "\nMessage from thrown exception was:\n " << e.what() << std::endl;
Например, без игнорирования политики ошибки домена, если мы просим
pdf(nb, -1)
Например, мы получим:
Message from thrown exception was: Error in function boost::math::pdf(const negative_binomial_distribution<double>&, double): Number of failures argument is -1, but must be >= 0 !
Статья Negative Binomial Sales Quota Example. раздела Math Toolkit 2.5.0 Negative Binomial Distribution Examples может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Negative Binomial Distribution Examples ::
реклама |