“numpy”是 python 生态系统中数据分析,机器学习和科学计算的主力。它极大地简化了向量和矩阵的操作和处理。python 的一些主要软件包依赖于 numpy 作为其基础架构的基础部分(例如 scikit-learn,SciPy,pandas 和 tensorflow,pytorch)。除了对数字数据进行切片和切块的能力之外,在使用这些库中的高级用例进行处理和调试时,掌握 “numpy” 会提供极大优势。
本次推文,将介绍使用 “numpy” 的主要方法,以及在我们为机器学习模型提供服务之前它如何表示不同类型的数据(表格,图像,文本等)。
我们可以通过将 python 列表传递给它并使用np.array()
来创建一个 “numpy” 数组。在这种情况下,python 创建了数组:
通常情况下,我们希望 “numpy” 为初始化数组的值。“numpy”为这些情况提供了诸如 ones(),zeros()和 random.random()之类的方法。我们只是传递它们要生成的元素数量:
一旦创建了数组,就可以开始以有趣的方式操作它们。
让我们创建两个 “numpy” 数组来展示它们的用处。
在位置上添加它们(即添加每行的值)就像键入 data + ones 一样简单:
开始学习这些工具时,会发现这样的抽象使学习者不必在循环中编写这样的计算。 这是一个很棒的抽象,可以站在更高层次上思考问题。
通常情况下,我们希望在数组和单个数字之间执行操作(我们也可以将其称为向量和标量之间的操作)。 比如说,数组表示以英里为单位的距离,我们希望将其转换为公里数。简单地说 data * 1.6:
我们可以通过切片 python 列表的所有方式对 “numpy” 数组进行索引和切片:
“numpy” 额外提供的其它好处是 “聚合功能”:
除了最小值,最大值和总和之外,还可以得到其它的东西,比如得到平均值,得到所有元素相乘的结果,标准差,以及更多。
所有例子都在一个维度上处理向量。“numpy” 的一个关键部分是它能够将目前所看到的所有内容应用到任意数量的维度。
我们可以传递以下形状的 python 列表,让 “numpy” 创建一个矩阵来表示它们:
np.array([[1,2],[3,4]])
我们也可以使用上面提到的相同方法(ones(),zeros()和 random.random()),只要给它们一个元组来描述我们正在创建的矩阵的维度:
如果两个矩阵的大小相同,可以使用算术运算符(+ - * /)来添加和乘以矩阵。“numpy” 将这些作为位置操作处理:
只有当不同维度为 1 时(例如矩阵只有一列或一行),才可以在不同大小的矩阵上进行算术运算,在这种情况下,“numpy” 将其规则用于该操作:
与算术相关的一个关键区别是使用点积的矩阵乘法。“numpy” 为每个矩阵提供了一个 dot()方法,我们可以用它来执行与其他矩阵的点积运算:
如图所示,底部添加了矩阵尺寸,以强调两个矩阵在它们彼此面对的一侧必须具有相同的尺寸。此操作可视化为如下所示:
当操作矩阵时,索引和切片操作变得更加有用:
可以像聚合向量一样聚合矩阵:
不仅可以聚合矩阵中的所有值,还可以使用 axis 参数在行或列之间进行聚合:
处理矩阵时的一个共同需求是需要旋转矩阵。当我们需要采用两个矩阵的点积并需要对齐它们共享的维度时,通常就是这种情况。“numpy” 数组有一个方便的属性叫做 T 来获得矩阵的转置:
在更高级的用例中,也许会发现需要切换某个矩阵的维度。在机器学习应用程序中通常就是这种情况,其中某个模型期望输入的某个形状与您的数据集不同。在这些情况下,NumPy 的 reshape()方法很有用。只需将矩阵所需的新尺寸传递给它即可。可以为维度传递 - 1,“numpy” 可以根据矩阵推断出正确的维度:
“numpy” 可以完成我们在任何维度上提到的所有内容。其中心数据结构称为 ndarray(N 维数组)。
在很多方面,处理新维度只是在 “numpy” 函数的参数中添加逗号:
实现适用于矩阵和向量的数学公式是考虑 “numpy” 的关键用例。例如,考虑平均误差公式,它是监督机器学习模型处理回归问题的核心:
在 “numpy” 中实现这一点是轻而易举的:
这样做的好处是,“numpy” 并不关心预测和标签是否包含一个或一千个值(只要它们的大小相同)。我们可以通过一个示例逐步执行该代码行中的四个操作:
预测和标签向量都包含三个值。这意味着 n 的值为 3。执行减法后,最终得到如下值:
然后可以对矢量中的值进行平方:
最后总结这些值:
这导致该预测的误差值和模型质量的分数。
想想你需要紧缩和构建模型所需的所有数据类型(电子表格,图像,音频等等)。其中很多都非常适合在 n 维数组中表示:
电子表格或值表是二维矩阵。电子表格中的每个工作表都可以是自己的变量。python 中最受欢迎的抽象是 pandas 数据帧,它实际上使用 “numpy” 并在其上构建。
音频文件是一个一维的样本数组。每个样本都是一个数字,代表音频信号的一小部分。CD 质量音频每秒可能有 44100 个采样,每个采样都是介于 - 65535 和 65536 之间的整数。也就是说,如果有一个 10 秒的 CD 质量波形文件,可以将其加载到一个长度为 10*44100=441000 个样本的 “numpy” 数组中。想提取第一秒钟的音频吗?只需将文件加载到一个我们称之为音频的 numpy 数组中,然后获取音频[:44100]。
下面是音频文件的一个片段:
时间序列数据也是如此(例如,股票价格随时间变化)。
图像是像素大小(高度 x 宽度)的矩阵。
如果图像是黑白的(即灰度),每个像素可以用一个数字表示(通常在 0(黑色)和 255(白色)之间)。要裁剪图像的左上角 10 x 10 像素部分吗?只需告诉 numpy 获取图像[:10,:10]。
下面是一个图像文件的切片:
如果图像是彩色的,那么每个像素由三个数字表示——红色、绿色和蓝色各一个值。在这种情况下,我们需要第三个维度(因为每个单元格只能包含一个数字)。因此,彩色图像由一个一维数组来表示:(高 x 宽 x3)。
文本的数字表示需要一个构建词汇表的步骤和一个嵌入步骤。演示一下用数字来代表这句话(翻译)的步骤:
“在我之前的吟游诗人有没有留下任何主题?”
一个模型需要看大量的文本,然后才能用数字表示这位战士诗人焦虑的话语。我们可以继续让它处理一个小的数据集,并使用它来构建一个词汇表(71290 个单词):
然后,可以将句子分解为一组标记(基于通用规则的单词或单词部分):
然后,用词汇表中的 ID 替换每个单词:
ID 仍然不能为模型提供太多的信息价值。因此,在向模型提供一个单词序列之前,需要将标记 / 单词替换为它们的嵌入(本例中为 50 维 Word2Vec 嵌入):
可以看到 numpy 数组具有维度[嵌入维度 x 序列长度]。实际上,这是另一种方式,但为了视觉上的一致性,用这种方式呈现它。出于性能原因,深度学习模型倾向于保留批量大小的第一个维度(因为如果并行训练多个示例,模型可以更快地进行训练)。这是一个很明显的例子,其中 reforme()变得非常有用。例如,像 bert 这样的模型期望其输入的形状为:【批处理大小、序列长度、嵌入大小】。
现在这是一个数字卷,模型可以处理它并用它做有用的事情。将其他行留空,但它们将被其他示例填满,以供模型训练(或预测)。
https://www.yuque.com/7125messi/haagtd/ug6wav