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的元素得来的。
先看下面的矩阵乘法运算:
结果中:
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去看看。