【小白学机器学习42】试验--随着样本容量增加,样本的均值的均值趋向总体,均值的方差减小。而样本的std的均值也是同样效果。

发布于:2024-12-07 ⋅ 阅读:(126) ⋅ 点赞:(0)

目录

1 进行多次抽样,样本的分布参数和总体的分布参数的关系

2  样本容量越大,多次抽样的样本的分布参数和总体的分布参数的关系

2.1 如果进行多次抽样,样本的均值将趋向总体的均值

2.2 换句话说:样本的均值将趋向总体的均值就是,mean(样本均值) = 总体均值

2.3 下面的图能说明很多信息

2.4 下面是具体的代码

2.4.1 代码里发现的一个随机问题

3 随着样本容量增大,多次抽样de均值de→平均值和std的变化

3.1 直接看(样本容量变化时)多次取样de样本的均值趋向总体均值的过程

3. 2 有意义的多次取样时,标准差std随着样本规模的变化趋势

3.3 继续改进,全部都修改为,相同样本规模下多次试验,然后根据多次试验结果得出均值和均值的std

4 多次取样的均值的标准差 ,std(mean) 即 标准误差/标准误

4.1 多次抽样时,随着样本规模的增大,样本的均值的标准差std会一直减少!

4.2 样本的均值的标准差std的学名:SE标准误/标准误差

4.3 SE的理论计算公式

4.4 画出SE的图和多次取样的样本的均值的std对比

4.4.1 对应代码

 4.4.2 多次取样的样本均值的std 和 se的曲线对比

5 随着样本容量增大,多次抽样de标准差de→平均值和std的变化

5.1 一般情况下,样本的方差<=总体方差

5.2 用样本方差直接去估计总体方差是有偏估计,但是可以通过/(n-1)获得无偏的方差估计。

5.3 随着样本容量增大,样本std也是趋向总体的std

5.4 下面这个图可以看出,同样的样本容量下,方差的无偏估计的结果更接近总体的std=0.5

5.5 下面是详细的代码


进行多次抽样,样本的分布参数和总体的分布参数的关系

1 进行多次抽样,样本的分布参数和总体的分布参数的关系

  • 每次抽样都会得到1个均值,1个方差
  • 多次抽样会得到多个均值,多个方差
  • 可以把多次抽样得到的均值,方差再进行平均,看下多次抽样的平均值和总体参数的关系

  • 多次抽样会得到多个均值→也就是均值数组,这个均值数组的平均值,接近总体的均值
  • 多次抽样会得到多个方差→也就是方差数组,这个方差数组的平均值,会远小于总体的均值,这就是样本方差对总体方差的有偏估计。
  •  std的情况类方差。

import numpy as np
import pandas as pd
import scipy as sp
from matplotlib import pyplot as plt
import seaborn as sns
%precision 3

population1=sp.stats.norm(loc=4,scale=0.8)  #不设置size,可以认为是一个无限的总体?
samples_mean_array1=np.zeros(1000)
np.random.seed(1)
for i in range(0,1000):
    sample1=population1.rvs(size=10)
    samples_mean_array1[i]=np.mean(sample1)

#print(samples_mean_array1)
sns.distplot(samples_mean_array1)
#sns.histplot(samples_mean_array1)
#sns.kdeplot(samples_mean_array1, fill=True)
plt.show()

print(f"设置的总体的均值 =4")
print(f"设置的总体的方差 ={0.8*0.8}")
print(f"设置的总体的标准差 =0.8")
print()

print(f"多次抽样的样本均值的均值 = {np.mean(samples_mean_array1)}")
print(f"多次抽样的样本方差的均值 = {np.var(samples_mean_array1)}")
print(f"多次抽样的样本标准差的均值 = {np.std(samples_mean_array1)}")
print()
      
print("多次抽样的样本的均值的均值,接近总体的均值")      
print("多次抽样的样本的方差的均值,远远小于总体的方差")   
print("多次抽样的样本的标准差的均值,远远小于总体的标准差")       
print()

2  样本容量越大,多次抽样的样本的分布参数和总体的分布参数的关系

2.1 如果进行多次抽样,样本的均值将趋向总体的均值

  • 首先,还是基于,多次抽样
  • 因为单次抽样的随机性比较大
  • 样本容量越大,多次抽样的样本的分布参数和总体的分布参数的关系会发现
  1. 样本容量越大,多次抽样的样本的平均值的均值,会收敛,越来越接近总体的平均值
  2. 样本容量越大,多次抽样的样本的方差的均值,会收敛,越来越接近总体的方差

2.2 换句话说:样本的均值将趋向总体的均值就是,mean(样本均值) = 总体均值

  • 样本的均值将趋向总体的均值
  • → 样本均值的均值 = 总体均值
  • → mean(样本均值) = 总体均值

2.3 下面的图能说明很多信息

  • 大数定律:简单理解,就是多次试验,样本的均值会接近总体的均值
  • 基本可以反应在下面的图里
  • 下面2张图
  • plot折线图,可以看出随着sample_size增加,样本均值向总体均值靠拢的趋势,过程
  • hist频度图更清晰的反应,样本均值的均值,集中靠近总体均值的程度。
  • hist图可以理解为,plot折线图,转过来,然后数据往下掉下来集中形成的!

hist图就像把plot给旋转竖过来了+ 下沉相同的归类后统计成次数!!

hist图就像把plot给旋转竖过来了+ 下沉相同的归类后统计成次数!!

hist图就像把plot给旋转竖过来了+ 下沉相同的归类后统计成次数!!

2.4 下面是具体的代码

2.4.1 代码里发现的一个随机问题

  • ramdon.seed(100) 计算出来的,均值的均值=4.34
  • 碰巧代码里整行用的是ramdon.seed(100),否则还发现不了这么奇怪的事情。。。
  • ramdon.seed(1)  或者ramdon.seed() 计算出来的,均值的均值=0.00099
  • 暂时不知道原因,很奇怪。。。。小心吧


 

3 随着样本容量增大,多次抽样de均值de→平均值和std的变化

3.1 直接看(样本容量变化时)多次取样de样本的均值趋向总体均值的过程

  • 多次抽样的样本均值的均值趋向总体的均值,我这因为总体loc=0, 样本均值的均值也接近0

  • 但是,这样求出的std 没意义
  • 错误:多次抽样的样本均值的 方差很小,说明很稳定
  • 因为,这个方差/ 标准差,是把不同取样规模的样本的均值,加一起再平均算的方差/ 标准差,本身没有意义
  • 有意义的方差/ 标准差,是在相同的 样本规模时,多次取样(循环里的循环),得出的多次取样的方差/ 标准差,才有比较的意义!这个一定要注意!

  • 为什么呢,因为我们必须再相同的标准下计算均值和方差
  • 相同的标准:取样的样本规模 sample_size
  • 相同的sample_size下,取样一次,均值基本比较稳定,勉强可用
  • 相同的sample_size下,取样一次,方差会相差很大,不能这么用

  • 其实严格的说
  • 无论,均值还是std,都需要再相同的sample_size下,多试验多次,计算这个相同条件:比如sample_size=50下的多次取样的均值和std
  • 相同的sample_size下,取样多次得到的mean,再计算np.mean(mean)
  • 相同的sample_size下,取样多次得到的mean,再计算np.std(mean)

import numpy as np
import pandas as pd
import scipy as sp
from matplotlib import pyplot as plt
import seaborn as sns
%precision 3

np.random.seed(1)
count1=999

#生成一个总体的正态分布,先不生成数量
population1=sp.stats.norm(loc=0,scale=1)
sample_mean_array1=np.zeros(count1)
sample_mean_std_array2=np.zeros(count1)

for i in range(0,count1,1):
    #每次循环时,取1次数量,作为样本
    array1=population1.rvs(size=10+i*10)
    sample_mean_array1[i]=np.mean(array1)
    sample_mean_std_array2[i]=np.std(array1)

#下面展示的是每次取样/试验得到的 均值和std随着 取样数量的增加 的变化趋势
fig1=plt.figure(num=1,figsize=(5, 5))
plt.plot(sample_mean_array1)
plt.title("随着抽样规模的变大,多次抽样的样本均值的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_mean",fontsize=16)

fig2=plt.figure(num=2,figsize=(5, 5))
plt.plot(sample_mean_std_array2)
plt.title("随着抽样规模的变大,多次抽样的样本std的变化---这个std无意义!",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

#print(sample_mean_array1)
print(f"取样{count1}次的均值的均值={np.mean(sample_mean_array1)}")
print(f"取样{count1}次的均值的std={np.std(sample_mean_array2)}")

3. 2 有意义的多次取样时,标准差std随着样本规模的变化趋势

  • 下图可见,
  • 在不同的抽样规模下,标准差,是明显随着取样规模的变大而变小的

import numpy as np
import pandas as pd
import scipy as sp
from matplotlib import pyplot as plt
import seaborn as sns
%precision 3

np.random.seed(1)
count1=999

#生成一个总体的正态分布,先不生成数量
population1=sp.stats.norm(loc=0,scale=1)
sample_mean_array1=np.zeros(count1)
sample_mean_std_array2=np.zeros(count1)

for i in range(0,count1,1):
    #每次循环时,取1次数量,作为样本
    array1=population1.rvs(size=10+i*10)
    sample_mean_array1[i]=np.mean(array1)
    sample_mean_std_array2[i]=np.std(array1)

#下面展示的是每次取样/试验得到的 均值和std随着 取样数量的增加 的变化趋势
fig1=plt.figure(num=1,figsize=(5, 5))
plt.plot(sample_mean_array1)
plt.title("随着抽样规模的变大,多次抽样的样本均值的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_mean",fontsize=16)

fig2=plt.figure(num=2,figsize=(5, 5))
plt.plot(sample_mean_std_array2)
plt.title("随着抽样规模的变大,多次抽样的样本std的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

#print(sample_mean_array1)
print(f"取样{count1}次的均值的均值={np.mean(sample_mean_array1)}")
print(f"取样{count1}次的均值的std={np.std(sample_mean_array2)}")



#下面展示的是每次取样/试验得到的 均值和std随着 取样数量的增加 的变化趋势
#这个 std是均值的std, 也就是在每个样本容量规模处,做多次试验(嵌套循环),所得到的std,
#而不是不同规模下的取样样本,得到的多个样本的均值的标准差,那个没啥意义!

sample_mean_array11=np.zeros(count1)
sample_mean_std_array21=np.zeros(count1)

for i in range(0,count1,1):
    #每次循环时,取1次数量,作为样本
    for j in range(0,10,1):
        array11=population1.rvs(size=10+i*10)
        sample_mean_array11[j]=np.mean(array11)
    #sample_mean11[i]=np.mean(sample_mean_array11)
    #sample_mean_std_array21[i]=np.std(sample_mean11)
    sample_mean_std_array21[i]=np.std(sample_mean_array11)
    

fig3=plt.figure(num=3,figsize=(5, 5))
plt.plot(sample_mean_std_array21)
plt.title("随着抽样规模的变大,多次抽样的样本std的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

3.3 继续改进,全部都修改为,相同样本规模下多次试验,然后根据多次试验结果得出均值和均值的std

  • 都是需要先内部循环多次,
  • 得到平均值的数组
  • 然后再求这个数组  平均值和std
  •     sample_mean_std_array21[i]=np.std(sample_mean_array11)
  •     sample_mean_mean_array20[i]=np.mean(sample_mean_array11)

结论

  • 随着取样规模变大,样本的均值的均值的绝对值趋向总体均值。图形上表现为,正负区间震荡着接近总体均值
  • 随着取样规模变大,样本的均值的的std越来越小,趋向总体均值。图形上表现为,都是正数,但是数值越来越小,趋向0

import numpy as np
import pandas as pd
import scipy as sp
from matplotlib import pyplot as plt
import seaborn as sns
%precision 3

np.random.seed(1)
count1=999

#生成一个总体的正态分布,先不生成数量
population1=sp.stats.norm(loc=0,scale=1)
sample_mean_array1=np.zeros(count1)
sample_mean_std_array2=np.zeros(count1)


#下面展示的是每次取样/试验得到的 均值和std随着 取样数量的增加 的变化趋势
#这个 std是均值的std, 也就是在每个样本容量规模处,做多次试验(嵌套循环),所得到的std,
#而不是不同规模下的取样样本,得到的多个样本的均值的标准差,那个没啥意义!

sample_mean_array11=np.zeros(count1)
sample_mean_std_array21=np.zeros(count1)
sample_mean_mean_array20=np.zeros(count1)

for i in range(0,count1,1):
    #每次循环时,取1次数量,作为样本
    for j in range(0,10,1):
        array11=population1.rvs(size=10+i*10)
        sample_mean_array11[j]=np.mean(array11)
    sample_mean_std_array21[i]=np.std(sample_mean_array11)
    sample_mean_mean_array20[i]=np.mean(sample_mean_array11)

    
fig3=plt.figure(num=3,figsize=(5, 5))
plt.plot(sample_mean_mean_array20)
plt.title("随着抽样规模的变大,多次抽样的样本mean的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

    
    
fig4=plt.figure(num=4,figsize=(5, 5))
plt.plot(sample_mean_std_array21)
plt.title("随着抽样规模的变大,多次抽样的样本std的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

4 多次取样的均值的标准差 ,std(mean) 即 标准误差/标准误

4.1 多次抽样时,随着样本规模的增大,样本的均值的标准差std会一直减少!

  • 多次抽样时,随着样本规模的增大,样本的均值的均值会围绕总体均值上下浮动,趋向总体均值。
  • 多次抽样时,随着样本规模的增大,样本的均值的标准差会一直减少!

4.2 样本的均值的标准差std的学名:SE标准误/标准误差

  • 样本均值标准差的名字:标准误差/标准误
  • SE
  • standard error
  • 标准误/标准误差
  • 就是进行多次取样,所有样本均值的均值的标准差std

4.3 SE的理论计算公式

  • 样本均值标准差的理论值的公式
  • 其中δ是标准差 np.std
  • 而其中δ^2是方差 np.var
$$ 标准误差=δ/\sqrt(N)$$
$$ SE=δ/\sqrt(N)$$

$$ 标准误差=δ/\sqrt(N)$$
$$ SE=δ/\sqrt(N)$$

  • 从公式看,标准误差是随着样本数量的增加而单调减小的。

4.4 画出SE的图和多次取样的样本的均值的std对比

4.4.1 对应代码

import numpy as np
import pandas as pd
import scipy as sp
from matplotlib import pyplot as plt
import seaborn as sns
%precision 5

plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False 
plt.rcParams.update({'font.size': 6}) # 设置字体大小

np.random.seed(1)
count1=999

#生成一个总体的正态分布,先不生成数量
population1=sp.stats.norm(loc=0,scale=1)
sample_mean_array1=np.zeros(count1)
sample_mean_std_array2=np.zeros(count1)


#下面展示的是每次取样/试验得到的 均值和std随着 取样数量的增加 的变化趋势
#这个 std是均值的std, 也就是在每个样本容量规模处,做多次试验(嵌套循环),所得到的std,
#而不是不同规模下的取样样本,得到的多个样本的均值的标准差,那个没啥意义!

sample_mean_array11=np.zeros(count1)
sample_mean_mean_array20=np.zeros(count1)
sample_mean_std_array21=np.zeros(count1)
sample_mean_se_array22=np.zeros(count1)

for i in range(0,count1,1):
    #每次循环时,取1次数量,作为样本
    for j in range(0,10,1):
        array11=population1.rvs(size=10+i*10)
        sample_mean_array11[j]=np.mean(array11)
    sample_mean_mean_array20[i]=np.mean(sample_mean_array11)
    sample_mean_std_array21[i]=np.std(sample_mean_array11,ddof=0)
    # 用样本std计算SE
    sample_mean_se_array22[i]=sample_mean_std_array21[i]/np.sqrt(10+i*10)

fig3=plt.figure(num=3,figsize=(5, 5))
plt.plot(sample_mean_mean_array20)
plt.title("随着抽样规模的变大,多次抽样的样本均值mean的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

"""
fig4=plt.figure(num=4,figsize=(5, 5))
plt.plot(sample_mean_std_array21)
plt.title("随着抽样规模的变大,多次抽样的样本均值的标准差std的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)
"""

#根据SE的公式计算标准的SE的公式和对应曲线,对比上面 均值的std的实际值组成的曲线
#  错误   se=总体std/np.sqrt(n样本数量)
#  正确   se=样本std/np.sqrt(n样本数量)


# 下面试图把 std(mean) 和 se=std/sqrt(N) 弄在一起进行显示对比
fig4=plt.figure(num=4,figsize=(5, 5))
plt.plot(sample_mean_std_array21)
plt.plot(sample_mean_se_array22,linestyle="dotted")
plt.title("多次抽样的样本均值的标准差std的变化--VS---SE的理论值的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

#print(sample_mean_std_array21)
#print("对比实际的数组内容")
#print(sample_mean_se_array22)

 4.4.2 多次取样的样本均值的std 和 se的曲线对比

  • 上图是我自己画出来的
  • 下图是书上的,日,马场真哉,《用python动手学统计》
  • 我觉得书上的图不对,因为他的SE是用固定的总体STD=0.8算出来的。而SE应该用样本std作为分子,而不是总体std作为分子。

5 随着样本容量增大,多次抽样de标准差de→平均值和std的变化

5.1 一般情况下,样本的方差<=总体方差

  • 一般情况下,样本的方差<=总体方差
  • 因为,总体里包括各个极值,极大极小值,这些值对方差的贡献影响最大
  • 而样本里经常是部分数据,最大取值在极值范围内,所以样本方差<=总体方差

5.2 用样本方差直接去估计总体方差是有偏估计,但是可以通过/(n-1)获得无偏的方差估计。

  • 多次抽样的样本方差的均值,应该还是小于总体的方差,因为是有偏估计
  • 比如针对方差
  • Σ(xi-u)^2/n     用样本方差去直接估计总体方差
  • Σ(xi-u)^2/(n-1)  才是无偏估计

5.3 随着样本容量增大,样本std也是趋向总体的std

  • 随着样本容量的增加
  • 多次抽样测量
  • 样本均值的均值,从2个方向趋向总体均值,并且是无偏的,也就是系统误差ϵ=0
  • 样本均值的方差/std,从1个方向趋向总体均值,单调减小

  • 样本std的均值,从2个方向趋向总体均值,并且是有偏的,也就是系统误差ϵ>0
  • 样本std的均值,如果取ddof=1(就是/(n-1)),从2个方向趋向总体均值,并且是无偏的,也就是系统误差ϵ>0
  • 样本std的std,从1个方向趋向总体std,单调减小,说明方差/std总是单调减小

5.4 下面这个图可以看出,同样的样本容量下,方差的无偏估计的结果更接近总体的std=0.5

5.5 下面是详细的代码

import numpy as np
import pandas as pd
import scipy as sp
from matplotlib import pyplot as plt
import seaborn as sns
%precision 5

plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False 
plt.rcParams.update({'font.size': 6}) # 设置字体大小

np.random.seed(1)
count1=999

# 用这个看方差的变化,有偏方差等
#生成一个总体的正态分布,先不生成数量
population1=sp.stats.norm(loc=0,scale=0.5)

sample_mean_array10=np.zeros(count1)
sample_mean_array11=np.zeros(count1)

sample_mean_mean_array10=np.zeros(count1)
sample_mean_std_array11=np.zeros(count1)

sample_mean_mean_array20=np.zeros(count1)
sample_mean_std_array21=np.zeros(count1)
sample_mean_se_array22=np.zeros(count1)

print("下面看有偏方差随着样本数量增加的变化,也就是/n")
for k in np.arange(10,120,50):
    for i in range(0,count1,1):
        #每次循环时,取1次数量,作为样本
        array10=population1.rvs(size=k)
        sample_mean_array11[i]=np.std(array10,ddof=0)

    sample_std_mean=np.mean(sample_mean_array11)
    sample_std_std=np.std(sample_mean_array11,ddof=0)
    sample_std_se=sample_mean_std_array21[i]/np.sqrt(10)

    print(f"std的均值= {sample_std_mean}",end=",")
    print(f"std的std= {sample_std_std}",end=",")
    print(f"std的se= {sample_std_se}")

print("下面看无偏方差随着样本数量增加的变化,也就是/(n-1)")
for k in np.arange(10,120,50):
    for i in range(0,count1,1):
        #每次循环时,取1次数量,作为样本
        array10=population1.rvs(size=k)
        sample_mean_array11[i]=np.std(array10,ddof=1)

    sample_std_mean=np.mean(sample_mean_array11)
    sample_std_std=np.std(sample_mean_array11,ddof=1)
    sample_std_se=sample_mean_std_array21[i]/np.sqrt(10)

    print(f"std的均值= {sample_std_mean}",end=",")
    print(f"std的std= {sample_std_std}",end=",")
    print(f"std的se= {sample_std_se}")  
    
    

for i in range(0,count1,1):
    #每次循环时,取1次数量,作为样本
    for j in range(0,10,1):
        array11=population1.rvs(size=10+i*10)
        sample_mean_array11[j]=np.std(array11,ddof=0)   #这里可选ddof=0,或者ddof=1
    sample_mean_mean_array20[i]=np.mean(sample_mean_array11)
    sample_mean_std_array21[i]=np.std(sample_mean_array11,ddof=0)
    # 用样本std计算SE
    sample_mean_se_array22[i]=sample_mean_std_array21[i]/np.sqrt(10+i*10)

fig3=plt.figure(num=3,figsize=(5, 5))
plt.plot(sample_mean_mean_array20)
plt.title("随着抽样规模的变大,多次抽样的样本std的均值mean的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)

# 下面试图把 std(mean) 和 se=std/sqrt(N) 弄在一起进行显示对比
fig4=plt.figure(num=4,figsize=(5, 5))
plt.plot(sample_mean_std_array21)
plt.plot(sample_mean_se_array22,linestyle="dotted")
plt.title("多次抽样的样本std的标准差std的变化--VS---SE的理论值的变化",fontsize=16)
plt.xlabel("sample_size",fontsize=16)
plt.ylabel("sample_std",fontsize=16)


网站公告

今日签到

点亮在社区的每一天
去签到