理解有放回和无放回抽样 (Python)
文章目录
- 一、说明
- 二、放回抽样模型概念
- 2.1 如何实现放回抽样
- 2.2 使用 NumPy 进行替换抽样
- 2.3 使用 Pandas 进行替换抽样
- 三、基本统计原理
- 四、什么是无放回抽样
- 4.1 使用 NumPy 进行无放回抽样
- 4.1 数据科学中不重复抽样的例子
- 五、结论
一、说明
概率的模型很重要,比如有放回抽样和无放回抽样,这两个模型都拥有很强实用型,绝不能说说就算了,而是用程序如何实现的问题。
本教程将深入探讨有放回和无放回抽样,并涉及这些概念在数据科学中的一些常见应用。与往常一样,本教程中使用的代码可在我的GitHub上找到。让我们开始吧!
二、放回抽样模型概念
放回抽样可以定义为允许抽样单元出现多次的随机抽样。放回抽样包括
- 从总体(如一罐珠子或一个数据集)中随机抽取的采样单元(如一颗玻璃珠或一行数据)。
- 记录抽取了哪个采样单元。
- 将抽样单位返回给总体。
在抽取下一个抽样单元之前将抽样单元返回总体的原因是为了确保在未来的抽样中,选择任何特定抽样单位的概率保持不变. 在整个数据科学中,有许多可替换抽样的应用。其中许多应用使用引导法,这是一种统计过程,它对数据集使用可替换抽样来创建许多模拟样本。使用可替换抽样创建的数据集(因此它们具有与原始数据集相同数量的样本)称为引导数据集。引导数据用于机器学习算法(如袋装树和随机森林)以及统计方法(如引导置信区间)等。
2.1 如何实现放回抽样
采用替换程序进行采样。图片由Michael Galarnyk提供。
放回抽样可以定义为允许抽样单元出现多次的随机抽样。放回抽样包括
从总体(如一罐珠子或一个数据集)中随机抽取的采样单元(如一颗玻璃珠或一行数据)。
记录抽取了哪个采样单元。
将抽样单位返回给总体。
假设您有一罐 12 颗不同的玻璃珠,如上图所示。如果您从罐子中放回原处取样,随机选择其中任何一颗玻璃珠的概率是 1/12。选择一颗珠子后,将其放回罐子中,这样在未来的取样中选择 12 颗珠子中的任意一颗的概率就不会改变(1/12)。这意味着如果您重复该过程,完全有可能随机取出相同的珠子(在这种情况下为 1/12 的概率)。
本节的剩余部分将介绍如何使用 Python 库 NumPy 和 Pandas 进行放回抽样,并将介绍相关概念,例如引导数据集以及在进行放回抽样以创建引导数据集时应预期多少个重复样本。
2.2 使用 NumPy 进行替换抽样
为了更好地理解放回抽样,我们现在用 Python 模拟这个过程。下面的代码加载 NumPy 并从包含从 0 到 11 的唯一数字的 NumPy 数组中放回抽样 12 次。
import numpy as np
np.random.seed(3)
# a parameter: generate a list of unique random numbers (from 0 to 11)
# size parameter: how many samples we want (12)
# replace = True: sample with replacement
np.random.choice(a=12, size=12, replace=True)
结果如下:
注意有多个重复的数字。
在上面的代码中我们之所以采样 12 次,是因为我们从中采样的原始罐子(数据集)中有 12 个珠子(采样单元)。我们选择的 12 个弹珠现在是引导数据集的一部分,引导数据集是通过有放回采样创建的数据集,其值数量与原始数据集相同。
2.3 使用 Pandas 进行替换抽样
由于大多数人对从罐子中取样珠子的应用不感兴趣,因此有必要提及采样单元也可以是整行数据之类的东西。下面的代码使用 Kaggle 的 King County 数据集创建了一个引导数据集,其中包含 2014 年 5 月至 2015 年 5 月期间 King County(包括西雅图)的房屋售价。您可以从Kaggle下载数据集或从我的GitHub加载它。
# Import libraries
import numpy as np
import pandas as pd
# Load dataset
url = 'https://raw.githubusercontent.com/mGalarnyk/Tutorial_Data/master/King_County/kingCountyHouseData.csv'
df = pd.read_csv(url)
# Selecting columns I am interested in
columns= ['bedrooms','bathrooms','sqft_living','sqft_lot','floors','price']
df = df.loc[:, columns]
# Only want to use 15 rows of the dataset for illustrative purposes.
df = df.head(15)
# Notice how we have 3 rows with the index label 8
df.sample(n = 15, replace = True, random_state=2)
请注意,有多个重复的行。
当通过替换抽样来创建引导数据集时,您应该预期有多少个重复样本/行?
自举数据通常用于袋装树和随机森林模型(这可能是袋装树或随机森林的图表,具体取决于决策树如何适应数据)。图片由Michael Galarnyk提供。
需要注意的是,当您使用替换抽样来生成数据时,您可能会得到重复的样本/行。实际上,平均引导数据集包含约 63.2% 的原始行。这意味着对于原始数据集中的任何特定行数据,36.8% 的引导数据集将不包含它。
本小节简要介绍如何从统计上得出这些数字,以及如何通过使用 Python 库 pandas 进行实验来接近这些数字。
三、基本统计原理
让我们首先推导一下,对于原始数据集中的任何特定行数据,36.8%的引导数据集将不包含该行。
假设原始数据集中有 N 行数据。如果要创建引导数据集,则需要进行 N 次替换抽样。
对于单个可替换样本,特定行数据不是从数据集中随机抽取的概率是
由于自举数据集是通过从大小为 N 的数据集中采样 N 次获得的,因此我们需要采样 N 次才能找到给定自举数据集中未选择特定行的概率。
如果我们当 N 趋向无穷大时取极限,我们会发现概率是 0.368。
原始数据集中任何特定行的数据出现在引导数据集中的概率仅为 1 — 𝑒^-1 = .63213。请注意,在现实生活中,数据集越大(N 越大),接近这些数字的可能性就越大。
使用 pandas
下面的代码使用 pandas 显示引导数据集将包含约 63.2% 的原始行。
# Import libraries
import numpy as np
import pandas as pd
# Load dataset
url = 'https://raw.githubusercontent.com/mGalarnyk/Tutorial_Data/master/King_County/kingCountyHouseData.csv'
df = pd.read_csv(url)
# Selecting columns I am interested in
columns= ['bedrooms','bathrooms','sqft_living','sqft_lot','floors','price']
df = df.loc[:, columns]
"""
Generate Bootstrapped Dataset (dataset generated with sample with replacement which has the same number of values as original dataset)
% of original rows will vary depending on random_state
"""
bootstrappedDataset = df.sample(frac = 1, replace = True, random_state = 2)
在下面的 bootstrap 样本中,请注意它包含约 63.2% 的原始样本/行。这是因为样本量很大(len(df) 为 21613)。这也意味着每个 bootstrap 数据集将不包含原始数据集中约 36.8% 的行。
长度(df)
len(bootstrappedDataset.index.unique())/ len(df)
四、什么是无放回抽样
无放回抽样。图片由Michael Galarnyk提供。
无放回抽样可以定义为不允许抽样单元出现多次的随机抽样。现在让我们看一个简单的例子来了解无放回抽样的工作原理。
假设您有一罐 12 颗独特的玻璃珠,如上图所示。如果您从罐中不放回原处取样,则随机选择任何 1 颗玻璃珠的概率为 1/12。选择一颗珠子后,不会将其放回罐中,因此在未来的取样中选中剩余 11 颗珠子的概率现在是 (1/11)。这意味着每多抽取一个样本,罐中的珠子就会越来越少,直到最终没有珠子可供取样(12 次取样后)。
4.1 使用 NumPy 进行无放回抽样
为了巩固这些知识,我们现在用 Python 模拟这个过程。下面的代码加载 NumPy 并从包含从 0 到 11 的唯一数字的 NumPy 数组中不重复地采样 12 次
import numpy as np
np.random.seed(3)
# a parameter: generate a list of unique random numbers (from 0 to 11)
# size parameter: how many samples we want (12)
# replace = False: sample without replacement
np.random.choice(a=12, size=12, replace=False)
注意没有重复的数字。
请注意,如果您尝试使用不放回抽样生成比原始样本(本例中为 12)更长的样本,您将收到错误。回到珠子罐的例子,您无法抽取比罐子中更多的珠子。
np.random.seed(3)
np.random.choice(a=12,size=20,replace=False)
您无法(不放回)取样比罐子中更多的珠子。图片由Michael Galarnyk提供。
4.1 数据科学中不重复抽样的例子
不重复抽样在整个数据科学中都有使用。一种非常常见的用途是在模型验证程序中,例如训练测试拆分和交叉验证。简而言之,这些程序中的每一个都允许您模拟机器学习模型在新/未见过的数据上的表现。
下图显示了训练测试拆分过程,该过程包括将数据集拆分为两部分:训练集和测试集。这包括随机抽样(不重复)约 75%(您可以调整此比例)的行并将其放入训练集,将剩余的 25% 放入测试集。请注意,“特征”和“目标”中的颜色表示特定训练测试拆分的数据将去往何处(“X_train”、“X_test”、“y_train”、“y_test”)。
训练测试分割程序。
如果您想了解有关训练测试分割的更多信息,可以查看我的博客文章《了解训练测试分割》。
五、结论
理解有放回和无放回抽样的概念在统计学和数据科学中非常重要。自举数据用于机器学习算法(如袋装树和随机森林)以及统计方法(如自举置信区间)等。