Python 样本分布模拟不会导致正态分布

Python 样本分布模拟不会导致正态分布,python,probability,normal-distribution,probability-distribution,bernoulli-probability,Python,Probability,Normal Distribution,Probability Distribution,Bernoulli Probability,我试图用Python模拟“样本比例的样本分布”。我尝试使用贝努利变量,如示例所示 关键是,在大量的口香糖球中,我们有黄色的口香糖球,真实比例为0.6。如果我们采集样本(一定大小,比如10个),取平均值并绘制图,我们应该得到一个正态分布 我试着用python来做,但我总是得到均匀分布(或中间的平面)。我无法理解我错过了什么 节目: from SDSP import create_bernoulli_population, get_frequency_df from random import sh

我试图用Python模拟“样本比例的样本分布”。我尝试使用贝努利变量,如示例所示

关键是,在大量的口香糖球中,我们有黄色的口香糖球,真实比例为0.6。如果我们采集样本(一定大小,比如10个),取平均值并绘制图,我们应该得到一个正态分布

我试着用python来做,但我总是得到均匀分布(或中间的平面)。我无法理解我错过了什么

节目:

from SDSP import create_bernoulli_population, get_frequency_df
from random import shuffle, choices
from bi_to_nor_demo import get_metrics, bare_minimal_plot
import matplotlib.pyplot as plt


N = 10000  # 10000 balls
p = 0.6    # probability of yellow ball is 0.6, and others (1-0.6)=>0.4
n_pickups = 1000       # sample size
n_experiments = 100  # I dont know what this is called 


# generate population
population = create_bernoulli_population(N,p)
theor_df = get_frequency_df(population)
theor_df

# choose sample, take mean and add to X_mean_list. Do this for n_experiments times
X_hat = []
X_mean_list = []
for each_experiment in range(n_experiments):
    X_hat = choices(population, k=n_pickups)  # this method is with replacement
    shuffle(population)
    X_mean = sum(X_hat)/len(X_hat)
    X_mean_list.append(X_mean)

# plot X_mean_list as bar graph
stats_df = get_frequency_df(X_mean_list)
fig, ax = plt.subplots(1,1, figsize=(5,5))
X = stats_df['x'].tolist()
P = stats_df['p(x)'].tolist()    
ax.bar(X, P, color="C0") 

plt.show()
相关函数:

输出:

更新: 我甚至尝试了如下的均匀分布,但得到了相似的输出。不收敛于正态:((使用下面的函数代替create_-bernoulli_总体)


你能分享你的matplotlib设置吗?我想你的绘图被截断了,你是正确的,在贝努利上样本比例的样本分布应该是正态分布在总体期望值周围

也许用一些东西作为:

plt.tight_layout()

若要检查是否没有图形问题,请共享matplotlib设置好吗?我认为您已截断了绘图,您是正确的,因为贝努利上样本比例的样本分布应围绕总体预期值正态分布

def plotHist(nr, N, n_):
    ''' plots the RVs'''
    x = np.zeros((N))
    sp = f.add_subplot(3, 2, n_ )

    for i in range(N):    
        for j in range(nr):
            x[i] += np.random.binomial(10, 0.6)/10 
        x[i] *= 1/nr
    plt.hist(x, 100, normed=True, color='#348ABD', label=" %d RVs"%(nr));
    plt.setp(sp.get_yticklabels(), visible=False)


N = 1000000   # number of samples taken
nr = ([1, 2, 4, 8, 16, 32])

for i in range(np.size(nr)):
    plotHist(nr[i], N, i+1)
也许用一些东西作为:

plt.tight_layout()
检查是否没有图形问题

def plotHist(nr, N, n_):
    ''' plots the RVs'''
    x = np.zeros((N))
    sp = f.add_subplot(3, 2, n_ )

    for i in range(N):    
        for j in range(nr):
            x[i] += np.random.binomial(10, 0.6)/10 
        x[i] *= 1/nr
    plt.hist(x, 100, normed=True, color='#348ABD', label=" %d RVs"%(nr));
    plt.setp(sp.get_yticklabels(), visible=False)


N = 1000000   # number of samples taken
nr = ([1, 2, 4, 8, 16, 32])

for i in range(np.size(nr)):
    plotHist(nr[i], N, i+1)
以上是基于我在CLT上写的一篇普通博客的代码示例:

本质上,我从(0,1)范围内的分布中生成几个随机数(nr)并求和。然后我看到,当我增加随机数的数量时,它们是如何收敛的

以上是基于我在CLT上写的一篇普通博客的代码示例:

本质上,我从(0,1)范围内的分布中生成几个随机数(nr)并求和。然后我看到,当我增加随机数的数量时,它们是如何收敛的


解决方案:
我想我已经找到了解决方案。通过逆向工程Rajesh的方法,并从Daniel那里得到了关于图形是否可能存在问题的提示,最终我找到了罪魁祸首:默认条形图宽度为0.8太宽,无法将我的图形显示为顶部平坦。下面是修改后的代码和输出

from SDSP import create_bernoulli_population, get_frequency_df
from random import shuffle, choices
from bi_to_nor_demo import get_metrics, bare_minimal_plot
import matplotlib.pyplot as plt

N = 10000  # 10000 balls
p = 0.6    # probability of yellow ball is 0.6, and others (1-0.6)=>0.4
n_pickups = 10       # sample size
n_experiments = 2000  # I dont know what this is called 


# THEORETICAL PDF
# generate population and calculate theoretical bernoulli pdf
population = create_bernoulli_population(N,p)
theor_df = get_frequency_df(population)


# STATISTICAL PDF
# choose sample, take mean and add to X_mean_list. Do this for n_experiments times. 
X_hat = []
X_mean_list = []
for each_experiment in range(n_experiments):
    X_hat = choices(population, k=n_pickups)  # choose, say 10 samples from population (with replacement)
    X_mean = sum(X_hat)/len(X_hat)
    X_mean_list.append(X_mean)
stats_df = get_frequency_df(X_mean_list)


# plot both theoretical and statistical outcomes
fig, (ax1,ax2) = plt.subplots(2,1, figsize=(5,10))
from SDSP import plot_pdf
mu,var,sigma = get_metrics(theor_df)
plot_pdf(theor_df, ax1, mu, sigma, p, title='True Population Parameters')
mu,var,sigma = get_metrics(stats_df)
plot_pdf(stats_df, ax2, mu, sigma, p=mu, bar_width=round(0.5/n_pickups,3),title='Sampling Distribution of\n a Sample Proportion')
plt.tight_layout()
plt.show()
输出:

解决方案:
我想我已经找到了解决方案。通过逆向工程Rajesh的方法,并从Daniel那里得到了关于图形是否可能存在问题的提示,最终我找到了罪魁祸首:默认条形图宽度为0.8太宽,无法将我的图形显示为顶部平坦。下面是修改后的代码和输出

from SDSP import create_bernoulli_population, get_frequency_df
from random import shuffle, choices
from bi_to_nor_demo import get_metrics, bare_minimal_plot
import matplotlib.pyplot as plt

N = 10000  # 10000 balls
p = 0.6    # probability of yellow ball is 0.6, and others (1-0.6)=>0.4
n_pickups = 10       # sample size
n_experiments = 2000  # I dont know what this is called 


# THEORETICAL PDF
# generate population and calculate theoretical bernoulli pdf
population = create_bernoulli_population(N,p)
theor_df = get_frequency_df(population)


# STATISTICAL PDF
# choose sample, take mean and add to X_mean_list. Do this for n_experiments times. 
X_hat = []
X_mean_list = []
for each_experiment in range(n_experiments):
    X_hat = choices(population, k=n_pickups)  # choose, say 10 samples from population (with replacement)
    X_mean = sum(X_hat)/len(X_hat)
    X_mean_list.append(X_mean)
stats_df = get_frequency_df(X_mean_list)


# plot both theoretical and statistical outcomes
fig, (ax1,ax2) = plt.subplots(2,1, figsize=(5,10))
from SDSP import plot_pdf
mu,var,sigma = get_metrics(theor_df)
plot_pdf(theor_df, ax1, mu, sigma, p, title='True Population Parameters')
mu,var,sigma = get_metrics(stats_df)
plot_pdf(stats_df, ax2, mu, sigma, p=mu, bar_width=round(0.5/n_pickups,3),title='Sampling Distribution of\n a Sample Proportion')
plt.tight_layout()
plt.show()
输出:

我已检查是否没有截断。还尝试了plt.tight_layout()但同样的结果你是很棒的Daniel。也许,宽度是罪魁祸首之一,减少它可以得到更好的图形。计算中也有问题。很快会更新它。@PaariVendhan,很高兴!很高兴你能解决问题,祝你好运!我已经检查过没有截断。还尝试了plt.tight_layout()但同样的结果你是很棒的Daniel。也许,宽度是罪魁祸首之一,减少它可以更好地呈现图形。此外,计算中存在问题。将很快更新它。@PaariVendhan,很高兴!很高兴你能够解决问题,祝你的模拟好运!你的np.random.binomian将始终从二项式返回随机值分布?二项分布总是收敛于正态分布。在我的例子中,我正在尝试使用伯努利分布和均匀分布。如果我遗漏了什么,请检查我的代码。很抱歉,我弄错了你的问题!我没有重做n=1的二项分布的练习,这是伯努利分布。你的代码很长!我将尝试找到一些技巧另外,可以通过将
x[i]+=np.random.binomian(10,0.6)/10
替换为
x[i]+=np.random.binomian(1,0.6)来修改上述内容
。然后,我是伯努利。你可以看到它仍然倾向于高斯分布。我还通过电子邮件向你发送了一个屏幕截图。我非常感谢你回复我的请求并在这里帮助我。期待反馈。我还试着在random.binomial中使用n=1运行你的代码,得到了一个非正态分布,奇怪的是,我只得到了一个图(同时发出警告),和非正态分布。您的np.random.binomial将始终返回来自二项分布的随机值?二项分布始终收敛到正态。在我的情况下,我正在尝试使用伯努利分布和均匀分布。如果我缺少任何内容,请检查我的代码。很抱歉,您的问题出错!我没有重做n=1的二项式的练习,即伯努利。你有一个很长的代码!我会设法找一些时间来研究它。另外,可以通过将
x[I]+=np.random.binomary(10,0.6)/10
替换为
x[I]+=np.random.binomary(1,0.6)来修改上述内容
。然后,我是伯努利。你可以看到它仍然倾向于高斯分布。我还通过电子邮件向你发送了一个屏幕截图。我非常感谢你回复我的请求并在这里帮助我。期待反馈。我还试着在random.binomial中使用n=1运行你的代码,得到了一个非正态分布,奇怪的是,我只得到了一个图(同时发出警告),非正态分布再次出现