分享

再见了 ! NumPy !

 InfoRich 2024-08-15 发布于上海

紧跟前沿AI技术

正文开始:

Image

NumPy 是 Python 生态系统中用于数据分析、机器学习和科学计算的核心工具包。它极大地简化了向量和矩阵的操作。许多重要的开发工具包,如 scikit-learn、SciPy、pandas 和 tensorflow,都建立在 NumPy 的基础上。掌握 NumPy 不仅有助于对数值数据进行切片和交叉分析,还能在处理和调试这些库时为你带来优势。

import numpy as np

创建数组

我们可以通过传递一个 Python 列表,使用 np.array() 方法来创建一个 NumPy 数组。。如下图,python创建了一个如右图所示的数组:

Image

在许多情况下,我们希望借助 NumPy 来初始化数组。NumPy 提供了一些便捷的方法,如 ones()、和 random.random()。我们只需要指定数组的大小即可,如图所示。

Image

一旦创建好数组后,我们就可以使用了了。

数组运算

我们首先创建两个 NumPy 数组:data数组和ones数组:

Image

将两个数组对应位置的元素相加,data + ones:

Image

这可以让我们不需要在代码中使用循环来计算这些。而且不只有加法,我们还可以以如下方式去计算:

Image

有时我们需要对数组和一个数字进行计算(也叫向量和标量的操作)。例如,当我们有一个以英里表示的距离数组,想将其转换为公里时(1 英里 = 1.60934 公里),可以这样操作:data * 1.6。

Image

可以看到 NumPy数组和数字 的乘法操作是对数组的每一个单元都和数字进行计算,这是称作 广播(broadcast)的一种机制,是非常有用的。

索引

们还可以像操作 Python 列表一样,对 NumPy 数组进行索引或切片操作。

Image

聚合

NumPy 还提供了聚合功能:

Image

除了min,maxsum, 还有mean可以获取平均值,prod可以获取所有元素相乘的结果等等。

多维

到目前为止,我们看到的示例都是一维向量。NumPy 的一个出色特点是,它可以将我们目前见到的所有功能扩展到任意维度。

创建矩阵

我们可以通过传递一个 Python 列表(多维列表),使用 NumPy 创建一个矩阵,如下图所示:

np.array([[1,2],[3,4]])
Image

我们还可以使用前面提到的方法(如 ones()、zeros() 和 random.random()),只需提供一个描述矩阵维度的元组,如下图:Image

矩阵运算

如果两个矩阵具有相同的行数和列数,我们可以使用运算符(+ - * /)对它们进行操作。Image

这些运算符还可以在不同尺寸的矩阵上使用,只要其中一个矩阵是一个一维矩阵(例如,只有一行或一列)。在这种情况下,NumPy 使用广播(broadcast)规则来进行计算。

Image

点积(Dot Product)

NumPy 提供了一个 dot() 方法来计算矩阵的点积。Image

在图片的底部,我已经标注了矩阵的维度信息,强调了在进行矩阵点乘时,相邻的维度必须相同(例如,1×3 的矩阵与 3×2 的矩阵相乘,前者的列维度与后者的行维度相同)。你可以想象是进行了如下的操作:

Image

矩阵索引

当我们使用矩阵的时候索引和切片功能将更加有用:

Image

矩阵聚合

与向量(数组)相同,可以对矩阵进行类似的聚合操作:

Image

而且不仅可以对矩阵中的所有值进行聚合,还能对行或列进行单独的聚合操作,使用axis参数进行指定(axis是轴的意思):

Image

置换和变形

当处理矩阵时一个共用功能就是矩阵的变换。比如当需要计算两个矩阵的点积的时候可能需要对齐矩阵相邻的维度(使矩阵能够进行点积运算)。NumPy 的数组有一个很方便的属性T可以获取矩阵的转置:

Image

在更高级的场合,你可能发现需要变换矩阵的维度。这在机器学习中时经常常见的,比如当一个特定的模型需要一个一个特定维度的矩阵,而你的数据集的输入数据维度不一样的时候。NumPy 的reshape()函数就变得有用了。你只需指定你需要的新的矩阵的维度即可。你还可以通过将维度指定为-1,NumPy 可以依据矩阵推断出正确的维度:

Image

更高维度

在更高的维度,前面提及的,NumPy 都可以做到。其中一个主要原因就是被称为ndarray(N-Dimensional Array)的数据结构。

Image

在大部分场合,处理一个新的维度只需要在 NumPy 的函数上参数上增加一个维度:

Image

需要记住的是,当你打印一个三维的 NumPy 数组时,输出的文本格式可能与这里展示的不同。NumPy 打印多维数组时,最后一个轴的元素打印得最快,而第一个轴的元素则最后打印。例如,np.ones((4, 3, 2)) 将会打印如下:

array([[[1., 1.],
        [1., 1.],
        [1., 1.]],

       [[1., 1.],
        [1., 1.],
        [1., 1.]],

       [[1., 1.],
        [1., 1.],
        [1., 1.]],

       [[1., 1.],
        [1., 1.],
        [1., 1.]]])

实际使用

现在我们来看一些 NumPy 如何帮助我们实现各种功能的例子。

公式

在矩阵和向量上的数学运算是 NumPy 的一个重要功能,这也是 NumPy 在 Python 科学计算领域中备受青睐的原因之一。例如,均方误差(MSE)公式在解决回归问题的有监督机器学习模型中扮演着关键角色。

Image

用 NumPy 来实现是一件轻而易举的事:

Image

NumPy 的优雅之处在于,它不关心 predictions 和 labels 向量的大小是 1 还是几百个值,只要它们的尺寸相同。我们可以通过以下四个步骤来逐步解析这段代码:

Image

predictionslabels向量都有3个值,也就是说n = 3, 计算完减法后,我们得到如下的公式:

Image

然后对这个向量求平方操作:

Image

现在,我们对三个数进行求和:

Image

error 中的值就是模型预测的质量

数据展示

考虑到所有可能需要处理和构建模型的数据类型(电子表格,图像,音频等)。很多是很适合用一个n维数组进行表示的。

电子表格
  • 电子表格可以看作一个二维矩阵,每个 sheet 页都包含它的变量。在 Python 中,最流行的工具之一是 pandas dataframe,这个工具包是基于 NumPy 构建的。
Image
音频和时间序列数据
  • 一个音频文件可以看作是一个一维数组,其中每个元素都是一个数字,表示一小段音频信号。对于 CD 质量的音频,每秒可能包含 44,100 个样本,每个样本的数值范围在 -32767 到 32768 之间。这意味着,如果你有一个持续 10 秒的 CD 质量的 WAVE 文件,你可以将其加载为一个长度为 10 * 44,100 = 441,000 的 NumPy 数组。如果你想提取音频的第一秒,只需将该文件加载到一个名为 audio 的 NumPy 数组中,并使用 audio[:44100] 来获取。

下面是一个音频文件的一个切片:

Image

时间序列的数据也是一样(比如, 随时间变化的股票价格 )

图像
  • 一张图像可以看作是一个像素矩阵,其维度就是高度 x 宽度。
    • 对于黑白图像,即灰度图,每个像素可以用一个数字来表示(通常在 0(黑色)到 255(白色)之间)。如果你想裁剪图像左上角 10 x 10 像素的部分,只需使用 NumPy 的 image[:10, :10] 函数即可获取。

下面是一个图片文件的切片:

Image

-如果是彩色图像,那么每个像素可以用3个数字来表示——分别代表红色、绿色和蓝色。在这种情况下,我们需要一个三维数组,因为每个元素只能存储一个数字。因此,一个彩色图像可以用一个维度为(高度 * 宽度 * 3)的 ndarray 来表示。

Image
语言

如果我们处理的是文本数据,情况会有所不同。为了将文本转换为数值表示,需要先构建一个词汇表(包含模型需要了解的所有唯一单词)并进行词嵌入(embedding)处理。

让我们看看用数字表示这个谚语的步骤:” Have the bards who preceded me left any theme unsung?”模型需要通过大量的文本训练,才能将这位诗人的诗句转换为数字表示。我们可以让模型处理一个小的数据集,并使用该数据集构建一个包含 71,290 个单词的词汇表:

Image

这个句子可以按照通用规则被分解成一系列词(token):

Image

然后,我们将这些词替换为词汇表中对应的单词ID:

Image

不过对于模型而言,这些单词ID本身并没有提供太多信息。因此,在将这些词传递给模型之前,需要先将她们替换为对应的词嵌入向量(本例中使用50维度的word2vec 词嵌入)

Image

可以看出这个 NumPy 数组有 [词嵌入维度 * 序列长度] 的维数。

在实践中可能有另外的情况,在此我用这种方式来表示。出于性能因素的考虑,深度学习模型倾向于保存批处理数据的第一个维度(因为如果并行地训练多个实例,模型可以训练得更快)。reshape()在这里就发挥了用武之地。比如像BERT这样的模型,他的输入希望是这种[批处理大小, 序列长度, 词嵌入维度]([ batch_size, sequence_length, embedding_size ]) 形状的。

Image

现在,这些就是一个模型可以处理并且使用的一个数值型卷积向量。我在上图中的其他行留了空白,但是他们实际是被填充用于训练(或者是预测)。

—  —

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多