<jupyter_start><jupyter_text>Interactive of the Central Limit Theorem Demonstration Summation or Averaging of Random Variables Tutorial* demonstrate the practical impact of summation or averaging on distributions* interactive plot demonstration with ipywidget package <NAME>, Associate Professor, University of Texas at Austin  [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1) | [GeostatsPy](https://github.com/GeostatsGuy/GeostatsPy) Central Limit TheoremThe summation of independent random variables will approach Gaussian distributed as the number of random variables become large* for any distribution shape for the individual random variables* same for averaging since it is just the application of a scalar to the summation ($\frac{1}{m}$)We can state this as:\begin{equation}Y \sim N\left[\right]\end{equation}where $Y$ is the summation of a large number of independent random variables, $X_i$, where $i = 1,\ldots,m$.\begin{equation}Y = \sum_{i=1}^{m \to \infty} X_i\end{equation}from statistical expectation we can calculate the central tedency as:\begin{equation}E[Y] = E \left[\sum_{i=1}^{m \to \infty} X_i \right] = \sum_{i=1}^{m \to \infty} E \left[X_i \right]  \end{equation}and under the assumption of independence the dispersion as:\begin{equation}\sigma_Y^2 = \sum_{i=1}^{m \to \infty} \sigma_X^2  \end{equation}therefore, we have our distribution as:\begin{equation}Y \sim N \left[ \sum_{i=1}^{m \to \infty} E[X_i], \sum_{i=1}^{m \to \infty} \sigma_X^2 \right]\end{equation}we can simplify by assuming the same central tendency and dispersion for all random variables, $X_i$, with central tendency and dispersion:\begin{equation}E[X_i] = \mu\end{equation}\begin{equation}Var[X_i] = \sigma^2\end{equation}now we have:\begin{equation}Y \sim N \left[ m \mu, m \sigma_X^2 \right]\end{equation}for the case of the average instead of the summation of random variables, $X_i$:\begin{equation}Y = \frac{1}{m} \sum_{i=1}^{m \to \infty} X_i\end{equation}and all with the same central tendency and dispersion the distribution of $Y$ is given by:\begin{equation}Y \sim N \left[ \mu, \frac{\sigma^2}{n} \right]\end{equation}**Monte Carlo Simulation** is a method to sample from a single or set of random variables to assess the emergent distribution. * also known as Monte Carlo methods and Monte Carlo experiments* a method in statistics for generating draws from probability distributions empirically* powerful due to it's broad applicabilityWe can apply Monte Carlo methods ot sample from the sum of our random variables.  We proceed as follows:* for all $X_i$ random variables draw a random value (random realization), $x_i$* calculate the average of the random realizations, $y_i = \frac{1}{n} \sum_{i=1}^{n} x_i$* repeat over a large number of samples, $n$, and observe the resulting distribution* compare the experimental CDF to the Gaussian distribution predicted from the Central Limit Theoremassess the uncertainty in a sample statistic by repeated random sampling with replacement. Objective Provide an example and demonstration for:1. interactive plotting in Jupyter Notebooks with Python packages matplotlib and ipywidgets2. provide an intuitive hands-on demonstration of the central limit theorem    Getting StartedHere's the steps to get setup in Python with the GeostatsPy package:1. Install Anaconda 3 on your machine (https://www.anaconda.com/download/). 2. Open Jupyter and in the top block get started by copy and pasting the code block below from this Jupyter Notebook to start using the geostatspy functionality.  Load the Required LibrariesThe following code loads the required libraries.<jupyter_code>%matplotlib inline
from ipywidgets import interactive                        # widgets and interactivity
from ipywidgets import widgets                            
from ipywidgets import Layout
from ipywidgets import Label
from ipywidgets import VBox, HBox
import matplotlib.pyplot as plt                           # plotting
import numpy as np                                        # working with arrays
import pandas as pd                                       # working with DataFrames
from scipy.stats import triang                            # parametric distributions
from scipy.stats import binom
from scipy.stats import norm
from scipy.stats import uniform
from scipy.stats import triang
from scipy import stats                                   # statistical calculations
import random                                             # random drawing / bootstrap realizations of the data
import math                                               # square root operator<jupyter_output><empty_output><jupyter_text>Specify the Distributions of $X_i$ and the Number of Random Variables, $m$, and Realizations, $L$This is an interactive method to:* select a parametric distribution* select the distribution parameters* select the number of random variables, $m$ * select the number of Monte Carlo realizations, $L$, to sample the distribution of $Y = \sum_{i=1}^m X_i$<jupyter_code># parameters for the synthetic dataset
bins = np.linspace(0,100,50)

# interactive calculation of the sample set (control of source parametric distribution and number of samples)
l = widgets.Text(value='                              Central Limit Theorem Demonstration, <NAME>, Associate Professor, The University of Texas at Austin',layout=Layout(width='950px', height='30px'))
dist = widgets.Dropdown(
    options=['Triangular', 'Uniform', 'Gaussian'],
    value='Gaussian',
    description='Dataset Distribution:',
    disabled=False,
    layout=Layout(width='200px', height='30px')
)
a = widgets.FloatSlider(min=0.0, max = 100.0, value = 0.5, description = '$X_i$: Mean / Mode',orientation='vertical',layout=Layout(width='110px', height='200px'))
a.style.handle_color = 'blue'
d = widgets.FloatSlider(min=0.01, max = 30.0, value = 5.0, step = 1.0, description = '$X_i$: St.Dev.',orientation='vertical',layout=Layout(width='110px', height='200px'))
d.style.handle_color = 'green'
b = widgets.FloatSlider(min = 0, max = 100.0, value = 0.5, description = '$X_i$: Min.',orientation='vertical',layout=Layout(width='110px', height='200px'))
b.style.handle_color = 'red'
c = widgets.IntSlider(min = 0, max = 100, value = 100, description = '$X_i$: Max.',orientation='vertical',layout=Layout(width='110px', height='200px'))
c.style.handle_color = 'orange'
m = widgets.IntSlider(min = 1, max = 20, value = 1, description = '$m$ ',orientation='vertical',layout=Layout(width='110px', height='200px'))
m.style.handle_color = 'gray'
L = widgets.IntSlider(min = 1, max = 1000, value = 100, description = '$L$ ',orientation='vertical',layout=Layout(width='110px', height='200px'))
L.style.handle_color = 'gray'

ui = widgets.HBox([dist,a,d,b,c,m,L],)                   # basic widget formatting   
ui2 = widgets.VBox([l,ui],)

def f_make(dist,a, b, c, d, m, L):                       # function to take parameters, make sample and plot
    dataset, average, stdev = make_average_data(dist,a, b, c, d, m, L)
    stdev = stdev / math.sqrt(m)

    plt.subplot(221)
    sample, null, null = make_average_data(dist,a, b, c, d, m=1, L=1000)
    plt.hist(sample,alpha=0.2,color="red",edgecolor="black",bins=bins) 
    plt.xlim(0.0,100.0); plt.title('Distribution, $X_i$'); plt.ylabel('Frequency'); plt.xlabel('Values')
    
    plt.subplot(222) 
    plt.hist(dataset,alpha=0.2,color="red",edgecolor="black",bins=bins) 
    plt.xlim(0.0,100.0); plt.title('Distribution, $Y$'); plt.ylabel('Frequency'); plt.xlabel('Values')
    
    plt.subplot(223)    
    plt.hist(dataset,cumulative = True, density = True, alpha=0.2,color="red",edgecolor="black", bins = bins, label = 'Bootstrap')
    plt.xlim(0.0,100.0); plt.title('Comparison to Gaussian CDF'); plt.xlabel('Values'); plt.ylabel('Cumulative Probability') 
    
    cumul_prob = np.linspace(0.0,1.0,100)
    prop_values = norm.ppf(cumul_prob) 
    prop_values = prop_values * stdev + average           
    plt.plot(prop_values, cumul_prob, color = 'black', linewidth = 2, dashes = (5,2,1,2), label = 'Analytical')

    plt.legend()
             
    plt.subplots_adjust(left=0.0, bottom=0.0, right=2.0, top=2.6, wspace=0.2, hspace=0.2)
    plt.show()

def make_average_data(dist,a, b, c, d, m, L):            # function to check parameters and make samples   
    average = 0.0; stdev = 0.0
    if dist == 'Uniform':
        if b >= c:
            print('Invalid uniform distribution parameters')
            return None
        dataset = np.mean(uniform.rvs(size=[m,L], loc = b, scale = c, random_state = 73073),axis = 0)
        average = uniform.mean(loc = b, scale = c)
        stdev = uniform.std(loc = b, scale = c)
        return dataset, average, stdev
    elif dist == 'Triangular':
        interval = c - b
        if b >= a or a >= c or interval <= 0:
            print('Invalid triangular distribution parameters')
            return None        
        dataset = np.mean(triang.rvs(size=[m,L], loc = b, c = (a-b)/interval, scale = interval, random_state = 73073), axis = 0)
        average = triang.mean(loc = b, c = (a-b)/interval, scale = interval)
        stdev = triang.std(loc = b, c = (a-b)/interval, scale = interval)
        return dataset, average, stdev
    elif dist == 'Gaussian':
        dataset = np.mean(norm.rvs(size=[m,L], loc = a, scale = d, random_state = 73073), axis = 0)
        average = norm.mean(loc = a, scale = d)
        stdev = norm.std(loc = a, scale = d)
        return dataset, average, stdev

# connect the function to make the samples and plot to the widgets    
interactive_plot = widgets.interactive_output(f_make, {'dist': dist,'a': a, 'd': d, 'b': b, 'c': c, 'm': m, 'L':L})
interactive_plot.clear_output(wait = True)               # reduce flickering by delaying plot updating<jupyter_output><empty_output><jupyter_text>Display the GUI for Building the Synthetic DatasetWe display the GUI now.  Select the desired parametric distribution and associated parameters.* if the parameters are invalid (e.g. traingular mode > max) an error message should display.<jupyter_code>display(ui2, interactive_plot)                            # display the interactive plot<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12012097155278328, 'fraction_numerical': 0.021359039788299783, 'mean_word_length': 3.7904028972385695, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 19, 'https://': 8, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '109815', 'license': 'MIT', 'n_tokens_mistral': 3329, 'n_tokens_neox': 3115, 'n_words': 1021, 'path': 'Interactive_Central_Limit_Theorem.ipynb', 'repo_name': 'AndrewAnnex/PythonNumericalDemos', 'size': '10595'}