【小白学机器学习39】如何用numpy生成总体,生成样本samples

发布于:2024-11-29 ⋅ 阅读:(24) ⋅ 点赞:(0)

目录

1 目的:研究 样本和总体之间的关系

2 先生成1个理论总体

2.0  下面是关于这一步的完整代码

2.1 一般情况下,我们先生成一个符合正态分布的总体

2.1.1 设置总体 ,或者说生成一个总体

2.2 为什么一定要是一个符合正态分布的总体?

2.2.1 事实上,一般我们很难得到自然界的总体,或者说根本不可能。

2.2.2 我们可以设置一些人造的总体和样本,也是符合样本和总体的关系

2.2.3 那为什么是一定正态分布?

2.2.4 假设为正态分布的好处

2.3 这个总体合适吗?是个正态分布吗?

2.3.1 用图形验证

2.3.2 用假设检验验证是否符合正态分布

2.3.3  如何确定h0假设?

2.4 从总体中取得样本

2.4.1 用np.random.choice(总体, size=, replace=) 从总体中取得样本

2.4.2 取样1次 sample,或者N次取样 samples(相当于做了n次取样!)

2.4.3 重复取样问题 replace=False = 不放回抽样

2.4.4 样本的容量问题

3 改进一个数据量更多的总体,然后从中取得样本容量稍大的样本

3.0 这一段的完整代码

3.1  总体population的改动

3.2  samples 样本的改动

3.3 额外看了samples 样本数组的均值


1 目的:研究 样本和总体之间的关系

  • 总体:population
  • 样本:sample:
  • 目标:下面想做一个关于样本和总体的试验,也就是从总体里取出1个样本,多个样本,验证样本的参数和总体的参数之间的关系。

2 先生成1个理论总体

2.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(99)   #设置确定的随机种子,保证每次随机的结果都相同

# 先生成一个正态分布的随机数组
#fig1=plt.figure(num=1,figsize=(3,3))
plt.subplot(2,3,1)

array1=np.random.normal(loc=0, scale=1, size=10)
print(array1)
print()

plt.plot(array1)

#fig3=plt.figure(num=3,figsize=(3,3))
plt.subplot(2,3,2)
plt.hist(array1)


##
# 假设data是你需要验证的数组
data =array1
# 使用scipy.stats.kstest来进行K-S检验,对data进行正态分布的验证
ks_statistic, p_value = sp.stats.kstest(data, 'norm')
# 设定显著性水平α,一般取0.05
alpha = 0.05
# 根据p值判断是否接受原假设(数据来自正态分布)
if p_value < alpha:
    print("数据不符合正态分布")
else:
    print("数据符合正态分布")  

array2=np.random.choice(array1,size=5,replace=False)
print(array2)
print()


#fig2=plt.figure(num=2,figsize=(3, 3))  #新开一个画布
plt.subplot(2,3,3)
for i in range(1,10):
    array3=np.random.choice(array1,size=5,replace=True)
    print(array3)
    plt.plot(array3)

2.1 一般情况下,我们先生成一个符合正态分布的总体

2.1.1 设置总体 ,或者说生成一个总体

  • 先用np.random.normal() 生成一个符合正态分布的数组array
  • 但是这个数组,是否符合正态分布呢?

2.2 为什么一定要是一个符合正态分布的总体?

2.2.1 事实上,一般我们很难得到自然界的总体,或者说根本不可能。

  • 理论上,关于自然界的各种总体我们是不可知,至少是不可全知道的
  • 简单的理由:
  1. 样本数量太大
  2. 样本数量多的无限
  3. 认识全部样本的成本很高很高
  4. 等等
  • 深层次的理由:
  1. 哲学的原因,kant, 我们只能认识物自体/存在的现象,但无法认识物自体本身。

2.2.2 我们可以设置一些人造的总体和样本,也是符合样本和总体的关系

  • 人造的总体数据,从中的取样samples
  • 也是符合自然总体和样本之间的关系的
  • 我们虽然无法直接认识自然总体和样本之间的关系的。
  • 但是我们可以直接认识  人造的总体数据 →取样samples 之间的关系,进而更深的理解自然总体和样本之间的关系。

2.2.3 那为什么是一定正态分布?

  • 首先也不一定是正态分布
  • 也可能是
  1. 正态分布,
  2. 幂律分布
  3. 等等
  • 即使不是正态分布,也要假设总体服从某种分布!

2.2.4 假设为正态分布的好处

  • 正态分布分布很广泛,一般情况下:一个总体服从正态分布的概率最高
  • 当然有些明确的情况下,符合其他分布的概率更好
  • 总体符合正态分布时,其残差也会符合正态分布,后面更好处理

2.3 这个总体合适吗?是个正态分布吗?

  • 先用np.random.normal() 生成一个符合正态分布的数组array
  • 但是这个数组,是否符合正态分布呢?
  • 理论上是符合的,因为我们就是用np.random.normal() 生成的
  • 但是因为2个原因
  1. 因为我们是随机取的,有可能随机性比较大,取得有点偏
  2. 因为我们取得10个数据模拟正态数据,数据量也会比较少

2.3.1 用图形验证

  • 如果用 plt.plot()  看是否正态分布不那么直观,如果在均值附近波动则是
  • 如果用 plt.hist()  频度图更适合看出是否正态分布
  • 虽然这个样本总体才10个数,但是是用np.random.normal() 生成的数组,确实是符合正态分布的。但是用频度图或者散点图来看,虽然像。但是也不是特别明显/典型。直接的原因还是数据量太少吧。

2.3.2 用假设检验验证是否符合正态分布

  • 下面的代码中
  •  array1=np.random.normal()
  • 可以使用scipy.stats.kstest来进行K-S检验,对data进行正态分布的验证
  • sp.stats.kstest(data, 'norm') 会返回2个结果:ks_statistic, p_value
  • 尤其是 p_value 就是检验的概率,需要和显著度进行α比较

判断标准

  • h0假设,这个数组符合正态分布
  • 如果p_value() 小于α,就认为是小概率事件,就拒绝h0假设,认为data 不符合正态分布。
  • 如果p_value() 大于α,就不是小概率事件,就接受h0假设,认为data 符合正态分布。
# 假设data是你需要验证的数组
data =array1
# 使用scipy.stats.kstest来进行K-S检验,对data进行正态分布的验证
ks_statistic, p_value = sp.stats.kstest(data, 'norm')
# 设定显著性水平α,一般取0.05
alpha = 0.05
# 根据p值判断是否接受原假设(数据来自正态分布)
if p_value < alpha:
    print("数据不符合正态分布")
else:
    print("数据符合正态分布")  

array2=np.random.choice(array1,size=5,replace=False)
print(array2)
print()

2.3.3  如何确定h0假设?

sp.stats.kstest(data, 'norm')

关于分布的假设检验,H0的假设一定是服从这个分布,h1假设一定是不符合。

为什么呢?

  • 我感觉是因为h0假设属于这个分布才好往下推导和计算,
  • 因为假设检验本身就是h1不好验证(h1=不是正态,有可能是各种分布,更复杂)
  • 其否命题h0(是正态,就一种确定的分布,而且这种分布只需要知道均值和方差) 更好验证。
  • 因此,这种有关数学和分布的假设检验,
  1. h0假设:往往是那个好计算的假设,比如符合正态分布,两数相等等这种作为h0假设

  2. h1假设,往往是那些不好计算的,比如,不是XX分布但是什么分布呢?

为什么不是看弃真错误是否更严重呢

  • 因为第1类错误=弃真错误=第1类错误,也就是我们设置的显著度α=弃真概率
  • 因为我们是从 设置显著度α 为出发点,那么我们肯定认为 弃真错误概率要越小越好,只是因为第1类错误和2类错误有此消彼长关系,所以也不能追求 弃真概率α无限小,在一个可接受的范围内如5%,1%这以下就可以了。
  • 弃真错误也就是h0 是对的但是我们错误的判断h0是假的,为什么会这样呢?
  • 因为我们本次(假设h0为真时,往下推导)检验出来的概率很小,是个小概率事件,不太可能发生,小于显著度α,因为我们顶着α的弃真错误的可能性,认为h0为假。
  • 所以理论上即使我们这次检验出来的概率小于α,可以拒绝h0, 还是有α的理论上的可能性,我们犯了弃真错误。
  • 所以,包含社会价值的假设检验里h0 往往是那个 弃真错误需要尽量低的作为h0
  1. h0 假设是假币,
  2. h0 假设新药无效,
  3. h0 假设传染口罩是阳性

2.4 从总体中取得样本

2.4.1 用np.random.choice(总体, size=, replace=) 从总体中取得样本

  • array3=np.random.choice(array1,size=5,replace=True)

2.4.2 取样1次 sample,或者N次取样 samples(相当于做了n次取样!)

取样1次

array3=np.random.choice(array1,size=5,replace=True)

取样n次

for i in range(1,10):
    array3=np.random.choice(array1,size=5,replace=True)

2.4.3 重复取样问题 replace=False = 不放回抽样

  • replace=False = 不放回抽样
  • replace=True= 放回抽样
  • 一般来说,
  1. 主要看,抽样是否对总体有影响
  2. 如果 样本数量/总体数量= 比值很小,那么 放回抽样 约= 不放回抽样,差别不大
  3. 如果样本数量/总体数量= 比值较大,那么不放回抽样,总体会随着抽样的进行,总体逐渐变小,从而剩下的数量里,抽样的概率实际上在发生变化!
  4. 这也就是抽样影响了总体,这种不放回抽样会对应 超几何分布的道理!而不是二项分布或正态分布

2.4.4 样本的容量问题

  • 这段代码里,样本数量=5
  • 用折线图看不出啥,如果用hist看频率还能好点
  • 样本容量尽量大,样本才会更接近总体


 

3 改进一个数据量更多的总体,然后从中取得样本容量稍大的样本

3.0 这一段的完整代码

代码,主要是基于对第2部分的修改

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(99)   #设置确定的随机种子,保证每次随机的结果都相同
# 
# 先生成一个正态分布的随机数组

array1=np.random.normal(loc=0, scale=1, size=100)
#print(array1)
print()
plt.subplot(2,2,1)
plt.plot(array1)

#用频度图hist才能更容易看出是否正态分布
plt.subplot(2,2,2)
plt.hist(array1)

##
# 假设data是你需要验证的数组
data =array1
# 使用scipy.stats.kstest来进行K-S检验,对data进行正态分布的验证
ks_statistic, p_value = sp.stats.kstest(data, 'norm')
# 设定显著性水平α,一般取0.05
alpha = 0.05
# 根据p值判断是否接受原假设(数据来自正态分布)
if p_value < alpha:
    print("数据不符合正态分布")
else:
    print("数据符合正态分布")    
    
array2=np.random.choice(array1,size=5,replace=False)
print(array2)
print()

#新开一个画布, plt.plot显示效果不好,但是plt.hist有点正态的感觉,毕竟多样本多曲线也就是频率图的叠加
array100=np.array([])


plt.subplot(2,2,3)
for i in range(1,15):
    array3=np.random.choice(array1,size=10,replace=True)
    mean3=np.mean(array3)
    print(mean3,end=",")
    #np.append(array100,mean3)
    array100=np.append(array100,mean3)
    print(array3)
    plt.hist(array3)
 
print(array100)
plt.subplot(2,2,4)
plt.hist(array100)

3.1  总体population的改动

  • 用 np.random.norm() 生成的 总体数量到了100
  • 这样无论是 plot 还是hist 都明显看到符合正态分布
  • 用ktest也是检验OK

3.2  samples 样本的改动

  • np.random.choice(array1,size=10,replace=True)
  • 用np.random.choice() 生成的样本数量马,从5修改为了10
  • 明显看到,用hist图,统计多个样本的频度,也更像正态分布

3.3 额外看了samples 样本数组的均值

  • 虽然只有15个样本 (重复取样15次)
  • 但是样本数量的均值明的hist有了点正态分布的样子
  • 如果直接改参数,做100次试验(重复取样100次),这个图更像,下面是对比


网站公告

今日签到

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