numpy.linalg学习

矩阵和向量积

两个数组点积

1
numpy.dot(a, b, out=None)

a、b都是常量或一维数组,则返回标量

对于一维数组,其结果等于两向量的内积:设向量 $a=(x_1, y_1)$,向量$b=(x_2, y_2)$,结果等于$x_1x_2 + y_1y_2$

1
2
3
4
5
6
import numpy as np

r1 = np.dot(3, 4)
r2 = np.dot([1, 2, 3], [4, 5, 6])
print(r1) # 12
print(r2) # 32

a、b都是二维数组,相当于矩阵的乘法

矩阵乘法,第一个矩阵$A$的行数必须等于第二个矩阵$B$的列数;矩阵$A$乘以矩阵$B$得到的结果矩阵$C$,其第m行n列元素等于矩阵$A$的第m行元素乘以矩阵$B$第n列对应元素之和。

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np

a = np.array([[1, 2], [3, 4], [2, 5]])
b = np.array([[2, 3, 1], [4, 5, 2]])
c = np.dot(a, b)
print(c)

'''
[[10 13 5]
[22 29 11]
[24 31 12]]
'''

a、b都是N维,其结果等于a的最后一轴和b的倒数第二轴积之和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import numpy as np

a = np.array(range(12)).reshape(2, 3, 1, 2)
b = np.array(range(12)).reshape(3, 2, 2)
np.dot(a, b)
print(a)
print(b)
print(c)
print(c.shape)

'''
[[[[ 0 1]]
[[ 2 3]]
[[ 4 5]]]
[[[ 6 7]]
[[ 8 9]]
[[10 11]]]]

[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]]]

[[[[[ 2 3]
[ 6 7]
[ 10 11]]]
[[[ 6 11]
[ 26 31]
[ 46 51]]]
[[[ 10 19]
[ 46 55]
[ 82 91]]]]
[[[[ 14 27]
[ 66 79]
[118 131]]]
[[[ 18 35]
[ 86 103]
[154 171]]]
[[[ 22 43]
[106 127]
[190 211]]]]]

(2, 3, 1, 3, 2)
'''

两向量点积

1
numpy.vdot(a, b)

参数a、b都是高维数组

vdot处理多维数组和dot处理方式不同,不是执行矩阵乘积,只能执行向量点积,则需将数组先扁平化,然后再计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np

a = np.array([[1, 4], [5, 6]])
b = np.array([[4, 1], [2, 2]])
c = np.vdot(a, b)
print(c)
# a、b数组扁平化即将多维数组转换成一维数组,可以使用ravel函数处理
c = np.vdot(a.ravel(), b.ravel())
print(c)

'''
30
30
'''

参数a、b为复数

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np

a = np.array([1+2j, 3+4j])
b = np.array([5+6j, 7+8j])
c = np.vdot(a, b)
print(c)
c = np.vdot(b, a)
print(c)

'''
(70-8j)
(70+8j)
'''

通过上述结果可知:np.vdot(a,b)np.vdot(b,a)计算出来的结果刚好互为共轭复数关系(实部相同,虚部互为相反数),其计算结果为取vdot函数中的第一个参数的共轭复数与另外一个参数点积。

以np.vdot(a,b)计算为例:

第一步:计算a的共轭复数

1
c = np.array([1-2j, 3-4j])

第二步:计算c与b的点积

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np

a = np.array([1+2j, 3+4j])
b = np.array([5+6j, 7+8j])
c = np.array([1-2j, 3-4j])
d = np.array([5-6j, 7-8j])
np.dot(c, b)
np.dot(d, a)

'''
(70-8j)
(70+8j)
'''

求解方程与求逆矩阵

逆矩阵

1
numpy.linalg.inv(a)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
from numpy.linalg import inv

a = np.array([[1., 2.], [3., 4.]])
b = inv(a)
print(b)
c = np.dot(a, b)
print(c)
# 比较两数组: np.allclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)
e = np.allclose(c, np.eye(2))
print(e)

'''
[[-2. 1. ]
[ 1.5 -0.5]]

[[1.0000000e+00 0.0000000e+00]
[8.8817842e-16 1.0000000e+00]]

True
'''

知识点:矩阵与其逆矩阵点积等于同阶单位矩阵,求解逆矩阵的方法有待定系数法、伴随矩阵法、初等变换法

最小二乘法

1
numpy.linalg.lstsq(a, b, rcond=-1)

b为一维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
from numpy.linalg import lstsq

X = np.array([[1, 6, 2], [1, 8, 1], [1, 10, 0], [1, 14, 2], [1, 18, 0]])
Y = np.array([[7], [9], [13], [17.5], [18]])
z = np.linalg.lstsq(X, Y, rcond=None)
print(z)

'''
(array([[1.1875 ],
[1.01041667],
[0.39583333]]), array([8.22916667]), 3, array([26.97402951, 2.46027806, 0.59056212]))
'''

从上述结果可知:返回元组,元组中四个元素,第一元素表示所求的最小二乘解,第二个元素表示残差总和,第三个元素表示X矩阵秩,第四个元素表示Y的奇异值

b为多维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
from numpy.linalg import lstsq

X = np.array([[1, 6, 2], [1, 8, 1], [1, 10, 0], [1, 14, 2], [1, 18, 0]])
Y = np.array([[7, 8], [9, 7], [13, 10], [17.5, 16], [18, 17]])
z = np.linalg.lstsq(X, Y, rcond=None)
print(z)

'''
(array([[ 1.1875 , -1.125 ],
[ 1.01041667, 1.02083333],
[ 0.39583333, 1.29166667]]), array([8.22916667, 2.91666667]), 3, array([26.97402951, 2.46027806, 0.59056212]))
'''

通过上面两个结果对比分析:参数b维度增加,第一个、第二个元素数组维度也变化,其对应的第k列分别表示对b数组中第k列的最小二乘法求解、残差总和

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :