如未作说明,下列方法均调用自linalg
矩阵分解 | cholesky ,qr ,奇异值分解svd |
求特征值 | eigvals ,共轭对称阵特征值eigvalsh(a[, UPLO]) |
特征值和 特征向量 |
eig ,共轭对称的特征值和向量eigh(a[, UPLO]) |
特征数字 | 范数norm ,迹trace |
条件数cond ,行列式det ,符号slogdet |
|
通过SVD方法求秩matrix_rank(M[, tol, hermitian]) |
|
解方程 | solve(a, b) ,张量方程tensorsolve(a, b[, axes]) |
线性矩阵方程的最小二乘解lstsq(a, b[, rcond]) |
|
求逆 | inv ,伪逆pinv ,张量逆tensorinv |
上述表格中所列出的均为经典概念或者经典算法,注入特征值、特征向量、范数等概念自然不必赘述。
有关矩阵分解的三种方法,在此做一个简略的解释,对于矩阵 M M M而言,如果可以分解为 Q R QR QR的形式,其中 Q Q Q为正交矩阵, R R R为上三角矩阵,则此种方法为QR分解;奇异值分解稍微复杂一点,假设 M M M可分解为 S V D SVD SVD,其中 S S S和 D D D分别是行数不相等的方阵, V V V则是对角阵,则这种分解方法为奇异值分解。
>>> import numpy as np
>>> M = np.random.rand(4,4)
>>> print(M)
[[0.32116742 0.8394773 0.36011495 0.4544155 ]
[0.39427835 0.17813826 0.49553932 0.9707901 ]
[0.12197008 0.67413918 0.84044815 0.47201928]
[0.86152707 0.57731393 0.57027362 0.91170088]]
>>> q,r = np.linalg.qr(M)
>>> print(q)
[[-0.31867407 0.65970523 0.55548743 -0.39328051]
[-0.39121741 -0.21491979 -0.49634831 -0.74457825]
[-0.12102318 0.67771442 -0.6574708 0.30624941]
[-0.85483868 -0.24351932 0.1131557 0.44401009]]
>>> print(r)
[[-1.00782415 -0.91230718 -0.89782856 -1.36108287]
[ 0. 0.83180887 0.56177969 0.18901576]
[ 0. 0. -0.53396118 -0.43660267]
[ 0. 0. 0. -0.35218194]]
# 下面是SVD分解
>>> s,v,d = np.linalg.svd(M)
>>> s
array([[-0.42332819, -0.46593393, -0.50222164, -0.59285094],
[-0.46502685, 0.54456992, 0.48233038, -0.50453051],
[-0.46055779, -0.60153282, 0.56922965, 0.31940945],
[-0.62644217, 0.35285612, -0.4371595 , 0.54032798]])
>>> v
array([2.32219426, 0.70718892, 0.46245349, 0.20757881])
>>> d
array([[-0.39410157, -0.47814575, -0.48540482, -0.61680042],
[ 0.41812791, -0.70128404, -0.2860149 , 0.50156278],
[-0.60183471, -0.44181835, 0.62117299, 0.23819245],
[ 0.55466024, -0.29047183, 0.54472172, -0.55790356]])
若 M M M可被分解为 L L ∗ LL^* LL∗,其中 L L L为下三角矩阵, L ∗ L^* L∗为其共轭,那么这种分解方式即为cholesky
分解,需要注意,并非所有矩阵均有cholesky
分解,只有对称的正定矩阵才可以。
>>> np.linalg.cholesky(M)
Traceback (most recent call last):
File "" , line 1, in <module>
File "<__array_function__ internals>", line 5, in cholesky
File "D:\CS\Anaconda3\lib\site-packages\numpy\linalg\linalg.py", line 763, in cholesky
r = gufunc(a, signature=signature, extobj=extobj)
File "D:\CS\Anaconda3\lib\site-packages\numpy\linalg\linalg.py", line 91, in _raise_linalgerror_nonposdef
raise LinAlgError("Matrix is not positive definite")
numpy.linalg.LinAlgError: Matrix is not positive definite
>>> L = np.linalg.cholesky(M@M.T)
>>> L
array([[ 1.06960127, 0. , 0. , 0. ],
[ 0.83747617, 0.82086233, 0. , 0. ],
[ 1.04922106, 0.20002046, 0.50756537, 0. ],
[ 1.29112734, 0.64431997, -0.15694312, 0.35375359]])
lstsq(a,b)
用于求解类似于a@x=b
中的x
,其中,a
为 M × N M\times N M×N的矩阵;则当b
为 M M M行的向量时,刚好相当于求解线性方程组。其本质是最小二乘法,对于 A x = b Ax=b Ax=b这样的方程组,如果 A A A是满秩仿真,那么可以表示为 x = A − 1 b x=A^{-1}b x=A−1b,否则可以表示为 x = ( A T A ) − 1 A T b x=(A^{T}A)^{-1}A^{T}b x=(ATA)−1ATb。
当b
为 M × K M\times K M×K的矩阵时,则对每一列,都会计算一组x
。
其返回值共有4个,分别是拟合得到的x
、拟合误差、矩阵a
的秩、以及矩阵a
的单值形式。
>>> x = np.arange(4)
>>> y = M@x
>>> xhat = np.linalg.lstsq(M,y)
>>> print(xhat[0])
[-2.46640454e-15 1.00000000e+00 2.00000000e+00 3.00000000e+00]