本文转自『读芯术』
来源:Pexels
在 Python 的生态环境中, NumPy 包是数据分析、机器学习和科学计算的主力军。它大大简化了向量和矩阵的操作及处理过程。一些领先的Python 包都依靠 NumPy 作为其基础架构中最基本的部分(例如scikit-learn、SciPy、pandas 和 tensorflow)。除了对数值数据进行分片和分块处理,在库中处理和调试高级用例时,掌握 NumPy 操作也能展现其优势。
此文将介绍一些主要的 NumPy 使用方法,以及在机器学习模型中应用数据前,NumPy 显示不同类别数据(表格、图像、文本等)的方式。
创建数组
通过向NumPy 传递Python列表并使用“ np.array()”,就可以创建一个NumPy 数组(又名:强大的 ndarray)。在此案例中,Python创建的数组如下所示:
许多情况下,需要NumPy对数组的值进行初始化。NumPy为这些情况提供了 ones()、 zeros()、 random.random() 等方法。只需传递要让NumPy生成的元素数量即可。
创建完数组,就可以开始通过有趣的方式处理它们了。
数组的运算
建立两个NumPy数组以展现其实用性。将其称作“data”和“ones”:
将每列的值相加,键入“ data + ones”:
笔者在开始学这一工具时觉得精神振奋,因为这种抽象概念可以避免在循环中对此类计算进行编程。它能够让人在更高的层面上思考问题。
还有其他方式:
许多情况下,要在一个数组和单个数字之间执行操作(也可称作向量和标量之间的操作)。假设目前数组代表了以英里为单位的距离,现在要将单位转换成公里。假设 data * 1.6:
索引
通过所有能够对Python列表切片(slice)的方式,能够对NumPy数组进行索引和切片:
聚合
NumPy的优势还在于提供聚合函数:
除了min、max和 sum这些函数,用mean可以计算平均值,用prod可以得到所有元素相乘的结果,用std可以得到标准差,以及其他函数等等。
更多维度
以上所有实例都是在一个维度中处理向量的。而NumPy的关键优势之一就是它能够将目前实例中的所有内容应用到任一数量的维度中。
创建矩阵
以下列形状传递一系列Python列表,使NumPy创建矩阵对其进行表示:
只要用一个元组描述所创建的矩阵的维度,就还是可以使用之前提及的方法(ones()、 zeros()和 random.random()):
矩阵的运算
如果两个矩阵大小相同,则可以使用运算符(+-*/)对矩阵进行相加或相乘。NumPy对每一矩阵进行相同的操作:
只有当不同的维度为1时(例如,矩阵只有一行或一列),才能在不同大小的矩阵上进行运算。在这种情况下,NumPy会对这一操作使用其broadcast机制:
点积
有关运算,在矩阵乘法情况下使用点积是矩阵关键区别。NumPy给每一个矩阵都提供了一个dot() 方法,因此可以用这个方法对其他矩阵执行点积操作:
在该图下方,笔者添加了矩阵维度,以强调两个矩阵在其与对方匹配的一侧必须具有相同维度。将操作可视化,就会如下所示:
矩阵索引
在处理矩阵时,索引分片操作会更有用:
矩阵聚合
聚合矩阵的方式跟聚合向量相同:
不仅可以在矩阵中聚合所有值,还可以通过使用axis参数跨行跨列进行聚合:
转置与重塑
旋转矩阵是处理矩阵的常见需求之一。情况常常是这样的——需要取两个矩阵的点积,并且需要对齐共用维度。NumPy数组有一个名为T的便捷属性,能够对矩阵进行转置:
在更高级的实操案例中,有可能需要切换特定矩阵的维度。在机器学习应用中,当某一特定模型要求输入具有特定形状,而这一形状又不同于数据集中的形状时,就常常会出现上述需求。此时NumPy的 reshape() 方法就会大显神通。向维度传递-1,接着NumPy就会基于矩阵推出正确维度:
更多维度
NumPy可以在任意维度完成已提及的一切。其中心数据架构叫做ndarray (n维数组)。
处理新维度有很多途径,但大多都是给NumPy的函数参数添加逗号:
注意:请记住,当在打印三维NumPy数组时,文本输出的数组与此处显示不同。NumPy要求打印n维数组时,最后一个轴的转速要最快,而第一个最慢。这就意味着会如下呈现:
实际应用
以下为实用示例,均得益于NumPy的帮助。
公式
执行对矩阵和向量有效的数学公式是NumPy的关键应用之一。这也是NumPy成为科学领域 Python领域团宠的原因。例如,想想主要用于跟踪回归问题的监督式机器学习的均方误差公式:
在NumPy中执行这一公式轻而易举:
其优势在于,在NumPy 中, predictions和labels包含的值只有一个还是有一千个,这无关紧要(只要都是同样大小)。随着一行代码中四项操作一步步推进,可以通过实例来看一下:
Predictions和labels都包含了三个值,也就意味着n的值为3。进行减法运算后,值会如下呈现:
接着就平方向量中的值:
对三个值进行求和:
最终,对预测来说,得到的是错误值;而对模型质量来说,得到的是分数。
数据表达
·  首先想清楚所有需要处理和建模的数据类型(表格、图像、音频等)。很多都适用于在n维数组中数据表达:
表格
·  值的表格是个二维矩阵。表格中的每一张工作簿都会有其自己的变量。在Python中,对于这些表格最受欢迎的数据抽取方式是使用pandasdataframe,它实际上也是使用了NumPy,并在此基础上进行构建。
音频和时间序列
·  一个音频文件是一组样本的一维数组。每个样本都是表示音频信号的一小个数据块。CD音质的音频每秒会有441,000个样本,每个样本都是-32767到32768之间的整数。也就是说,如果有一个十秒CD音质的WAVE文件,就可以以10 * 44,100 = 441,000样本的长度将其置于NumPy数组中。如果想要抽取音频的第一秒,只要将文件至于音频的NumPy数组中,得到音频[:44100]。
这里呈现的是音频文件的一个片段:
时间序列数据也是同理(比如,股票随时间变动的价格)。
图像
·  一个图像是个大小像素的矩阵(高x宽)
如果图像是黑白的(又称灰度图),每个像素都可以用单个数字表示(一般在0(黑)和255(白)之间)。如果想要获取图像最顶端的10x10的部分,只需用NumPy获取image[:10,:10]即可。
这里呈现的是图像文件的一部分:
如果图像为彩色的,那么每个像素都用三个数字表示——各有红、绿、蓝三色的值。在这种情况下就需要第三个维度了(因为每一格只能包含一个数字)。因此,一幅彩色图像要用维度的多维数组表示(高x宽x3)。
语言
如果要处理文本,情况会困难一些。用数字表示文本要求建立词汇表(模型已知的所有独有单词列表)这一步和嵌入步骤。一起来看看用数字表示这一句(翻译过来的)古话吧:
“Have the bards who preceded me left any themeunsung?”
在用数字表示这名尚武诗人略显焦虑的词汇之前,需要让模型观看大量文本。可以将一小个数据集提供给模型,并用这个来建立(含71290个单词的)词汇表:
接着,就可以将这个句子拆分到一个符号数组中(基于通用规则的单词或单词部分):
然后用词汇表中的id代替对应的单词:
这些id仍没有给模型提供包含足够信息的值。因此在给模型输入单词序列之前,需要用嵌入向量(在该情况下,是50维度的word2vec 嵌入))替换符号/单词:
可以看到,这个NumPy数组的维度是 [embedding_dimensionx sequence_length]。实际操作中情况可能不同,但在此处为了视觉上的一致性,就这样表示。为了完成效果,深度学习模型倾向于保留批量大小的第一维度(因为如果多个实例平行训练,那么模型训练将更高效)。显然这是个证明reshape()相当有用的实例。例如像BERT这样的模型,会希望其输入形状是这样的:[batch_size,sequence_length, embedding_size]。
现在,这是模型能够进行处理并执行有效操作的数字体积了。空了一些行,最好用其他一些要训练的(或要预测的)模型实例填补它们。
(事实证明,相比其他引发焦虑的诗人的词句,这个诗人的用词在本实例中,似乎更为不朽。生而为奴,Antarah的英勇无畏和对语言的需求为其获得了自由,以及神话般的地位——他的诗是前伊斯兰阿拉伯国家悬在克尔白神殿上的七首诗之一)。
注:本文已获作者授权
编译组:鲍歆祎
相关链接:
https://jalammar.github.io/visual-numpy/
推荐阅读
继续阅读