线性代数中最基本的数据类型是矩阵。矩阵由行和列组成。
图B-1给出了一个简单的矩阵样例。该矩阵由3行3列组成。行通常从上到下编号,而列则从左到右编号。第一行的值分别是9、9和77。类似地,第3列的值分别是77、18和10。在NumPy当中可以通过调用numpy.shape(myMat)
来得到给定矩阵myMat
的行列大小。上述调用返回的结果形式是(行数,列数)。
图B-1 一个简单的3x3矩阵,图中给出了行、列的方向
本书每一章都用到了向量,而向量是一个特殊的矩阵,其行或列数目为1。通常情况下,提到向量时不会特别说是行向量还是列向量。如果这样,则假设是列向量。图B-2左部给出了一个列向量,是一个3×1的矩阵。而在图B-2右部给出的是一个1×3的行向量。在矩阵的运算过程中跟踪矩阵的大小十分重要,比如矩阵乘法。
图B-2 左边给出了一个列向量,右边给出了一个行向量
矩阵的一个最基本的运算是转置,即按照对角线翻转矩阵。原来的行变成列、列变成行。图B-3给出了矩阵B的一个转置过程示意图。转置运算通过矩阵上标的一个大写的T
来表示。转置运算常用来对矩阵处理使之更加容易计算。
图B-3 矩阵的转置过程,转置后行变成列
可以用一个数字去加或者乘以矩阵,这相当于对矩阵的每个元素都独立进行加法或乘法运算。由于矩阵元素之间的相对值没有发生变化,而只有比例发生了变化,所以上述这类运算称为标量运算(scalar operation)。如果想对矩阵进行常数放缩变换或者加上一个常数偏移值,就可以使用矩阵标量乘法或加法运算。图B-4给出了标量乘法和加法的两个例子。
图B-4 矩阵上的标量运算,最后的结果是每个元素乘上或者加上某个标量
接下来看一些矩阵运算。如何对两个矩阵求和?首先,两个矩阵行列数必须要相同才能进行求和运算。矩阵求和相当于每个位置上对应元素求和。图B-5给出了一个例子。矩阵减法运算与此类似,只不过将刚才的加法变成减法即可。
图B-5 矩阵求和
一个更有趣的运算是矩阵乘法。两个矩阵相乘不像标量乘法那么简单。两个矩阵要相乘,前一个矩阵的列数必须要等于后一个矩阵的行数。例如,两个分别为3×4和4×1的矩阵可以相乘,但是3×4的矩阵不能和1×4的矩阵相乘。而3×4的矩阵和4×1的矩阵相乘会得到3×1的结果矩阵。有一种方法可以快速检查两个矩阵能否相乘以及结果矩阵大小,将它们的大小连在一起的写法 (3×4)(4×1)。由于中间的值相等,因此可以进行乘法运算。去掉中间的值之后,就可以得到结果矩阵的大小3×1。图B-6给出了一个矩阵乘法的例子。
图B-6 一个矩阵乘法的示意图,图中3x2矩阵乘以2x1矩阵得到一个3x1矩阵
本质上来说,图B-6中所做的是将3×2矩阵的每一行旋转之后与2×1矩阵的每一列对齐,然后计算对应元素的乘积并最终求和。矩阵相乘还可以看成是列的加权求和(参见图B-7)。
图B-7 矩阵乘法可以看成是列的加权求和
在上面第二种看法下,最终的结果虽然一样但是采用了不同的组织方式。将矩阵乘法看成是列加权求和对于某些算法很有用,比如矩阵相乘的MapReduce版本。一般来说,两个矩阵X和Y的乘法定义为:
如果对上述两种做法的一致性存疑,那么总是可以采用上式来对矩阵求积。
机器学习中的一个常用运算是对向量求内积(也称点积)。比如第6章支持向量机中就需要对向量进行内积计算。两个向量进行内积计算时,相应元素相乘然后求和得到最终向量。图B-8给出了一个示意图。
图B-8 两个向量的内积计算
通常来说,向量内积还有一层物理含义,比如某个向量沿着另一个向量的移动量。向量的内积可以用于计算两个向量的夹角余弦值。在任意支持矩阵乘法的程序中,可以通过X
的转置乘以Y
实现两个向量X
和Y
的内积计算。如果向量X
和Y
的长度都是m
,那么两个向量都可以看成m×1
的矩阵,因此XT
是1×m的矩阵,XT*Y
是1×1的矩阵。