# The numpy.random Package

## The numpy.random.rand function

It returns random numbers between 0 (inclusive) and 1 (excluded) from a uniform distribution, that is, that all numbers have the same chance of being generated. Some examples of the rand() function.


```python
import numpy as np
```

Without arguments returns a single random number.


```python
np.random.rand()
```




    0.3865977004060728



With one argument, returns one row of the specified amount of random numbers


```python
np.random.rand(4)
```




    array([0.3538205 , 0.83122368, 0.82438008, 0.82653591])



Two or more arguments specify the dimensions of a random number matrix of n dimensions.  
The following example creates a 3rows x 2columns bi-dimensional matrix of random numbers.


```python
np.random.rand(3,2)
```




    array([[0.19419741, 0.83770466],
           [0.23207319, 0.91892121],
           [0.48023263, 0.95674632]])



This is for a 3 dimensinal matrix


```python
np.random.rand(2,3,4)
```




    array([[[0.31275436, 0.2966332 , 0.03552384, 0.05661765],
            [0.03365126, 0.93465359, 0.22284531, 0.44080924],
            [0.99612159, 0.01390498, 0.12771833, 0.80728456]],
    
           [[0.59284224, 0.52451676, 0.15293951, 0.64379681],
            [0.0130766 , 0.09336192, 0.07912765, 0.12024213],
            [0.00620319, 0.26831825, 0.59609507, 0.52829718]]])



More dimensions can be added:


```python
np.random.rand(2,3,4,5)
```




    array([[[[0.25400198, 0.71564977, 0.84791478, 0.72418088, 0.37960561],
             [0.06136708, 0.93565164, 0.19076122, 0.93820752, 0.05045084],
             [0.78041494, 0.23319917, 0.14905534, 0.76390876, 0.94512773],
             [0.34758882, 0.64021847, 0.49606102, 0.76652501, 0.60493063]],
    
            [[0.29840472, 0.15596761, 0.00945163, 0.56341337, 0.32107821],
             [0.57810549, 0.37450431, 0.16463507, 0.84571593, 0.19674281],
             [0.15557396, 0.18328489, 0.09789508, 0.30280672, 0.68028505],
             [0.63890307, 0.94600077, 0.07323507, 0.99446171, 0.7351696 ]],
    
            [[0.02468972, 0.8336871 , 0.85852907, 0.53800354, 0.31352037],
             [0.2681188 , 0.52370945, 0.70708558, 0.31196688, 0.96426333],
             [0.97701089, 0.00863002, 0.80063927, 0.40472819, 0.64684389],
             [0.7563089 , 0.36278422, 0.99288845, 0.56923364, 0.94445027]]],
    
    
           [[[0.55619061, 0.24476025, 0.50736685, 0.8748219 , 0.3206011 ],
             [0.22740634, 0.48640009, 0.86848969, 0.3018048 , 0.33290738],
             [0.35095548, 0.12444695, 0.89119414, 0.0055413 , 0.4014696 ],
             [0.09001962, 0.60208518, 0.83172887, 0.70785125, 0.49869301]],
    
            [[0.34209451, 0.85067727, 0.7295171 , 0.55716894, 0.18908333],
             [0.78637236, 0.09585448, 0.11319947, 0.52212523, 0.46112526],
             [0.35067546, 0.49620289, 0.58795027, 0.92687042, 0.94724196],
             [0.73620748, 0.82733139, 0.09107609, 0.23094873, 0.15143179]],
    
            [[0.54682514, 0.25025108, 0.04996302, 0.69876476, 0.42415793],
             [0.79874469, 0.75125809, 0.08934286, 0.80897496, 0.21766874],
             [0.09376575, 0.08575073, 0.83181027, 0.7920451 , 0.83420195],
             [0.98087357, 0.67500649, 0.80787735, 0.3177536 , 0.26993374]]]])



## Random Distributions

### Uniform distribution
Is a type of probability distribution in which all outcomes are equally likely; each variable has the same probability that it will be the outcome. A deck of cards has within it uniform distributions because the likelihood of drawing a heart, a club, a diamond or a spade is equally likely. A coin also has a uniform distribution because the probability of getting either heads or tails in a coin toss is the same.  
In an uniform distribution there is no skewness. As a result, the mean and median coincide. A uniform distribution with only two possible outcomes is a special case of the binomial distribution, which will be explained later.   

The probability density function of the continuous uniform distribution is: 
$$f(x)={\begin{cases}{\frac {1}{b-a}}&\mathrm {for} \ a\leq x\leq b,\\[8pt]0&\mathrm {for} \ x<a\ \mathrm {or} \ x>b\end{cases}}$$

#### Uniform Distribution for Discrete Random Variables 
Any situation in which every outcome in a sample space is equally likely will use a uniform distribution. One example of this in a discrete case is when we roll a single standard die. There are a total of six sides of the die, and each side has the same probability of being rolled face up. The probability histogram for this distribution is rectangular shaped, with six bars that each have height of 1/6.

#### Uniform Distribution for Continuous Random Variables 
For an example of a uniform distribution in a continuous setting, we will consider an idealized random number generator. This will truly generate a random number from a specified range of values. So if we specify that the generator is to produce a random number between 1 and 4, then 3.25, 3, e, 2.222222, 3.4545456 and pi are all possible numbers that are equally likely to be produced.

Since the total area enclosed by a density curve must be 1, which corresponds to 100%, it is straightforward to determine the density curve for our random number generator. If the number is from the range a to b, then this corresponds to an interval of length b - a. In order to have an area of one, the height would have to be 1/(b - a) .

For an example of this, for a random number generated from 1 to 4, the height of the density curve would be 1/3.

The np.random.uniform function is very similar to the function numpy.random.rand, but it allows to specify different sampling intervals, not only between 0 and 1. Without arguments it behaves like numpy.random.rand


```python
np.random.uniform()
```




    0.5154793212062049



With one argument, it generates a random number between 0 and the passed argument


```python
np.random.uniform(5)
```




    1.974965561899129



With two arguments, it generates a random number between the first and second argument


```python
np.random.uniform(0.0, 100.0)
```




    56.95318361698911



With three arguments, it generates an amount of random numbers specified by the third argument; between the first and second argument


```python
np.random.uniform(-1,0,10)
```




    array([-0.90778777, -0.18229758, -0.18322659, -0.46404898, -0.51798764,
           -0.36411949, -0.92226615, -0.82016842, -0.90423882, -0.23266782])



A histogram plot of the uniform distribution:


```python
import matplotlib.pyplot as plt
%matplotlib inline
x = np.random.uniform(0,1000,1000)
plt.hist(x)
```

Since every outcome in a uniform distribution occurs with the same relative frequency, the resulting shape of the distribution is that of a rectangle.  
It is important to remember that the height of a curve does not directly indicate the probability of an outcome. Rather, as with any density curve, probabilities are determined by the areas under the curve.

Since a uniform distribution is shaped like a rectangle, the probabilities are very easy to determine. Rather than using calculus to find the area under a curve, we can simply use some basic geometry. All that we need to remember is that the area of a rectangle is its base multiplied by its height.

### Normal Distribution
The normal distribution, also known as the Gaussian distribution, is a probability distribution that is symmetric about the mean, showing that data near the mean are more frequent in occurrence than data far from the mean.

The normal distribution model is motivated by the Central Limit Theorem. This theory states that averages calculated from independent, identically distributed random variables have approximately normal distributions, regardless of the type of distribution that the variables are sampled from (provided it has finite variance).

The probability density of the normal distribution is 
$$f(x\mid \mu ,\sigma ^{2})={\frac {1}{\sqrt {2\pi \sigma ^{2}}}}e^{-{\frac {(x-\mu )^{2}}{2\sigma ^{2}}}}$$

where 
* μ is the mean or expectation of the distribution (and also its median and mode),
* σ is the standard deviation, and
* $σ^2$ is the variance.  

The normal distribution is a continuous probability distribution. This has several implications for probability.
* The total area under the normal curve is equal to 1.
* The probability that a normal random variable X equals any particular value is 0.
* The probability that X is greater than a equals the area under the normal curve bounded by a and plus infinity (as indicated by the non-shaded area in the figure below).
* The probability that X is less than a equals the area under the normal curve bounded by a and minus infinity (as indicated by the shaded area in the figure below).

* Additionally, every normal curve (regardless of its mean or standard deviation) conforms to the following "rule".
* About 68% of the area under the curve falls within 1 standard deviation of the mean.
* About 95% of the area under the curve falls within 2 standard deviations of the mean.
* About 99.7% of the area under the curve falls within 3 standard deviations of the mean.
Collectively, these points are known as the empirical rule or the 68-95-99.7 rule. Clearly, given a normal distribution, most outcomes will be within 3 standard deviations of the mean.

The np.random.normal function draws samples from a normal distribution. It has three arguments. The first one is the center of the distribution, oftenly called 'mu' and is the mean, median and mode of it. The second parameter is the standard deviation and specifies the width of the distribution. It is three times the value of the std dev to the right and three times its value to the left too. The last argument is optional and specifies how many samples to draw.  

With no arguments draws a sample from the space space between 0 and three units distance that could be to the right or to the left. So it's drawing samples using 0 as the mean and 1 as standard deviation $(\mu = 0, \sigma = 1)$. Such normal distribution is also known as the Standard Normal distribution:


```python
np.random.normal()
```




    0.6513401440215899



With one argument draws a sample using the argument as the mean and 1 as standard deviation:


```python
np.random.normal(5)
```




    7.932867930955178



With two arguments draws a sample using the first argument as the mean and the second as the standard deviation:


```python
np.random.normal(7,2)
```




    8.98517322042102



With three arguments, the first two arguments behave like before and the third argument specifies the amount of samples to draw:


```python
np.random.normal(7,1,10)
```




    array([6.54938041, 6.46515938, 4.53737357, 6.58259218, 7.18589575,
           5.4490317 , 6.05170156, 6.18654825, 6.27885212, 7.42507323])



Below are some histogram plots of the normal distribution changing the function arguments.  
Base example:


```python
x = np.random.normal(0,0.1,10000)
plt.hist(x)
```

Changing the first argument ('center' or 'loc'):


```python
x = np.random.normal(8,0.1,10000)
plt.hist(x)
```

Changing the second argument ('standard devtiation' or 'spread'):


```python
x = np.random.normal(8,8,10000)
plt.hist(x)
```

Changing the third argument, the amount of samples:


```python
x = np.random.normal(8,8,100)
plt.hist(x)
```

## Skewness and Kurtosis
Real life data rarely, if ever, follow a perfect normal distribution. The skewness and kurtosis coefficients measure how different a given distribution is from a normal distribution. The skewness measures the symmetry of a distribution. The normal distribution is symmetric, and has a skewness of zero. If the distribution of a data set has a skewness less than zero, or negative skewness, then the left tail of the distribution is longer than the right tail; positive skewness implies that the right tail of the distribution is longer than the left.

The kurtosis statistic measures the thickness of the tail ends of a distribution in relation to the tails of the normal distribution. Distributions with large kurtosis exhibit tail data exceeding the tails of the normal distribution (e.g., five or more standard deviations from the mean). Distributions with low kurtosis exhibit tail data that is generally less extreme than the tails of the normal distribution. The normal distribution has a kurtosis of three, which indicates the distribution has neither fat nor thin tails. Therefore, if an observed distribution has a kurtosis greater than three, the distribution is said to have heavy tails when compared to the normal distribution. If the distribution has a kurtosis of less than three, it is said to have thin tails when compared to the normal distribution.

## Degrees of Freedom
For the next two probability distributions we need to explain first what are the degrees of freedom.

Let's start with a simple example.  Let's say we have seven hats and we want to wear one different hat every day of the week.
On the first day, we can wear any of the 7 hats. On the second day, we can choose from the 6 remaining hats, on day 3 we can choose from 5 hats, and so on.  

When day 6 rolls around, we still have a choice between 2 hats that we haven’t worn yet that week. But after we choose our hat for day 6, we have no choice for the hat that we wear on Day 7. We must wear the one remaining hat. We had 7-1 = 6 days of “hat” freedom—in which the hat we wore could vary!  

That’s kind of the idea behind degrees of freedom in statistics. Degrees of freedom are often broadly defined as the number of "observations" (pieces of information) in the data that are free to vary when estimating statistical parameters.  

Let's suppose we want to test the population mean with a sample of 10 values, using a 1-sample t test. We now have a constraint—the estimation of the mean. What is that constraint? By definition of the mean, the following relationship must hold: The sum of all values in the data must equal the amount of values multiplied by the mean.  

So if a data set has 10 values, the sum of the 10 values must equal the mean times 10. If the mean of the 10 values is 3.5, this constraint requires that the sum of the 10 values must equal 10 x 3.5 = 35.
With that constraint, the first value in the data set is free to vary. Whatever value it is, it’s still possible for the sum of all 10 numbers to have a value of 35. The second value is also free to vary, because whatever value you choose, it still allows for the possibility that the sum of all the values is 35.
In fact, the first 9 values could be anything, including these two examples:  
34, -8.3, -37, -92, -1, 0, 1, -22, 99   
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9  

But to have all 10 values sum to 35, and have a mean of 3.5, the 10th value cannot vary. It must be a specific number:  
34, -8.3, -37, -92, -1, 0, 1, -22, 99  -----> 10TH value must be 61.3  
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 ----> 10TH value must be 30.5  

Therefore, we have 10 - 1 = 9 degrees of freedom. It doesn’t matter what sample size we use, or what mean value we use—the last value in the sample is not free to vary. You end up with $n - 1$ degrees of freedom, where $n$ is the sample size.  

Another way to say this is that the number of degrees of freedom equals the number of "observations" minus the number of required relations among the observations (e.g., the number of parameter estimates). For a 1-sample t-test, one degree of freedom is spent estimating the mean, and the remaining $n - 1$ degrees of freedom estimate variability.

## Student's $t$ Distribution
The derivation of the t-distribution was first published in 1908 by William Gosset while working for the Guinness Brewery in Dublin. Due to proprietary issues, he had to publish under a pseudonym, and so he used the name Student. Gosset was interested in the problems of small samples – for example, the chemical properties of barley where sample sizes might be as few as 3. 

The probability density function for the $t$ distribution is

The $t$ test is based on an assumption that the data come from a normal distribution. The $t$ test provides a way to test whether the sample mean (that is the mean calculated from the data) is a good estimate of the true mean.

The random.standard_t function takes at least 1 argument, the degrees of freedom $df$. In return, draws one number from the Student's $t$ distribution.


```python
np.random.standard_t(1)
```




    -1.4896380758404848



With two arguments, the function draws an amount of samples specified by the second argument where the degrees of freedom ($df$) are provided by the first argument.


```python
np.random.standard_t(1,4)
```




    array([-2.57548993, -0.06677714,  0.30567152,  0.31311476])



Below is histogram plot with 100000 samples and $df$ and is 10


```python
x = np.random.standard_t(10,100000)
plt.hist(x)
```

## Chi Square Distribution
The chi-squared distribution is used in the common chi-squared tests for goodness of fit of an observed distribution to a theoretical one, the independence of two criteria of classification of qualitative data, and in confidence interval estimation for a population standard deviation of a normal distribution from a sample standard deviation.

When an amount of independent random variables that is equal to the degrees of freedom, each variable from standard normal distributions (mean 0, variance 1), are squared and summed, the resulting distribution is chi-square. This distribution is often used in hypothesis testing.

The chi-square distribution is defined by the following probability density function:  
$$Y = Y_0({\chi}^2)^{( \frac{v}{2} - 1 )} e^{-\frac{\chi^2}{2}}$$

where $Y_0$ is a constant that depends on the number of degrees of freedom, $\chi^2$ is the chi-square statistic, $v$ = n - 1 is the number of degrees of freedom. $Y_0$ is defined, so that the area under the chi-square curve is equal to one.

The chi-square distribution has the following properties: 
* The mean of the distribution is equal to the number of degrees of freedom: μ = $v$.
* The variance is equal to two times the number of degrees of freedom: σ2 = $2v$
* When the degrees of freedom are greater than or equal to 2, the maximum value for $Y$ occurs when $\chi^2 = v - 2$.
* As the degrees of freedom increase, the chi-square curve approaches a normal distribution.

The random.chisquare function takes at least 1 argument, the degrees of freedom $df$. In return, draws one number from the Chi Squared distribution.


```python
np.random.chisquare(2)
```




    1.4139564851873445



With two arguments, the function draws an amount of samples specified by the second argument where the degrees of freedom ($df$) are provided by the first argument.


```python
np.random.chisquare(6,4)
```




    array([5.55272072, 5.30505102, 1.64756882, 4.63372768])



Below is histogram plot with 1000 samples and $df$ and is 6


```python
x = np.random.chisquare(6,1000)
plt.hist(x)
```

## Binomial Distribution
In many cases, it is appropriate to summarize a group of independent observations by the number of observations in the group that represent one of two outcomes. For example, the proportion of individuals in a random sample who support one of two political candidates fits this description. In this case, the statistic  is the count X of voters who support the candidate divided by the total number of individuals in the group $n$. This provides an estimate of the parameter $p$, the proportion of individuals who support the candidate in the entire population. 
The binomial distribution describes the behavior of a count variable X if the following conditions apply: 
* The number of observations $n$ is fixed. 
* Each observation is independent. 
* Each observation represents one of two outcomes ("success" or "failure"). 
* The probability of "success" $p$ is the same for each outcome. 

If these conditions are met, then X has a binomial distribution with parameters $n$ and $p$, abbreviated $B(n,p)$. 

The probability density for the binomial distribution is
$$P(N) = {{n}\choose{N}} \cdot p^N(1-kp)^{n-N}$$
where $n$ is the number of trials, $p$ is the probability of success, and $N$ is the number of successes.  
The binomial distribution is frequently used to model the number of successes in a sample of size $n$ drawn with replacement from a population of size $N$. If the sampling is carried out without replacement, the draws are not independent and so the resulting distribution is a hypergeometric distribution, not a binomial one. 

The random.binomial function takes at least 2 arguments, the first argument is the number $n$ of trials and the second is the probabability $p$ of success. In return, draws one number from the binomial distribution.


```python
np.random.binomial(10, 1/6)
```




    4



With three arguments, the function draws an amount of samples specified by the third argument. The first two arguments are the still the same as explained in the previous cell. For example let's see the result of of getting a 1 on after rolling a die 10 times, tested 1000 times.


```python
np.random.binomial(10, 1/6, 1000)
```




    array([0, 0, 2, 1, 2, 3, 1, 2, 3, 2, 3, 2, 2, 3, 2, 2, 1, 2, 0, 1, 2, 2,
           3, 1, 1, 1, 0, 1, 2, 4, 2, 4, 1, 2, 0, 2, 0, 1, 2, 2, 3, 0, 1, 3,
           2, 2, 2, 1, 1, 3, 1, 1, 0, 2, 2, 2, 0, 3, 1, 1, 2, 3, 1, 1, 2, 2,
           0, 1, 0, 2, 4, 0, 2, 3, 1, 2, 4, 3, 2, 3, 1, 1, 1, 4, 0, 2, 2, 4,
           0, 4, 2, 0, 1, 2, 2, 1, 2, 1, 0, 0, 3, 1, 1, 4, 1, 2, 3, 3, 2, 4,
           4, 1, 1, 2, 1, 3, 0, 3, 0, 2, 1, 1, 2, 0, 1, 1, 2, 2, 3, 3, 3, 1,
           1, 1, 4, 3, 3, 3, 0, 4, 0, 1, 3, 1, 0, 1, 1, 3, 2, 1, 1, 3, 5, 2,
           1, 1, 1, 0, 2, 1, 1, 2, 4, 1, 1, 0, 2, 3, 2, 2, 0, 2, 0, 3, 2, 1,
           1, 2, 1, 2, 0, 3, 0, 0, 2, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 0, 2, 4,
           1, 2, 3, 0, 2, 3, 2, 2, 1, 2, 0, 3, 5, 2, 0, 1, 1, 1, 3, 0, 1, 3,
           2, 1, 1, 2, 2, 2, 1, 2, 1, 1, 2, 3, 0, 3, 4, 3, 1, 1, 2, 1, 3, 0,
           1, 2, 0, 2, 2, 2, 2, 3, 1, 2, 2, 4, 5, 2, 1, 2, 3, 2, 2, 0, 2, 4,
           5, 0, 2, 3, 2, 2, 3, 2, 2, 1, 0, 1, 2, 2, 2, 1, 0, 2, 1, 2, 2, 2,
           3, 2, 0, 2, 2, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 3, 3, 2, 2, 1, 2,
           1, 2, 3, 3, 0, 2, 2, 1, 3, 0, 2, 1, 1, 2, 3, 3, 0, 3, 1, 2, 1, 1,
           1, 2, 0, 1, 3, 2, 3, 1, 2, 2, 4, 2, 3, 5, 1, 1, 0, 3, 2, 3, 1, 0,
           3, 4, 2, 1, 3, 1, 1, 2, 2, 1, 3, 3, 2, 1, 1, 2, 0, 3, 2, 3, 1, 0,
           3, 3, 3, 1, 1, 3, 3, 1, 0, 0, 3, 0, 2, 0, 0, 4, 0, 1, 0, 3, 3, 1,
           2, 0, 1, 1, 2, 1, 1, 0, 1, 1, 2, 3, 0, 3, 1, 2, 2, 1, 1, 3, 3, 0,
           3, 1, 0, 2, 3, 3, 0, 2, 2, 1, 3, 3, 5, 3, 0, 0, 1, 1, 1, 2, 0, 2,
           5, 1, 1, 2, 0, 4, 1, 1, 1, 5, 3, 2, 5, 2, 4, 3, 2, 1, 5, 1, 3, 2,
           1, 1, 2, 0, 2, 2, 1, 3, 3, 1, 0, 0, 3, 7, 1, 2, 3, 1, 0, 2, 3, 0,
           1, 2, 2, 2, 2, 1, 1, 0, 2, 1, 0, 1, 3, 3, 0, 3, 0, 4, 0, 1, 1, 5,
           0, 1, 0, 1, 3, 1, 1, 1, 0, 2, 1, 2, 6, 4, 2, 3, 2, 2, 2, 3, 1, 2,
           1, 2, 2, 1, 5, 2, 3, 1, 3, 0, 1, 2, 2, 0, 0, 1, 2, 1, 2, 2, 3, 1,
           3, 2, 0, 0, 5, 0, 0, 2, 0, 2, 3, 4, 3, 1, 3, 2, 4, 1, 1, 4, 2, 1,
           2, 1, 2, 4, 0, 1, 1, 1, 2, 4, 4, 1, 1, 2, 3, 2, 0, 1, 0, 4, 2, 0,
           3, 1, 3, 4, 2, 1, 2, 6, 3, 2, 1, 0, 0, 0, 1, 0, 0, 1, 2, 1, 1, 0,
           0, 2, 1, 2, 0, 2, 2, 3, 1, 2, 3, 1, 1, 1, 0, 1, 1, 3, 1, 2, 1, 0,
           1, 3, 5, 1, 2, 4, 4, 1, 2, 1, 4, 1, 2, 0, 3, 1, 1, 1, 1, 1, 1, 3,
           1, 3, 1, 1, 3, 1, 3, 3, 2, 1, 2, 1, 1, 1, 3, 2, 3, 2, 4, 1, 3, 1,
           2, 0, 1, 2, 1, 0, 2, 3, 2, 0, 3, 0, 1, 1, 2, 4, 2, 1, 2, 4, 1, 3,
           0, 3, 2, 3, 0, 2, 1, 2, 0, 2, 2, 1, 2, 1, 1, 1, 1, 1, 3, 1, 4, 2,
           3, 1, 1, 1, 3, 2, 2, 1, 3, 4, 2, 3, 2, 0, 3, 2, 1, 1, 2, 4, 2, 0,
           3, 2, 1, 2, 2, 0, 1, 3, 1, 1, 2, 4, 2, 0, 4, 1, 2, 4, 2, 1, 0, 1,
           0, 3, 2, 2, 1, 1, 0, 0, 1, 2, 2, 0, 2, 3, 0, 2, 1, 2, 1, 1, 3, 4,
           2, 3, 1, 0, 1, 2, 1, 3, 0, 2, 2, 0, 2, 2, 1, 0, 2, 1, 4, 2, 1, 1,
           1, 2, 1, 1, 1, 1, 5, 0, 2, 3, 2, 2, 2, 4, 4, 0, 4, 0, 3, 3, 1, 3,
           2, 1, 2, 1, 1, 1, 1, 5, 0, 1, 0, 2, 3, 2, 1, 1, 1, 2, 2, 1, 1, 1,
           2, 0, 4, 1, 2, 2, 2, 1, 2, 1, 0, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2,
           3, 3, 1, 1, 2, 0, 0, 2, 2, 0, 3, 4, 4, 3, 1, 3, 2, 1, 3, 1, 3, 1,
           1, 2, 1, 3, 1, 2, 2, 1, 2, 0, 1, 4, 3, 2, 3, 2, 2, 0, 3, 1, 2, 2,
           2, 2, 2, 2, 3, 1, 4, 2, 2, 5, 1, 2, 2, 3, 3, 2, 2, 0, 2, 2, 1, 0,
           3, 2, 3, 1, 2, 3, 1, 2, 0, 2, 0, 2, 2, 0, 1, 1, 1, 0, 0, 1, 3, 2,
           0, 1, 1, 1, 2, 1, 1, 2, 1, 3, 2, 2, 1, 1, 1, 1, 1, 3, 2, 1, 3, 0,
           1, 2, 2, 2, 0, 4, 2, 3, 2, 4])



Below is the histogram plot of the previos experiment


```python
x = np.random.binomial(10, 1/6, 1000)
plt.hist(x)
```

## Hypergeometric Distribution


This distribution is very similar to the binomial distribution, except that in this case, samples are drawn without replacement, whereas in the Binomial case samples are drawn with replacement (or the sample space is infinite). As the sample space becomes large, this distribution approaches the binomial.

The probability density for the Hypergeometric distribution is
$$P(x)=\frac{{{m}\choose{n}}{{N-m}\choose{n-x}}}{{N}\choose{n}}$$
where $0\leq x \leq m$ and $n+m-N \leq x \leq n$ for $P(x)$ the probability of $x$ successes, $n$ = ngood, $m$ = nbad, and $N$ = number of samples.

Let's do an example, say we have a deck of cards contains 20 cards: 6 red cards and 14 black cards. 5 cards are drawn randomly without replacement. What is the probability that exactly 4 red cards are drawn?
The probability of choosing exactly 4 red cards is:
P(4 red cards) = # samples with 4 red cards and 1 black card / # of possible 4 card samples
$$P(4)=\frac{{{6}\choose{4}}{{14}\choose{1}}}{{20}\choose{5}}$$
In shorthand, the above formula can be interpreted as:
$6\choose4$ means that out of 6 possible red cards, we are choosing 4.
$14\choose1$ means that out of a possible 14 black cards, we’re choosing 1.
$20\choose5$ means that out of a total of 20 cards, we draw 5.  
The solution is 0.0135 or 1.35%  
The binomial distribution doesn’t apply here, because the cards are not replaced once they are drawn. In other words, the trials are not independent events. 

The random.hypergeometric function takes at least 3 arguments, the first argument is ngood (ways to make a good selection), the second is nbad (ways to make a bad selection), and the third one is nsample = number of items sampled, which is less than or equal to the sum ngood + nbad. In return, draws one number from the hypergeometric distribution.


```python
np.random.hypergeometric(6, 14, 15)
```




    4



With four arguments, the function draws an amount of samples specified by the third argument. The first three arguments are the still the same as explained in the previous cell.


```python
np.random.hypergeometric(6, 14, 15, 1000)
```




    array([5, 6, 3, 4, 5, 3, 3, 5, 5, 6, 5, 4, 6, 3, 6, 4, 3, 4, 5, 5, 3, 5,
           5, 5, 6, 4, 4, 6, 3, 4, 6, 6, 4, 3, 5, 6, 4, 3, 5, 6, 4, 4, 4, 5,
           5, 5, 4, 5, 3, 5, 4, 3, 6, 5, 4, 5, 3, 5, 5, 5, 5, 5, 4, 5, 5, 4,
           5, 4, 5, 6, 4, 6, 5, 3, 5, 4, 5, 4, 3, 6, 4, 5, 5, 5, 5, 5, 3, 5,
           3, 6, 5, 5, 3, 3, 6, 4, 4, 4, 4, 6, 5, 6, 4, 5, 6, 4, 4, 3, 4, 5,
           3, 4, 6, 5, 4, 6, 5, 5, 5, 6, 5, 4, 4, 3, 5, 5, 4, 5, 4, 3, 5, 4,
           4, 5, 4, 5, 3, 5, 5, 4, 4, 4, 5, 6, 4, 4, 5, 4, 5, 5, 5, 4, 4, 4,
           4, 5, 4, 4, 4, 5, 4, 5, 5, 6, 4, 4, 5, 4, 5, 5, 4, 6, 4, 5, 5, 3,
           4, 4, 3, 4, 5, 4, 4, 5, 5, 3, 5, 5, 5, 4, 5, 4, 5, 4, 4, 3, 4, 3,
           4, 3, 5, 6, 3, 4, 4, 5, 6, 5, 5, 3, 5, 5, 4, 5, 4, 5, 4, 5, 4, 5,
           5, 5, 4, 5, 3, 5, 5, 4, 5, 6, 5, 5, 4, 4, 6, 4, 5, 6, 4, 5, 4, 5,
           3, 4, 6, 4, 3, 3, 5, 5, 3, 5, 5, 5, 4, 5, 5, 5, 5, 4, 4, 5, 5, 3,
           5, 6, 6, 5, 4, 6, 4, 5, 4, 4, 4, 5, 4, 4, 4, 5, 6, 5, 5, 3, 5, 3,
           5, 4, 4, 4, 5, 3, 6, 6, 5, 6, 4, 5, 4, 6, 5, 5, 6, 4, 5, 5, 4, 3,
           5, 4, 4, 4, 5, 5, 4, 5, 4, 4, 4, 4, 2, 4, 4, 6, 5, 5, 4, 5, 3, 5,
           4, 4, 5, 4, 5, 5, 5, 6, 3, 6, 6, 4, 5, 6, 5, 4, 5, 5, 4, 5, 4, 5,
           6, 4, 5, 3, 5, 6, 2, 5, 5, 4, 5, 6, 4, 6, 5, 6, 6, 4, 4, 5, 5, 3,
           3, 5, 5, 5, 5, 4, 5, 5, 6, 5, 4, 4, 5, 5, 5, 5, 5, 5, 3, 5, 4, 4,
           6, 4, 5, 5, 4, 3, 4, 5, 5, 4, 5, 6, 6, 5, 6, 4, 3, 5, 5, 4, 3, 5,
           5, 3, 6, 4, 6, 2, 5, 5, 4, 5, 6, 6, 5, 5, 5, 4, 4, 5, 4, 4, 4, 4,
           6, 4, 5, 5, 5, 6, 5, 6, 4, 6, 5, 5, 5, 6, 5, 5, 4, 5, 6, 5, 5, 4,
           5, 6, 4, 5, 3, 5, 4, 4, 5, 6, 6, 4, 6, 5, 4, 4, 4, 5, 4, 6, 5, 4,
           5, 5, 3, 4, 4, 3, 5, 4, 3, 5, 4, 6, 4, 6, 3, 5, 4, 5, 6, 5, 5, 4,
           3, 5, 5, 5, 3, 4, 5, 4, 4, 4, 6, 5, 3, 4, 5, 3, 4, 5, 5, 3, 4, 4,
           3, 6, 4, 5, 5, 4, 5, 3, 6, 5, 4, 4, 5, 4, 5, 4, 6, 5, 5, 4, 5, 4,
           5, 4, 5, 5, 5, 5, 5, 3, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5,
           5, 6, 6, 4, 6, 5, 5, 6, 6, 6, 5, 4, 4, 4, 6, 4, 6, 4, 5, 3, 4, 4,
           5, 4, 5, 2, 5, 5, 5, 4, 4, 5, 5, 6, 5, 4, 5, 5, 5, 4, 6, 2, 6, 4,
           3, 5, 4, 6, 6, 6, 4, 6, 4, 3, 5, 5, 2, 4, 6, 5, 5, 3, 4, 5, 4, 3,
           4, 5, 5, 6, 6, 3, 4, 4, 6, 4, 3, 5, 4, 4, 4, 4, 6, 5, 6, 6, 3, 4,
           5, 5, 4, 5, 4, 3, 4, 5, 4, 5, 4, 6, 5, 5, 5, 5, 6, 4, 4, 5, 3, 5,
           4, 4, 5, 4, 3, 4, 6, 5, 4, 5, 4, 6, 5, 4, 5, 5, 5, 4, 6, 4, 6, 5,
           4, 2, 5, 5, 4, 6, 5, 6, 5, 4, 5, 3, 5, 4, 5, 5, 6, 6, 3, 5, 4, 4,
           4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 5, 3, 5, 3, 5, 4, 4, 5, 5, 5, 6, 4,
           4, 5, 3, 4, 4, 4, 3, 4, 5, 5, 2, 6, 5, 4, 3, 6, 5, 3, 5, 6, 4, 5,
           5, 5, 5, 4, 3, 4, 5, 4, 5, 3, 4, 5, 5, 3, 5, 5, 3, 6, 2, 5, 5, 6,
           5, 5, 5, 4, 4, 3, 4, 3, 5, 4, 5, 4, 4, 4, 5, 5, 6, 5, 4, 4, 5, 4,
           5, 4, 5, 4, 4, 5, 6, 4, 3, 6, 4, 6, 5, 4, 4, 3, 5, 5, 5, 4, 4, 4,
           5, 5, 4, 5, 5, 3, 5, 3, 6, 3, 5, 4, 6, 5, 4, 4, 5, 4, 5, 5, 4, 4,
           4, 4, 4, 4, 5, 4, 3, 5, 5, 4, 5, 5, 4, 3, 5, 4, 5, 5, 4, 6, 4, 3,
           5, 4, 5, 3, 5, 3, 5, 5, 3, 5, 5, 4, 6, 6, 4, 4, 4, 6, 5, 6, 6, 4,
           5, 4, 4, 4, 5, 6, 3, 6, 5, 6, 6, 4, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4,
           3, 4, 6, 6, 4, 5, 3, 5, 5, 4, 3, 4, 5, 5, 5, 4, 4, 4, 5, 5, 4, 3,
           5, 5, 3, 6, 5, 6, 5, 4, 3, 6, 4, 4, 6, 4, 5, 4, 4, 5, 5, 6, 4, 5,
           5, 5, 4, 4, 5, 4, 6, 3, 5, 5, 4, 5, 6, 5, 3, 6, 4, 4, 4, 6, 4, 4,
           3, 6, 5, 5, 5, 5, 4, 4, 4, 5])



Below is the histogram plot of the previos experiment


```python
x = np.random.hypergeometric(6, 14, 15, 1000)
plt.hist(x)
```

## Pareto Distribution
The Pareto distribution is a probability distribution that seeks to describe quantities which have a particular property: namely, that a few items account for a lot of it and a lot of items account for a little of it.

The distribution can be defined by the following survival function (also called tail function):  
$${\displaystyle {\overline {F}}(x)=\Pr(X>x)={\begin{cases}\left({\frac {x_{\mathrm {m} }}{x}}\right)^{\alpha }&x\geq x_{\mathrm {m} },\\0&x<x_{\mathrm {m} },\end{cases}}}$$

* X is a random variable with a Pareto distribution. The probability that X is greater than some number x. 
* $x_m$ is the (necessarily positive) minimum possible value of X. The Pareto distribution is characterized by $x_m$.
* α is shape parameter, which is known as the tail index.

A well known example of the Pareto distribution is that 20 percent of the people control 80 percent of the wealth (which itself is sometimes called the Pareto principle), is another statement of the fact that the allocation of income could be Pareto distributed.  
Some other examples:
* business: the top few customers account for a bulk of the profits
* insurance: a small number of big claims account for a bulk of payments
* settlement: a small number of cities include a bulk of the population
* languages: the most frequent words account for most words in books
* gardening: a select few pods account for most of the peas
* software: a small number of bugs account for most of the crashes

The random.pareto function takes at least 1 argument, α the shape parameter, which is known as the tail index. In return, draws one number from the pareto distribution.


```python
np.random.pareto(3)
```




    1.429784162583148



With two arguments, the function draws an amount of samples specified by the second argument where shape (α) is provided by the first argument.


```python
np.random.pareto(3,5)
```




    array([0.34836993, 0.78069429, 7.20838718, 0.09207709, 0.2667663 ])



Below is a histogram plot with 1000 samples and α and is 3


```python
x = np.random.pareto(3, 1000)
plt.hist(x)
```

## Poisson Distribution

The Poisson distribution is popular for modelling the number of times an event occurs in an interval of time or space.

An event can occur 0, 1, 2, … times in an interval. The average number of events in an interval is designated 
λ (lambda). Lambda is the event rate, also called the rate parameter. The probability of observing k events in an interval is given by the equation  
$${\displaystyle P(k{\text{ events in interval}})=e^{-\lambda }{\frac {\lambda ^{k}}{k!}}}$$

where 
* λ is the average number of events per interval
* $e$ is the number 2.71828... (Euler's number) the base of the natural logarithms
* $k$ takes values 0, 1, 2, …
* $k! = k × (k − 1) × (k − 2) × … × 2 × 1$ is the factorial of $k$.

For example, the average number of goals in a World Cup soccer match is approximately 2.5 and the Poisson model is appropriate.
Because the average event rate is 2.5 goals per match, λ = 2.5. 

\begin{align}
& {\displaystyle P(k{\text{ goals in a match}})={\frac {2.5^{k}e^{-2.5}}{k!}}}  \\
& {\displaystyle P(k=0{\text{ goals in a match}})={\frac {2.5^{0}e^{-2.5}}{0!}}={\frac {e^{-2.5}}{1}}\approx 0.082} \\
& {\displaystyle P(k=1{\text{ goal in a match}})={\frac {2.5^{1}e^{-2.5}}{1!}}={\frac {2.5e^{-2.5}}{1}}\approx 0.205} \\
& {\displaystyle P(k=2{\text{ goals in a match}})={\frac {2.5^{2}e^{-2.5}}{2!}}={\frac {6.25e^{-2.5}}{2}}\approx 0.257}
\end{align}

The table below gives the probability for 0 to 7 goals in a match.  

k | P(k goals in a World Cup soccer match)
--- | ---
0 | 0.082 
1 | 0.205 
2 | 0.257 
3 | 0.213 
4 | 0.133 
5 | 0.067 
6 | 0.028 
7 | 0.010

The random.poisson function without arguments draws a sample where the average lambda $(\lambda)$ is 1 


```python
np.random.poisson()
```




    1



With one argument, the function draws a number where the argument is the average lambda $(\lambda)$


```python
np.random.poisson(2.5)
```




    1



With two arguments, the function draws an amount of samples specified by the second argument where  average lambda 
($\lambda$) is provided by the first argument


```python
np.random.poisson(2.5,10)
```




    array([2, 2, 3, 4, 2, 0, 3, 1, 4, 3])



Below is histogram plot with 1000 samples and $\lambda$ is 2.5


```python
x = np.random.poisson(2.5,1000)
plt.hist(x)
```

## Random Seeds
A random seed (or seed state, or just seed) is a number used to initialize a pseudorandom number generator. Random seeds are often generated from the state of the computer system, such as the time.  
A pseudorandom number generator is an algorithm for generating a sequence of numbers whose properties approximate the properties of sequences of random numbers. The pseudorandom-generated sequence is not truly random, because it is completely determined by an initial value, the seed.  
If the seed is fixed, the same series of pseudorandom numbers are going to be generated. This is useful for debugging and testing programs that use random numbers

By default Python uses a fraction of time to set the seed, usually microseconds at runtime. Let's compare calls to the 'rand()' function without and with a fixed seed.


```python
np.random.rand()
```




    0.4095710254077406



Let's fixed the seed to a fixed value and call 'rand()' again


```python
np.random.seed(4)
np.random.rand()
```




    0.9670298390136767



Let's use time as seed again an


```python
np.random.seed()
np.random.rand()
```




    0.51266711229377



Now, let's set the seed value to 4 again and we'll see it generate the same value as before:


```python
np.random.seed(4)
np.random.rand()
```




    0.9670298390136767



bcc673f4001e027febb10456759dc3555bcd0268
ipynb
Jupyter Notebook
numpy-random.ipynb
cadel560x/EmergingTechAssignments
48ff0f500ad5ae26f3f29949a165f21825e93cf0
MIT
numpy-random.ipynb
cadel560x/EmergingTechAssignments
48ff0f500ad5ae26f3f29949a165f21825e93cf0
MIT
numpy-random.ipynb
cadel560x/EmergingTechAssignments
48ff0f500ad5ae26f3f29949a165f21825e93cf0
MIT
Qwen/Qwen-72B
1. YES
2. YES