numpy中提供了不少数学中矩阵的运算、构造函数。

闭上眼睛想一想,发现其中常用的也就是那么几个:cos, sin, mean, dot,
max,min, outer,argsort,ones,zeros,arrange,reshape,fft………等。

想了半天,可以也不超过30个左右常用函数。

但是numpy的确博大精深:查看文档发现有大概586个方法或属性!

今天,我就记录一下numpy中,矩阵运算tile与kron的用处之一吧。

确切的讲,是谈论的在向量化运算方面的用处。

记得高等代数中有过关于矩阵初等行变换与初等列变换的介绍。

比如:A*B

如果矩阵A满秩,并且矩阵A可以由一系列初等行变换或列变换操作都得到的化,那么在A*B的乘法操作中,A可以看做是操作矩阵,这一系列的初等行变换作用在矩阵B上就得到了它们的积。

现在,我们跳出来这种宏观的思考方式。为什么说是宏观?我想,因为初等行列变换的对象都是矩阵。反之,微观的思考方式就是把着眼点放在矩阵元素上。看看A*B的结果是怎样变换矩阵B的元素得来的。

先看下面的矩阵乘法运算:

[1 42536]2 0 1=[5 14]

结果中:
5 = 1*2 + 2*0 + 3* 1
14 = 4*2 + 5*0 + 6*1
如果我们把[2 0 1]之前的系数都换成1,那就是对向量的求和操作。
3 = 1*2 + 1*0 + 1* 1
对,tile与kron的作用就是在求和操作。
但是并不是仅仅限于这样简单的求和, 这样简单的求和我们直接sum了。

比如在机器学习与数据挖掘中,我们通常会遇到大量的特征,在处理这些特征的时候,我们可能会按某个规律选取一些特征后进行求和等运算。这时候numpy的tile与kron就有了用武之地。

比如,一个特征有240个维度。但是由于种种原因,我想降维。把240个元素分为20组,每组中元素间的索引值都间隔20,每组元素数量为12个,然后对每组求和。

如果我把B作为Feature那么她的A是什么样呢?

由简入繁,第一组的索引可以为:0,20,40,60,80……….

第二组的索引可以为:1,21,41,61,81………..

以此类推,那么A的第一行应该为1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0…………….

第二行应为:0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ……….

不难发现,A其实是12个秩为20的单位矩阵并排!

这便是tile的用途: A = np.tile(np.eye(20), 12) .

那么,kron的用处呢?

如果我改一下需求,同样想降维,但是方式不同。想要把240个元素分为12
个组,索引从零开始,每20个为一组。

这样的话,矩阵A的第一行为1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1………………………

第二行为:000000000000000000001111111111111111111100000………..

类推可得,A = np.kron(np.eye(12), np.ones((1,20)))
这便是向量化的作用,很复杂的事情一段代码就能表示清楚。
如果还不理解克罗内克积的话,可以到维基百科kronecker product去看看。