1. 程式人生 > >概率論中伯努利分佈(bernoulli distribution)介紹及C++11中std::bernoulli_distribution的使用

概率論中伯努利分佈(bernoulli distribution)介紹及C++11中std::bernoulli_distribution的使用

Bernoulli分佈(Bernoulli distribution):是單個二值隨機變數的分佈。它由單個引數ø∈[0,1],ø給出了隨機變數等於1的概率。它具有如下的一些性質:

P(x=1)= ø

P(x=0)=1-ø

P(x=x)= øx(1-ø)1-x

Ex[x]= ø

Varx(x)= ø(1-ø)

伯努力分佈(Bernoulli distribution,又名兩點分佈或者0-1分佈)是一個離散型概率分佈,為紀念瑞士科學家雅各布·伯努利而命名。若伯努利試驗成功,則伯努利隨機變數取值為1。若伯努利試驗失敗,則伯努利隨機變數取值為0。記其成功概率為p(0≤p≤1),失敗概率為q=1-p。則:

其概率質量函式為:

其期望值為:

其方差為:


Multinoulli分佈(multionoulli distribution)或者範疇分佈(categorical distribution):是指在具有k個不同狀態的單個離

散型隨機變數上的分佈,其中k是一個有限值。Multinoulli分布由向量p∈[0,1]k-1引數化,其中每一個分量pi表示第i個狀

態的概率。最後的k個狀態的概率可以通過1-lTp給出。注意必須限制lTp≤1。Multinoulli分佈經常用來表示物件分類的分

布,所以很少假設狀態1具有數值1之類的。因此,我們通常不需要去計算Multinoulli分佈的隨機變數的期望和方差.

Bernoulli分佈和Multinoulli分佈足夠用來描述在它們領域內的任意分佈。它們能夠描述這些分佈,不是因為它們

特別強大,而是因為它們的領域很簡單;它們可以對那些能夠將所有的狀態進行列舉的離散型隨機變數進行建模。

當處理的是連續型隨機變數時,會有不可數無限多的狀態,所以任何通過少量引數描述的概率分佈都必須在分佈上加以

嚴格的控制。

“multinoulli”這個術語是最近被Gustavo Lacerdo發明,被Murphy(2012)推廣的。Multinoulli分佈是多項式分

布(multinomial distribution)的一個特例。多項式分佈是{0,…,n}k中的向量的分佈,用於表示當對Multinoulli分佈採

樣n次時k個類中的每一個被訪問的次數。多項式分佈(multinomial distribution)是二項式分佈的推廣。二項分佈的

典型例子是扔硬幣,硬幣正面朝上概率為p,重複扔n次硬幣,k次為正面的概率即為一個二項式分佈概率。把二

項分佈推廣至多個(大於2)互斥事件的發生次數,就得到了多項式分佈。比如扔骰子,不同於扔硬幣,骰子有6個

面對應6個不同的點數,這樣單次每個點數朝上的概率都是1/6.

In probability theory and statistics, a categorical distribution(分類分佈)(also called a generalized Bernoulli

distribution(廣義伯努利分佈), multinoull distribution or, less precisely, a discrete distribution) is a probabilit

distribution that describes the possible results of a random event that can take on one of K possible outcomes,

with the probability of each outcom separately specified. There is not necessarily an underlying ordering of thes

outcomes, but numerical labels are often attached for convenience in describing the distribution. On the other

hand, the categorical distribution is a special case of the multinomial distribution.

以下是對C++11中伯努利分佈std::bernoulli_distribution類介紹:

C++11在標頭檔案<random>中提供了伯努利概率分佈類std::Bernoulli_distribution。伯努利分佈(Bernoulli distribution)是判斷某件事情發生或者未發生的概率,產生隨機bool值。它是一個單次試驗只有0(失敗)和1(成功)兩個結果的離散分佈。

std::bernoulli_distribution:Bernoulli distribution, Random number distribution that produces bool values according to a Bernoulli distribution.
#include "bernoulli_distribution.hpp"
#include <iostream>
#include <random>
#include <string>
#include <iomanip>
#include <map>

/////////////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/random/bernoulli_distribution/
int test_bernoulli_distribution_1()
{
{
	const int nrolls = 10000;

	std::default_random_engine generator;
	std::bernoulli_distribution distribution(0.5);

	int count = 0;  // count number of trues

	for (int i = 0; i<nrolls; ++i) if (distribution(generator)) ++count;

	std::cout << "bernoulli_distribution (0.5) x 10000:" << std::endl;
	std::cout << "true:  " << count << std::endl;
	std::cout << "false: " << nrolls - count << std::endl;
}

{ // (1)、bernoulli_distribution::bernoulli_distribution: Constructs a bernoulli_distribution object
//   with a probability of p (or with the probability specified by object parm)
//   (2)、bernoulli_distribution::operator(): Generate random number
//   Returns a new random value with the probability associated to the object (version 1) or
//   with the probability specified by parm (version 2)
//   (3)、bernoulli_distribution::p: Probability of true
//   Returns the parameter p associated with the bernoulli_distribution.
//   This parameter represents the probabily that member function operator() returns true.
//   (4)、bernoulli_distribution::max:Maximum value, Returns the least upper bound of the range of
//   values potentially returned by member operator(), which for bernoulli_distribution is true.
//   (5)、bernoulli_distribution::min: Minimum value, Returns the greatest lower bound of the range of
//   values potentially returned by member operator(), which for bernoulli_distribution is false.
	std::cout << "Please, enter a yes/no question (I will answer it):" << std::endl;
	std::string text;
	getline(std::cin, text);

	std::seed_seq seed(text.begin(), text.end());  // seed using question
	std::default_random_engine generator(seed);
	std::bernoulli_distribution distribution(0.91);

	bool result = distribution(generator);
	std::cout << (result ? "yes" : "no") << std::endl;
	std::cout << "p: " << distribution.p() << std::endl;
	std::cout << "max: " << distribution.max() << std::endl;
	std::cout << "min: " << distribution.min() << std::endl;
}

{ // bernoulli_distribution::param: Distribution parameters
//   A bernoulli_distribution is defined by a single parameter: its probability (p) of true results.
//   An object of type param_type carries this information, but it is meant to be used only to construct
//   or specify the parameters for a bernoulli_distribution object, not to inspect the individual parameter.
	std::default_random_engine generator;
	std::bernoulli_distribution d1(0.7);
	std::bernoulli_distribution d2(d1.param());

	// print two independent values:
	std::cout << std::boolalpha;
	std::cout << d1(generator) << std::endl;
	std::cout << d2(generator) << std::endl;
}

{ // bernoulli_distribution::reset: Resets the distribution,
//   so that subsequent uses of the object do not depend on values already produced by it.
	std::default_random_engine generator;
	std::bernoulli_distribution distribution;

	// print two independent values:
	std::cout << std::boolalpha;
	std::cout << distribution(generator) << std::endl;
	distribution.reset();
	std::cout << distribution(generator) << std::endl;
}

	return 0;
}

/////////////////////////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/numeric/random/bernoulli_distribution
int test_bernoulli_distribution_2()
{

	std::random_device rd;
	std::mt19937 gen(rd());
	// give "true" 1/4 of the time
	// give "false" 3/4 of the time
	std::bernoulli_distribution d(0.25);

	std::map<bool, int> hist;
	for (int n = 0; n<10000; ++n) {
		++hist[d(gen)];
	}
	for (auto p : hist) {
		std::cout << std::boolalpha << std::setw(5) << p.first
			<< ' ' << std::string(p.second / 500, '*') << '\n';
	}

	return 0;
}

/////////////////////////////////////////////////////////////
int test_bernoulli_distribution_3()
{
	std::random_device rd; std::mt19937 gen(rd()); // 每次產生不固定的不同的值
	//std::default_random_engine gen; // 每次產生固定的不同的值
	std::bernoulli_distribution d(0.5);

	for (int i = 0; i < 10; ++i)
		std::cout << d(gen);
	std::cout << std::endl;

	return 0;
}

GitHubhttps://github.com/fengbingchun/Messy_Test