10.3 随机抽样与洗牌
NumPy随机抽样与洗牌教程:从np.random.choice到机器学习数据划分
本教程详细讲解NumPy中的随机抽样方法,包括简单随机抽样np.random.choice、加权抽样、分层抽样,以及数组洗牌shuffle和permutation的使用,最后探讨抽样在机器学习数据划分中的应用,适合Python数据分析新手快速掌握。
NumPy随机抽样与洗牌教程
引言
NumPy是Python中用于科学计算的核心库,特别擅长处理数组操作。随机抽样和洗牌在数据分析、模拟实验和机器学习中至关重要。本教程将引导你从基础开始,逐步掌握NumPy中的随机抽样和洗牌功能。
1. 简单随机抽样(np.random.choice)
np.random.choice()是NumPy中实现简单随机抽样的主要函数。它可以从给定数组或序列中随机抽取元素。
基本语法
import numpy as np
# 从列表或数组中随机抽取单个元素
result = np.random.choice([1, 2, 3, 4, 5])
print(result) # 输出可能为2、3等随机值
参数详解
- a:输入数组或整数。如果是整数n,则从0到n-1中抽取。
- size:输出形状,可以是整数或元组,定义抽取样本的数量。默认None表示抽取单个样本。
- replace:布尔值,指定是否允许重复抽样。默认为True(有放回抽样)。
- p:可选数组,指定每个元素的抽取概率,用于加权抽样。
示例代码
# 从1到10中随机抽取3个不重复的数字
samples = np.random.choice(10, size=3, replace=False)
print(samples) # 如 [3, 7, 1]
# 有放回抽样
samples_with_replacement = np.random.choice(['A', 'B', 'C'], size=5, replace=True)
print(samples_with_replacement) # 如 ['B', 'A', 'C', 'A', 'B']
2. 加权抽样与分层抽样
加权抽样
加权抽样允许根据指定概率抽取元素,这在模拟或统计中很有用。使用np.random.choice()的p参数实现。
示例代码
# 定义元素和对应概率
elements = ['Red', 'Green', 'Blue']
probabilities = [0.5, 0.3, 0.2] # Red有50%概率被抽取
# 执行加权抽样
weighted_sample = np.random.choice(elements, size=10, p=probabilities)
print(weighted_sample) # 输出可能包含更多'Red'
分层抽样
分层抽样将总体分成不同层次(如类别),然后从每层中随机抽取样本。NumPy中没有直接函数,但可以结合循环和np.random.choice()实现。
示例代码
假设有一个数据集,按标签分层:
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
sample_size_per_stratum = 1
samples = []
for stratum in data.values():
samples.append(np.random.choice(stratum, size=sample_size_per_stratum, replace=False))
print(samples) # 如 [2, 5, 8]
3. 数组洗牌(shuffle()和permutation())
洗牌用于随机重新排列数组顺序,常用于数据预处理。NumPy提供两种方法:np.random.shuffle()和np.random.permutation()。
np.random.shuffle()
- 原地修改数组,不返回新数组。
- 适用于一维数组或多维数组的第一个轴。
示例代码
arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr)
print(arr) # 如 [3, 1, 5, 2, 4]
np.random.permutation()
- 返回一个新的随机排列数组,不修改原数组。
- 如果输入是整数n,返回0到n-1的随机排列。
示例代码
# 洗牌并返回新数组
new_arr = np.random.permutation(arr)
print(new_arr) # 如 [2, 4, 1, 5, 3]
# 从0到4的随机排列
perm = np.random.permutation(5)
print(perm) # 如 [3, 0, 4, 1, 2]
比较
shuffle()修改原数组,适合需要就地操作的情况。permutation()返回新数组,适合需要保留原数据的情况。
4. 抽样在机器学习中的应用(数据划分)
在机器学习中,抽样常用于将数据集划分为训练集、验证集和测试集,以评估模型性能。
常见方法
- 随机划分:使用洗牌后分割。
- 分层划分:保持类别比例,常用于分类问题。
示例代码:使用NumPy实现训练-测试集划分
# 假设有一个数据集X和标签y
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([0, 1, 0, 1, 0])
# 设置随机种子以确保可复现性
np.random.seed(42)
# 生成随机索引排列
indices = np.random.permutation(len(X))
# 划分比例:80%训练,20%测试
train_size = int(0.8 * len(X))
train_indices = indices[:train_size]
test_indices = indices[train_size:]
X_train, X_test = X[train_indices], X[test_indices]
y_train, y_test = y[train_indices], y[test_indices]
print("训练集大小:", X_train.shape) # 如 (4, 2)
print("测试集大小:", X_test.shape) # 如 (1, 2)
分层抽样划分示例
使用sklearn库的train_test_split结合NumPy可以实现,但NumPy原生方法如下:
# 简化示例:手动分层抽样
# 假设y有类别0和1
unique_classes = np.unique(y)
train_indices_list = []
test_indices_list = []
for cls in unique_classes:
class_indices = np.where(y == cls)[0]
np.random.shuffle(class_indices)
split_idx = int(0.8 * len(class_indices))
train_indices_list.extend(class_indices[:split_idx])
test_indices_list.extend(class_indices[split_idx:])
X_train_stratified = X[train_indices_list]
y_train_stratified = y[train_indices_list]
print("分层训练集大小:", X_train_stratified.shape)
总结
本教程覆盖了NumPy中随机抽样与洗牌的核心功能:从简单随机抽样np.random.choice(),到加权和分层抽样,再到数组洗牌shuffle()和permutation(),最后应用于机器学习的数据划分。通过示例代码,你可以快速上手这些技术,提升数据分析和建模效率。记得在真实项目中设置随机种子以确保结果可复现。
进一步学习建议:探索NumPy的random模块其他函数,如np.random.rand()用于生成随机数,或结合Pandas进行更复杂的数据处理。