![021f14d5454196d5e58d310cce9a819b.png](https://i-blog.csdnimg.cn/blog_migrate/aa227fc2e82ad7533f115705af5df582.jpeg)
乱序函数
在机器学习中为了防止模型学习到样本顺序这些影响泛化能力的特征,通常在模型进行训练之前打乱样本顺序。Numpy模块提供了permutation(x)
和shuffle(x)
两个乱序函数,permutation(x)
和shuffle(x)
两个函数都在 Numpy 的 random 模块下,因此要使用这两个乱序函数需要先导入 random 模块。
numpy.random.permutation(x)
permutation(x)
函数由传入的 x 参数的类型决定功能:
- 当 x 设置为标量时,返回指定范围值为 [0, x) 的乱序数组;
- 当 x 设置为数组(本文的所有数组指的都是ndarray数组)、列表以及元组时,则对数组、列表以及元组中的元素值进行乱序排列;
无论实现哪种功能,permutation(x)
函数最终返回的都是乱序后的数组。
import numpy as np
a = np.random.permutation(5) # x 为标量
b = np.random.permutation(np.arange(5)) # x 为数组
b2 = np.random.permutation([1, 2, 3, 4, 5]) # x 为列表
b3 = np.random.permutation((1, 2, 3, 4, 5)) # x 为元组
>>> print(f"the type of a:{type(a)}, a:{a}")
the type of a:<class 'numpy.ndarray'>, a:[1 4 2 0 3]
>>> print(f"the type of b:{type(b)}, b:{b}")
the type of b:<class 'numpy.ndarray'>, b:[0 1 3 4 2]
>>> print(f"the type of b2:{type(b2)}, b2:{b2}")
the type of b2:<class 'numpy.ndarray'>, b2:[1 3 5 4 2]
>>> print(f"the type of b3:{type(b3)}, b3:{b3}")
the type of b3:<class 'numpy.ndarray'>, b3:[3 1 4 2 5]
当 x 为标量时只能返回范围值为 [0, x) 乱序的一维数组,**这是因为传入 x 为标量,相当于对numpy.arange(x)
数组进行乱序,因此返回的只能是一维数组。**但是如果传入的 x 为数组、列表以及元组时,我们可以指定数组、列表以及元组的维度,无论几个维度的数组、列表以及元组,permulation(x)
函数最终只对第一个维度进行乱序。
import numpy as np
b = np.arange(6).reshape(3, 2) # 原始的二维数组
# 使用乱序函数
b2 = np.random.permutation(b) # x 为二维数组
b3 = np.random.permutation(b.tolist()) # x 为二维列表, 通过 tolist 函数将数组转换列表
b4 = np.random.permutation(tuple(b.tolist())) # x 为二维元组(通常不会使用), 使用 tuple 函数将列表转换为元组
>>> print(b)
[[0 1]
[2 3]
[4 5]]
>>> print(b2)
[[4 5]
[2 3]
[0 1]]
>>> print(b3)
[[4 5]
[2 3]
[0 1]]
>>> print(b4)
[[0 1]
[2 3]
[4 5]]
这里以数组为例(列表和元组类似),对于二维数组:
- 第一个维度为
axis0
,表示沿着行方向; - 第二个维度为
axis1
,表示沿着列方向;
permulation(x)
函数对第一个维度进行乱序,也就是axis0
的行方向。假设现在原始二维数组为b
,乱序后的二维数组为b2
,permulation(x)
函数是如何沿着第一个维度进行乱序呢?
![ee5cefbcb62e6e4ca339a87e9f7c3852.png](https://i-blog.csdnimg.cn/blog_migrate/7cd3dc92bdfe116a19ee8bf5f4d5d2ef.jpeg)
沿着第一个维度进行乱序,沿着行方向进行乱序,我们将每一行都看成一个整体,每一个整体用相同颜色表示,不同整体用不同颜色进行区分。对第一个维度进行乱序,相当于对这些不同颜色的整体进行乱序。
此时原始的二维数组b = array([[0, 1], [2, 3], [4, 5]])
,是一个 3 行 4 列的二维数组,将每一行看成是一个整体,可以分成[0, 1]
, [2, 3]
和[4, 5]
三个整体,对其进行乱序相当于对这三个整体进行乱序,最终的乱序结果为b2 = array([[4, 5], [2, 3], [0, 1]])
。(因为乱序是随机的,有可能得到不同的乱序结果)
random.shuffle(x)
shuffle(x)
函数中的参数 x 只能是数组或者列表(不能是元组)。shuffle(x)
函数并不返回乱序后的数组。
import numpy as np
a = np.arange(5) # 数组
>>> print(a) # 乱序前的 a 数组
[0 1 2 3 4]
a2 = np.random.shuffle(a)
>>> print(a) # 乱序后的 a 数组
[4 3 1 0 2]
>>> print(a2) # shuffle 函数不返回乱序后的数组
None
b = [0, 1, 2, 3, 4]
>>> print(b) # 乱序前的 b 列表
[0, 1, 2, 3, 4]
b2 = np.random.shuffle(b)
>>> print(b) # 乱序后的 b 列表
[0, 3, 4, 2, 1]
>>> print(b2) # shuffle 函数不返回乱序后的数组
None
上面的例子使用的都是一维数组或者一维列表,**同样,我们可以指定数组和列表的维度,shuffle(x)
函数和permutation(x)
函数一样,无论几个维度的数组和列表,最终只对第一个维度进行乱序。**关于shuffle(x)
函数对高维数组和列表的乱序处理这里不再赘述。
总结
下面通过一个表格对permutation(x)
和shuffle(x)
两个乱序函数进行一个简单的总结。
![ab0b7ce135a898b32649674ee3e7b970.png](https://i-blog.csdnimg.cn/blog_migrate/192e5d7ed698039d4efc314fb5ecb15b.png)