Python---NumPy万字总结【此篇文章内容难度较大,线性代数模块】(3)

NumPy的应用(3)
向量
向量(vector)也叫矢量,是一个同时具有大小和方向,且满足平行四边形法则的几何对象。与向量相对的概念叫标量或数量,标量只有大小,绝大多数情况下没有方向。我们通常用带箭头的线段来表示向量,在平面直角坐标系中的向量如下图所示。需要注意的是,向量是表达大小和方向的量,并没有规定起点和终点,所以相同的向量可以画在任意位置,例如下图中 w \boldsymbol{w} w v \boldsymbol{v} v两个向量并没有什么区别。
在这里插入图片描述

向量有很多种代数表示法,对于二维空间的向量,下面几种写法都是可以的。 a = ⟨ a 1 , a 2 ⟩ = ( a 1 , a 2 ) = ( a 1 a 2 ) = [ a 1 a 2 ] \boldsymbol{a} = \langle a_1, a_2 \rangle = (a_1, a_2) = \begin{pmatrix} a_1 \\ a_2 \end{pmatrix} = \begin{bmatrix} a_1 \\ a_2 \end{bmatrix} a=a1,a2=(a1,a2)=(a1a2)=[a1a2] 向量的大小称为向量的模,它是一个标量,对于二维空间的向量,模可以通过下面的公式计算(高中知识啦)。 ∣ a ∣ = a 1 2 + a 2 2 \lvert \boldsymbol{a} \rvert = \sqrt{a_{1}^{2} + a_{2}^{2}} a=a12+a22 注意,这里的 ∣ a ∣ \lvert \boldsymbol{a} \rvert a并不是绝对值。上面的写法和概念也可以推广到 n n n维空间,我们通常用 R n \boldsymbol{R^n} Rn表示 n n n维空间,我们刚才说的二维空间可以记为 R 2 \boldsymbol{R^2} R2,三维空间可以记为 R 3 \boldsymbol{R^3} R3。虽然生活在三维空间的我们很难想象四维空间、五维空间是什么样子,但是这并不影响我们此内容。

向量的加法
相同维度的向量可以相加得到一个新的向量,运算的方法是将向量的每个分量相加,如下所示。 u = [ u 1 u 2 ⋮ u n ] , v = [ v 1 v 2 ⋮ v n ] , u + v = [ u 1 + v 1 u 2 + v 2 ⋮ u n + v n ] \boldsymbol{u} = \begin{bmatrix} u_1 \\ u_2 \\ \vdots \\ u_n \end{bmatrix}, \quad \boldsymbol{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix}, \quad \boldsymbol{u} + \boldsymbol{v} = \begin{bmatrix} u_1 + v_1 \\ u_2 + v_2 \\ \vdots \\ u_n + v_n \end{bmatrix} u= u1u2un ,v= v1v2vn ,u+v= u1+v1u2+v2un+vn 向量的加法满足“平行四边形法则”,即两个向量 u \boldsymbol{u} u v \boldsymbol{v} v构成了平行四边形的两条邻边,相加的结果是平行四边形的对角线,如下图所示。
在这里插入图片描述

向量的数乘
一个向量 v \boldsymbol{v} v可以和一个标量 k k k相乘,运算的方法是将向量中的每个分量与该标量相乘即可,如下所示。 v = [ v 1 v 2 ⋮ v n ] , k ⋅ v = [ k ⋅ v 1 k ⋅ v 2 ⋮ k ⋅ v n ] \boldsymbol{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix}, \quad k \cdot \boldsymbol{v} = \begin{bmatrix} k \cdot v_1 \\ k \cdot v_2 \\ \vdots \\ k \cdot v_n \end{bmatrix} v= v1v2vn ,kv= kv1kv2kvn 我们可以用 NumPy 的数组来表示向量,向量的加法可以通过两个数组的加法来实现,向量的数乘可以通过数组和标量的乘法来实现。

向量的点积
点积(dot product)是两个向量之间最为重要的运算之一,运算的方法是将两个向量对应分量的乘积求和,所以点积的结果是一个标量,其几何意义是两个向量的模乘以二者夹角的余弦如下所示。 u = [ u 1 u 2 ⋮ u n ] , v = [ v 1 v 2 ⋮ v n ] u ⋅ v = ∑ i = 1 n u i v i = ∣ u ∣ ∣ v ∣ c o s θ \boldsymbol{u} = \begin{bmatrix} u_1 \\ u_2 \\ \vdots \\ u_n \end{bmatrix}, \quad \boldsymbol{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix} \quad \\ \boldsymbol{u} \cdot \boldsymbol{v} = \sum_{i=1}^{n}{u_iv_i} = \lvert \boldsymbol{u} \rvert \lvert \boldsymbol{v} \rvert cos\theta u= u1u2un ,v= v1v2vn uv=i=1nuivi=uvcosθ 假如我们用3维向量来表示用户对喜剧片、言情片和动作片这三类电影的偏好,我们用1到5的数字来表示喜欢的程度,其中5表示非常喜欢,4表示比较喜欢,3表示无感,2表示比较反感,1表示特别反感。那么,下面的向量表示用户非常喜欢喜剧片,特别反感言情片,对动作片不喜欢也不反感。 u = ( 5 1 3 ) \boldsymbol{u} = \begin{pmatrix} 5 \\ 1 \\ 3 \end{pmatrix} u= 513 现在有两部电影上映了,一部属于言情喜剧片,一部属于喜剧动作片,我们把两部电影也通过3维向量的方式进行表示,如下所示。 m 1 = ( 4 5 1 ) , m 2 = ( 5 1 5 ) \boldsymbol{m_1} = \begin{pmatrix} 4 \\ 5 \\ 1 \end{pmatrix}, \quad \boldsymbol{m_2} = \begin{pmatrix} 5 \\ 1 \\ 5 \end{pmatrix} m1= 451 ,m2= 515 如果现在我们需要向刚才的用户推荐一部电影,我们应该给他推荐哪一部呢?我们可以将代表用户的向量 u \boldsymbol{u} u和代表电影的向量 m 1 \boldsymbol{m_1} m1 m 2 \boldsymbol{m_2} m2分别进行点积运算,再除以向量的模长,得到向量夹角的余弦值,余弦值越接近1,说明向量的夹角越接近0度,也就是两个向量的相似度越高。很显然,我们应该向用户推荐跟他观影喜好相似度更高的电影。 c o s θ 1 = u ⋅ m 1 ∣ u ∣ ∣ m 1 ∣ ≈ 4 × 5 + 5 × 1 + 3 × 1 5.92 × 6.48 ≈ 0.73 c o s θ 2 = u ⋅ m 2 ∣ u ∣ ∣ m 2 ∣ ≈ 5 × 5 + 1 × 1 + 3 × 5 5.92 × 7.14 ≈ 0.97 cos\theta_1 = \frac{\boldsymbol{u} \cdot \boldsymbol{m1}}{|\boldsymbol{u}||\boldsymbol{m1}|} \approx \frac{4 \times 5 + 5 \times 1 + 3 \times 1}{5.92 \times 6.48} \approx 0.73 \\ cos\theta_2 = \frac{\boldsymbol{u} \cdot \boldsymbol{m2}}{|\boldsymbol{u}||\boldsymbol{m2}|} \approx \frac{5 \times 5 + 1 \times 1 + 3 \times 5}{5.92 \times 7.14} \approx 0.97 cosθ1=u∣∣m1um15.92×6.484×5+5×1+3×10.73cosθ2=u∣∣m2um25.92×7.145×5+1×1+3×50.97 在这里,我们可能会思考,向量 m 2 \boldsymbol{m_2} m2代表的电影肉眼可见跟用户是更加匹配的。的确,对于一个三维向量我们凭借直觉也能够给出正确的答案,但是对于一个 n n n维向量,当 n n n的值非常大时,你还有信心凭借肉眼的观察和本能的直觉给出准确的答案吗?向量的点积可以通过dot函数来计算,而向量的模长可以通过 NumPy 的linalg模块中的norm函数来计算,代码如下所示。

u = np.array([5, 1, 3])
m1 = np.array([4, 5, 1])
m2 = np.array([5, 1, 5])
print(np.dot(u, m1) / (np.linalg.norm(u) * np.linalg.norm(m1)))  # 0.7302967433402214
print(np.dot(u, m2) / (np.linalg.norm(u) * np.linalg.norm(m2)))  # 0.9704311900788593

向量的叉积
在二维空间,两个向量的叉积是这样定义的: A = ( a 1 a 2 ) , B = ( b 1 b 2 ) A × B = ∣ a 1 a 2 b 1 b 2 ∣ = a 1 b 2 − a 2 b 1 \boldsymbol{A} = \begin{pmatrix} a_{1} \\ a_{2} \end{pmatrix}, \quad \boldsymbol{B} = \begin{pmatrix} b_{1} \\ b_{2} \end{pmatrix} \\ \boldsymbol{A} \times \boldsymbol{B} = \begin{vmatrix} a_{1} \quad a_{2} \\ b_{1} \quad b_{2} \end{vmatrix} = a_{1}b_{2} - a_{2}b_{1} A=(a1a2),B=(b1b2)A×B= a1a2b1b2 =a1b2a2b1 对于三维空间,两个向量的叉积结果是一个向量,如下所示: A = ( a 1 a 2 a 3 ) , B = ( b 1 b 2 b 3 ) A × B = ∣ i ^ j ^ k ^ a 1 a 2 a 3 b 1 b 2 b 3 ∣ = ⟨ i ^ ∣ a 2 a 3 b 2 b 3 ∣ , − j ^ ∣ a 1 a 3 b 1 b 3 ∣ , k ^ ∣ a 1 a 2 b 1 b 2 ∣ ⟩ \boldsymbol{A} = \begin{pmatrix} a_{1} \\ a_{2} \\ a_{3} \end{pmatrix}, \quad \boldsymbol{B} = \begin{pmatrix} b_{1} \\ b_{2} \\ b_{3} \end{pmatrix} \\ \boldsymbol{A} \times \boldsymbol{B} = \begin{vmatrix} \boldsymbol{\hat{i}} \quad \boldsymbol{\hat{j}} \quad \boldsymbol{\hat{k}} \\ a_{1} \quad a_{2} \quad a_{3} \\ b_{1} \quad b_{2} \quad b_{3} \end{vmatrix} = \langle \boldsymbol{\hat{i}}\begin{vmatrix} a_{2} \quad a_{3} \\ b_{2} \quad b_{3} \end{vmatrix}, -\boldsymbol{\hat{j}}\begin{vmatrix} a_{1} \quad a_{3} \\ b_{1} \quad b_{3} \end{vmatrix}, \boldsymbol{\hat{k}}\begin{vmatrix} a_{1} \quad a_{2} \\ b_{1} \quad b_{2} \end{vmatrix} \rangle A= a1a2a3 ,B= b1b2b3 A×B= i^j^k^a1a2a3b1b2b3 =i^ a2a3b2b3 ,j^ a1a3b1b3 ,k^ a1a2b1b2 因为叉积的结果是向量,所以 A × B \boldsymbol{A} \times \boldsymbol{B} A×B B × A \boldsymbol{B} \times \boldsymbol{A} B×A的结果并不相同,事实上: A × B = − ( B × A ) \boldsymbol{A} \times \boldsymbol{B} = -(\boldsymbol{B} \times \boldsymbol{A}) A×B=(B×A) NumPy 中可以通过cross函数来计算向量的叉积,代码如下所示。

print(np.cross(u, m1))  # [-14   7  21]
print(np.cross(m1, u))  # [ 14  -7 -21]

行列式
行列式(determinant)通常记作 ∣ A ∣ |\boldsymbol{A}| A,其中 A \boldsymbol{A} A是一个 n n n阶方阵。行列式可以看做是有向面积或体积的概念在一般欧几里得空间的推广,或者说行列式描述的是一个线性变换对“体积”所造成的影响。
在这里插入图片描述

行列式的性质
行列式是由向量引出的,所以行列式解释的其实是向量的性质。

性质1:如果 d e t ( A ) det(\boldsymbol{A}) det(A)中某行(或某列)的元素全部为0,那么 d e t ( A ) = 0 det(\boldsymbol{A}) = 0 det(A)=0

性质2:如果 d e t ( A ) det(\boldsymbol{A}) det(A)中某行(或某列)有公共因子 k k k,则可以提出 k k k,得到行列式 d e t ( A ′ ) det(\boldsymbol{A^{'}}) det(A),且 d e t ( A ) = k ⋅ d e t ( A ′ ) det(\boldsymbol{A}) = k \cdot det(\boldsymbol{A^{'}}) det(A)=kdet(A) d e t ( A ) = ∣ a 11 a 12 … a 1 n ⋮ ⋮ ⋱ ⋮ k a i 1 k a i 2 … k a i n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 … a n n ∣ = k ∣ a 11 a 12 … a 1 n ⋮ ⋮ ⋱ ⋮ a i 1 a i 2 … a i n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 … a n n ∣ = k ⋅ d e t ( A ′ ) det(\boldsymbol{A})={\begin{vmatrix}a_{11}&a_{12}&\dots &a_{1n}\\\vdots &\vdots &\ddots &\vdots \\{\color {blue}k}a_{i1}&{\color {blue}k}a_{i2}&\dots &{\color {blue}k}a_{in}\\\vdots &\vdots &\ddots &\vdots \\a_{n1}&a_{n2}&\dots &a_{nn}\end{vmatrix}}={\color {blue}k}{\begin{vmatrix}a_{11}&a_{12}&\dots &a_{1n}\\\vdots &\vdots &\ddots &\vdots \\a_{i1}&a_{i2}&\dots &a_{in}\\\vdots &\vdots &\ddots &\vdots \\a_{n1}&a_{n2}&\dots &a_{nn}\end{vmatrix}}={\color {blue}k} \cdot det(\boldsymbol{A^{'}}) det(A)= a11kai1an1a12kai2an2a1nkainann =k a11ai1an1a12ai2an2a1nainann =kdet(A)

性质3:如果 d e t ( A ) det(\boldsymbol{A}) det(A)中某行(或某列)的每个元素是两数之和,则此行列式可拆分为两个行列式相加,如下所示。 ∣ a 11 a 12 … a 1 n ⋮ ⋮ ⋱ ⋮ a i 1 + b i 1 a i 2 + b i 2 … a i n + b i n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 … a n n ∣ = ∣ a 11 a 12 … a 1 n ⋮ ⋮ ⋱ ⋮ a i 1 a i 2 … a i n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 … a n n ∣ + ∣ a 11 a 12 … a 1 n ⋮ ⋮ ⋱ ⋮ b i 1 b i 2 … b i n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 … a n n ∣ {\begin{vmatrix}a_{11}&a_{12}&\dots &a_{1n}\\\vdots &\vdots &\ddots &\vdots \\{\color {blue}a_{i1}}+{\color {OliveGreen}b_{i1}}&{\color {blue}a_{i2}}+{\color {OliveGreen}b_{i2}}&\dots &{\color {blue}a_{in}}+{\color {OliveGreen}b_{in}}\\\vdots &\vdots &\ddots &\vdots \\a_{n1}&a_{n2}&\dots &a_{nn}\end{vmatrix}}={\begin{vmatrix}a_{11}&a_{12}&\dots &a_{1n}\\\vdots &\vdots &\ddots &\vdots \\{\color {blue}a_{i1}}&{\color {blue}a_{i2}}&\dots &{\color {blue}a_{in}}\\\vdots &\vdots &\ddots &\vdots \\a_{n1}&a_{n2}&\dots &a_{nn}\end{vmatrix}}+{\begin{vmatrix}a_{11}&a_{12}&\dots &a_{1n}\\\vdots &\vdots &\ddots &\vdots \\{\color {OliveGreen}b_{i1}}&{\color {OliveGreen}b_{i2}}&\dots &{\color {OliveGreen}b_{in}}\\\vdots &\vdots &\ddots &\vdots \\a_{n1}&a_{n2}&\dots &a_{nn}\end{vmatrix}} a11ai1+bi1an1a12ai2+bi2an2a1nain+binann = a11ai1an1a12ai2an2a1nainann + a11bi1an1a12bi2an2a1nbinann 性质4:如果 d e t ( A ) det(\boldsymbol{A}) det(A)中两行(或两列)元素对应成比例,那么 d e t ( A ) = 0 det(\boldsymbol{A}) = 0 det(A)=0

性质5:如果 d e t ( A ) det(\boldsymbol{A}) det(A)中两行(或两列)互换得到 d e t ( A ′ ) det(\boldsymbol{A^{'}}) det(A),那么 d e t ( A ) = − d e t ( A ′ ) det(\boldsymbol{A}) = -det(\boldsymbol{A^{'}}) det(A)=det(A)

性质6:将 d e t ( A ) det(\boldsymbol{A}) det(A)中某行(或某列)的 k k k倍加进另一行(或另一列)里,行列式的值不变,如下所示。 ∣ ⋮ ⋮ ⋮ ⋮ a i 1 a i 2 … a i n a j 1 a j 2 … a j n ⋮ ⋮ ⋮ ⋮ ∣ = ∣ ⋮ ⋮ ⋮ ⋮ a i 1 a i 2 … a i n a j 1 + k a i 1 a j 2 + k a i 2 … a j n + k a i n ⋮ ⋮ ⋮ ⋮ ∣ {\begin{vmatrix}\vdots &\vdots &\vdots &\vdots \\a_{i1}&a_{i2}&\dots &a_{in}\\a_{j1}&a_{j2}&\dots &a_{jn}\\\vdots &\vdots &\vdots &\vdots \\\end{vmatrix}}={\begin{vmatrix}\vdots &\vdots &\vdots &\vdots \\a_{i1}&a_{i2}&\dots &a_{in}\\a_{j1}{\color {blue}+ka_{i1}}&a_{j2}{\color {blue}+ka_{i2}}&\dots &a_{jn}{\color {blue}+ka_{in}}\\\vdots &\vdots &\vdots &\vdots \\\end{vmatrix}} ai1aj1ai2aj2ainajn = ai1aj1+kai1ai2aj2+kai2ainajn+kain 性质7:将行列式的行列互换,行列式的值不变,如下所示。 ∣ a 11 a 12 … a 1 n a 21 a 22 … a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 … a n n ∣ = ∣ a 11 a 21 … a n 1 a 12 a 22 … a n 2 ⋮ ⋮ ⋱ ⋮ a 1 n a 2 n … a n n ∣ {\begin{vmatrix}a_{11}&a_{12}&\dots &a_{1n}\\a_{21}&a_{22}&\dots &a_{2n}\\\vdots &\vdots &\ddots &\vdots \\a_{n1}&a_{n2}&\dots &a_{nn}\end{vmatrix}}={\begin{vmatrix}a_{11}&a_{21}&\dots &a_{n1}\\a_{12}&a_{22}&\dots &a_{n2}\\\vdots &\vdots &\ddots &\vdots \\a_{1n}&a_{2n}&\dots &a_{nn}\end{vmatrix}} a11a21an1a12a22an2a1na2nann = a11a12a1na21a22a2nan1an2ann 性质8:方块矩阵 A \boldsymbol{A} A B \boldsymbol{B} B的乘积的行列式等于其行列式的乘积,即 d e t ( A B ) = d e t ( A ) d e t ( B ) det(\boldsymbol{A}\boldsymbol{B}) = det(\boldsymbol{A})det(\boldsymbol{B}) det(AB)=det(A)det(B)。特别的,若将矩阵中的每一行都乘以常数 r r r,那么行列式的值将是原来的 r n r^{n} rn倍,即 d e t ( r A ) = d e t ( r I n ⋅ A ) = r n d e t ( A ) det(r\boldsymbol{A}) = det(r\boldsymbol{I_{n}} \cdot \boldsymbol{A}) = r^{n}det(\boldsymbol{A}) det(rA)=det(rInA)=rndet(A),其中 I n \boldsymbol{I_{n}} In n n n阶单位矩阵。

性质9:若 A \boldsymbol{A} A是可逆矩阵,那么 d e t ( A − 1 ) = ( d e t ( A ) ) − 1 det(\boldsymbol{A}^{-1}) = (det(\boldsymbol{A}))^{-1} det(A1)=(det(A))1

行列式的计算
n n n阶行列式的计算公式如下所示: d e t ( A ) = ∑ n ! ± a 1 α a 2 β ⋯ a n ω det(\boldsymbol{A})=\sum_{n!} \pm {a_{1\alpha}a_{2\beta} \cdots a_{n\omega}} det(A)=n!±a1αa2βa

对于二阶行列式,上面的公式相当于: ∣ a 11 a 12 a 21 a 22 ∣ = a 11 a 22 − a 12 a 21 \begin{vmatrix} a_{11} \quad a_{12} \\ a_{21} \quad a_{22} \end{vmatrix} = a_{11}a_{22} - a_{12}a_{21} a11a12a21a22 =a11a22a12a21 对于三阶行列式,上面的计算公式相当于: ∣ a 11 a 12 a 13 a 21 a 22 a 23 a 31 a 32 a 33 ∣ = a 11 a 22 a 33 + a 12 a 23 a 31 + a 13 a 21 a 32 − a 11 a 23 a 32 − a 12 a 21 a 33 − a 13 a 22 a 31 \begin{vmatrix} a_{11} \quad a_{12} \quad a_{13} \\ a_{21} \quad a_{22} \quad a_{23} \\ a_{31} \quad a_{32} \quad a_{33} \end{vmatrix} = a_{11}a_{22}a_{33} + a_{12}a_{23}a_{31} + a_{13}a_{21}a_{32} - a_{11}a_{23}a_{32} - a_{12}a_{21}a_{33} - a_{13}a_{22}a_{31} a11a12a13a21a22a23a31a32a33 =a11a22a33+a12a23a31+a13a21a32a11a23a32a12a21a33a13a22a31 高阶行列式可以用代数余子式(cofactor)展开成多个低阶行列式,如下所示: d e t ( A ) = a 11 C 11 + a 12 C 12 + ⋯ + a 1 n C 1 n = ∑ i = 1 n a 1 i C 1 i det(\boldsymbol{A})=a_{11}C_{11}+a_{12}C_{12}+ \cdots +a_{1n}C_{1n} = \sum_{i=1}^{n}{a_{1i}C_{1i}} det(A)=a11C11+a12C12++a1nC1n=i=1na1iC1i 其中, C 11 C_{11} C11是原行列式去掉 a 11 a_{11} a11所在行和列之后剩余的部分构成的行列式,以此类推。

矩阵
矩阵(matrix)是由一系列元素排成的矩形阵列,矩阵里的元素可以是数字、符号或数学公式。矩阵可以进行加法、减法、数乘、转置、矩阵乘法等运算,如下图所示。
在这里插入图片描述

值得一提的是矩阵乘法运算,该运算仅当第一个矩阵 A \boldsymbol{A} A的列数和另一个矩阵 B \boldsymbol{B} B的行数相等时才能定义。如果 A \boldsymbol{A} A是一个 m × n m \times n m×n的矩阵, B \boldsymbol{B} B是一个 n × k n \times k n×k矩阵,它们的乘积是一个 m × k m \times k m×k的矩阵,其中元素的计算公式如下所示: [ A B ] i , j = A i , 1 B 1 , j + A i , 2 B 2 , j + ⋯ + A i , n B n , j = ∑ r = 1 n A i , r B r , j [\mathbf{AB}]{i,j} = A{i,1}B_{1,j} + A_{i,2}B_{2,j} + \cdots + A_{i,n}B_{n,j} = \sum_{r=1}^n A_{i,r}B_{r,j} [AB]i,j=Ai,1B1,j+Ai,2B2,j++Ai,nBn,j=r=1nAi,rBr,j
在这里插入图片描述

例如: [ 1 0 2 − 1 3 1 ] × [ 3 1 2 1 1 0 ] = [ ( 1 × 3 + 0 × 2 + 2 × 1 ) ( 1 × 1 + 0 × 1 + 2 × 0 ) ( − 1 × 3 + 3 × 2 + 1 × 1 ) ( − 1 × 1 + 3 × 1 + 1 × 0 ) ] = [ 5 1 4 2 ] \begin{bmatrix} 1 & 0 & 2 \\ -1 & 3 & 1 \\ \end{bmatrix} \times \begin{bmatrix} 3 & 1 \\ 2 & 1 \\ 1 & 0 \end{bmatrix} = \begin{bmatrix} (1 \times 3 + 0 \times 2 + 2 \times 1) & (1 \times 1 + 0 \times 1 + 2 \times 0) \\ (-1 \times 3 + 3 \times 2 + 1 \times 1) & (-1 \times 1 + 3 \times 1 + 1 \times 0) \\ \end{bmatrix} = \begin{bmatrix} 5 & 1 \\ 4 & 2 \\ \end{bmatrix} [110321]× 321110 =[(1×3+0×2+2×1)(1×3+3×2+1×1)(1×1+0×1+2×0)(1×1+3×1+1×0)]=[5412] 矩阵的乘法满足结合律和对矩阵加法的分配律:

结合律: ( A B ) C = A ( B C ) (\boldsymbol{AB})\boldsymbol{C} = \boldsymbol{A}(\boldsymbol{BC}) (AB)C=A(BC)

左分配律: ( A + B ) C = A C + B C (\boldsymbol{A} + \boldsymbol{B})\boldsymbol{C} = \boldsymbol{AC} + \boldsymbol{BC} (A+B)C=AC+BC

右分配律: C ( A + B ) = C A + C B \boldsymbol{C}(\boldsymbol{A} + \boldsymbol{B}) = \boldsymbol{CA} + \boldsymbol{CB} C(A+B)=CA+CB

矩阵乘法不满足交换律。一般情况下,矩阵 A \boldsymbol{A} A B \boldsymbol{B} B的乘积 A B \boldsymbol{AB} AB存在,但 B A \boldsymbol{BA} BA不一定存在,即便 B A \boldsymbol{BA} BA存在,大多数时候 A B ≠ B A \boldsymbol{AB} \neq \boldsymbol{BA} AB=BA

矩阵乘法的一个基本应用是在线性方程组上。线性方程组是方程组的一种,它符合以下的形式: { a 1 , 1 x 1 + a 1 , 2 x 2 + ⋯ + a 1 , n x n = b 1 a 2 , 1 x 1 + a 2 , 2 x 2 + ⋯ + a 2 , n x n = b 2 ⋮ ⋮ a m , 1 x 1 + a m , 2 x 2 + ⋯ + a m , n x n = b m \begin{cases} a_{1,1}x_{1} + a_{1,2}x_{2} + \cdots + a_{1,n}x_{n}= b_{1} \\ a_{2,1}x_{1} + a_{2,2}x_{2} + \cdots + a_{2,n}x_{n}= b_{2} \\ \vdots \quad \quad \quad \vdots \\ a_{m,1}x_{1} + a_{m,2}x_{2} + \cdots + a_{m,n}x_{n}= b_{m} \end{cases} a1,1x1+a1,2x2++a1,nxn=b1a2,1x1+a2,2x2++a2,nxn=b2am,1x1+am,2x2++am,nxn=bm 运用矩阵的方式,可以将线性方程组写成一个向量方程: A x = b \boldsymbol{Ax} = \boldsymbol{b} Ax=b 其中, A \boldsymbol{A} A是由方程组里未知数的系数排成的 m × n m \times n m×n矩阵, x \boldsymbol{x} x是含有 n n n个元素的行向量, b \boldsymbol{b} b是含有 m m m个元素的行向量。

矩阵是线性变换(保持向量加法和标量乘法的函数)的便利表达法。矩阵乘法的本质在联系到线性变换的时候最能体现,因为矩阵乘法和线性变换的合成有以下的联系,即每个 m × n m \times n m×n的矩阵 A \boldsymbol{A} A都代表了一个从 R n \boldsymbol{R}^{n} Rn射到 R m \boldsymbol{R}^{m} Rm的线性变换。

矩阵对象
NumPy 中提供了专门用于线性代数(linear algebra)的模块和表示矩阵的类型matrix,当然我们通过二维数组也可以表示一个矩阵,官方并不推荐使用matrix类而是建议使用二维数组,而且有可能在将来的版本中会移除matrix类。无论如何,利用这些已经封装好的类和函数,我们可以轻松愉快的实现很多对矩阵的操作。

我们可以通过下面的代码来创建矩阵(matrix)对象。

代码:

m1 = np.matrix('1 2 3; 4 5 6')
m1

说明:matrix构造器可以传入类数组对象也可以传入字符串来构造矩阵对象。

输出:

matrix([[1, 2, 3],
        [4, 5, 6]])

代码:

m2 = np.asmatrix(np.array([[1, 1], [2, 2], [3, 3]]))
m2

说明:asmatrix函数也可以用mat函数代替,这两个函数其实是同一个函数。

输出:

matrix([[1, 1],
        [2, 2],
        [3, 3]])

代码:

m1 * m2

输出:

matrix([[14, 14],
        [32, 32]])

说明:注意matrix对象和ndarray对象乘法运算的差别,matrix对象的运算是矩阵乘法运算。如果两个二维数组要做矩阵乘法运算,应该使用@运算符或matmul函数,而不是运算符

矩阵对象的属性如下表所示。

属性	说明
A	获取矩阵对象对应的ndarray对象
A1	获取矩阵对象对应的扁平化后的ndarray对象
I	可逆矩阵的逆矩阵
T	矩阵的转置
H	矩阵的共轭转置
shape	矩阵的形状
size	矩阵元素的个数

矩阵对象的方法跟之前讲过的ndarray数组对象的方法基本差不多。

线性代数模块
NumPy 的linalg模块中有一组标准的矩阵分解运算以及诸如求逆和行列式之类的函数,下面的表格列出了numpy以及linalg模块中一些常用的线性代数相关函数。
在这里插入图片描述

下面进行简单尝试,先试一试求逆矩阵。

代码:

m3 = np.array([[1., 2.], [3., 4.]])
m4 = np.linalg.inv(m3)
m4

输出:

array([[-2. ,  1. ],
       [ 1.5, -0.5]])

代码:

np.around(m3 @ m4)

说明:around函数对数组元素进行四舍五入操作,默认小数点后面的位数为0。

输出:

array([[1., 0.],
       [0., 1.]])

说明:矩阵和它的逆矩阵做矩阵乘法会得到单位矩阵。

计算行列式的值。

代码:

m5 = np.array([[1, 3, 5], [2, 4, 6], [4, 7, 9]])
np.linalg.det(m5)

输出:

2

计算矩阵的秩。

代码:

np.linalg.matrix_rank(m5)

输出:

3

求解线性方程组。 { x 1 + 2 x 2 + x 3 = 8 3 x 1 + 7 x 2 + 2 x 3 = 23 2 x 1 + 2 x 2 + x 3 = 9 \begin{cases} x_1 + 2x_2 + x_3 = 8 \\ 3x_1 + 7x_2 + 2x_3 = 23 \\ 2x_1 + 2x_2 + x_3 = 9 \end{cases} x1+2x2+x3=83x1+7x2+2x3=232x1+2x2+x3=9

对于上面的线性方程组,我们可以用矩阵的形式来表示它,如下所示。 A = [ 1 2 1 3 7 2 2 2 1 ] , x = [ x 1 x 2 x 3 ] , b = [ 8 23 9 ] \boldsymbol{A} = \begin{bmatrix} 1 & 2 & 1\\ 3 & 7 & 2\\ 2 & 2 & 1 \end{bmatrix}, \quad \boldsymbol{x} = \begin{bmatrix} x_1 \\ x_2\\ x_3 \end{bmatrix}, \quad \boldsymbol{b} = \begin{bmatrix} 8 \\ 23\\ 9 \end{bmatrix} A= 132272121 ,x= x1x2x3 ,b= 8239

A x = b \boldsymbol{Ax} = \boldsymbol{b} Ax=b

线性方程组有唯一解的条件:系数矩阵 A \boldsymbol{A} A的秩等于增广矩阵 A b \boldsymbol{Ab} Ab的秩,而且跟未知数的个数相同。

代码:

A = np.array([[1, 2, 1], [3, 7, 2], [2, 2, 1]])
b = np.array([8, 23, 9]).reshape(-1, 1)
print(np.linalg.matrix_rank(A))
print(np.linalg.matrix_rank(np.hstack((A, b))))

说明:使用数组对象的reshape方法调形时,如果其中一个参数为-1,那么该维度有多少个元素是通过数组元素个数(size属性)和其他维度的元素个数自动计算出来的。

输出:

3
3

代码:

np.linalg.solve(A, b)

输出:

array([[1.],
       [2.],
       [3.]])

说明:上面的结果表示,线性方程组的解为: x 1 = 1 , x 2 = 2 , x 3 = 3 x_1 = 1, x_2 = 2, x_3 = 3 x1=1,x2=2,x3=3

下面是另一种求解线性方程组的方法,大家可以停下来思考下为什么。 x = A − 1 ⋅ b \boldsymbol{x} = \boldsymbol{A}^{-1} \cdot \boldsymbol{b} x=A1b 代码:

np.linalg.inv(A) @ b

输出:

array([[1.],
       [2.],
       [3.]])

多项式
除了数组,NumPy 中还封装了用于多项式(polynomial)运算的数据类型。多项式是变量的整数次幂与系数的乘积之和,形如: f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x 1 + a 0 x 0 f(x)=a_nx^n + a_{n-1}x^{n-1} + \cdots + a_1x^{1} + a_0x^{0} f(x)=anxn+an1xn1++a1x1+a0x0
创建多项式对象
创建poly1d对象,例如: f ( x ) = 3 x 2 + 2 x + 1 \small{f(x)=3x^{2}+2x+1} f(x)=3x2+2x+1

代码:

p1 = np.poly1d([3, 2, 1])
p2 = np.poly1d([1, 2, 3])
print(p1)
print(p2)

输出:

   2
3 x + 2 x + 1
   2
1 x + 2 x + 3

多项式的操作
获取多项式的系数

代码:

print(p1.coefficients)
print(p2.coeffs)

输出:

[3 2 1]
[1 2 3]

两个多项式的四则运算

代码:

print(p1 + p2)
print(p1 * p2)

输出:

   2
4 x + 4 x + 4
   4     3      2
3 x + 8 x + 14 x + 8 x + 3

带入 x \small{x} x求多项式的值

代码:

print(p1(3))
print(p2(3))

输出:

34
18

多项式求导和不定积分

代码:

print(p1.deriv())
print(p1.integ())

输出:

6 x + 2
   3     2
1 x + 1 x + 1 x

求多项式的根

例如有多项式 f ( x ) = x 2 + 3 x + 2 \small{f(x)=x^2+3x+2} f(x)=x2+3x+2,多项式的根即一元二次方程 x 2 + 3 x + 2 = 0 \small{x^2+3x+2=0} x2+3x+2=0的解。

代码:

p3 = np.poly1d([1, 3, 2])
print(p3.roots)

输出:

[-2. -1.]

如果使用numpy.polynomial模块的Polynomial类来表示多项式对象,那么对应的操作如下所示。

代码:

from numpy.polynomial import Polynomial

p3 = Polynomial((2, 3, 1))
print(p3)           # 输出多项式
print(p3(3))        # 令x=3,计算多项式的值
print(p3.roots())   # 计算多项式的根
print(p3.degree())  # 获得多项式的次数
print(p3.deriv())   # 求导
print(p3.integ())   # 求不定积分

输出:

2.0 + 3.0·x + 1.0·x²
20.0
[-2. -1.]
2
3.0 + 2.0·x
0.0 + 2.0·x + 1.5·x² + 0.33333333·x³

最小二乘解
Polynomial类还有一个名为fit的类方法,它可以给多项式求最小二乘解。所谓最小二乘解(least-squares solution),是用最小二乘法通过最小化误差的平方和来寻找数据的最佳匹配函数的系数。假设多项式为 f ( x ) = a x + b \small{f(x)=ax+b} f(x)=ax+b,最小二乘解就是让下面的残差平方和 R S S \small{RSS} RSS达到最小的 a \small{a} a b \small{b} b R S S = ∑ i = 0 k ( f ( x i ) − y i ) 2 RSS = \sum_{i=0}^{k}(f(x_i) - y_i)^{2} RSS=i=0k(f(xi)yi)2 例如,我们想利用收集到的月收入和网购支出的历史数据来建立一个预测模型,以达到通过某人的月收入预测他网购支出金额的目标,下面是我们收集到的收入和网购支出的数据,保存在两个数组中。

x = np.array([
    25000, 15850, 15500, 20500, 22000, 20010, 26050, 12500, 18500, 27300,
    15000,  8300, 23320,  5250,  5800,  9100,  4800, 16000, 28500, 32000,
    31300, 10800,  6750,  6020, 13300, 30020,  3200, 17300,  8835,  3500
])
y = np.array([
    2599, 1400, 1120, 2560, 1900, 1200, 2320,  800, 1650, 2200,
     980,  580, 1885,  600,  400,  800,  420, 1380, 1980, 3999,
    3800,  725,  520,  420, 1200, 4020,  350, 1500,  560,  500
])

我们可以先绘制散点图来了解两组数据是否具有正相关或负相关关系。正相关意味着数组x中较大的值对应到数组y中也是较大的值,而负相关则意味着数组x中较大的值对应到数组y中较小的值。

import matplotlib.pyplot as plt

plt.figure(dpi=120)
plt.scatter(x, y, color='blue')
plt.show()

输出:
在这里插入图片描述

如果需要定量的研究两组数据的相关性,我们可以计算协方差或相关系数,对应的 NumPy 函数分别是cov和corrcoef。

代码:

np.corrcoef(x, y)

输出:

array([[1.        , 0.92275889],
       [0.92275889, 1.        ]])

说明:相关系数是一个-1到1之间的值,越靠近1 说明正相关性越强,越靠近-1说明负相关性越强,靠近0则说明两组数据没有明显的相关性。上面月收入和网购支出之间的相关系数是0.92275889,说明二者是强正相关关系。

通过上面的操作,我们确定了收入和网购支出之前存在强正相关关系,于是我们用这些数据来创建一个回归模型,找出一条能够很好的拟合这些数据点的直线。这里,我们就可以用到上面提到的fit方法,具体的代码如下所示。

代码:

from numpy.polynomial import Polynomial

Polynomial.fit(x, y, deg=1).convert().coef

说明:deg=1说明回归模型最高次项就是1次项,回归模型形如 y = a x + b \small{y=ax+b} y=ax+b;如果要生一个类似于 y = a x 2 + b x + c \small{y=ax^2+bx+c} y=ax2+bx+c的模型,就需要设置deg=2,以此类推。

输出:

array([-2.94883437e+02,  1.10333716e-01])

根据上面输出的结果,我们的回归方程应该是 y = 0.110333716 x − 294.883437 \small{y=0.110333716x-294.883437} y=0.110333716x294.883437。我们将这个回归方程绘制到刚才的散点图上,红色的点是我们的预测值,蓝色的点是历史数据,也就是真实值。

代码:

import matplotlib.pyplot as plt

plt.scatter(x, y, color='blue')
plt.scatter(x, 0.110333716 * x - 294.883437, color='red')
plt.plot(x, 0.110333716 * x - 294.883437, color='darkcyan')
plt.show()

输出:
在这里插入图片描述

如果不使用Polynomial类型的fit方法,我们也可以通过 NumPy 提供的polyfit函数来完成同样的操作,在此不详细介绍啦~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/622718.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 超级终端Terminator常用使用技巧

Ubuntu 超级终端Terminator常用使用技巧 Terminator 是一款功能强大的终端模拟器,它特别适合于需要同时管理多个终端会话的用户。以下是如何在 Ubuntu 上使用 Terminator 的详细指南: 安装 Terminator 如果你的系统尚未安装 Terminator,你…

Prompt Engineering ,Fine-tuning , RAG ?

Prompt Engineering ,Fine-tuning , RAG 总结:1 prompt engineering2 RAG (Retrieval Augmented Generation)**RAG特点****RAG优势****RAG劣势** 3 微调(Fine-tuning)**微调特点****微调优势****微调劣势** 4 三者共性和区别5 RAG和微调的适应…

港中深「户外自重构蜗牛机器人集群」登Nature子刊!

在科幻电影《超能陆战队》中,我们见证了一种由成千上万个微小磁性单元组成的机器人通过磁力相互连接,形成各种复杂的三维结构。香港中文大学(深圳)林天麟教授团队致力于将这一科幻转化为现实,近年来开发了一系列自由形…

C++基础与深度解析 | 数组 | vector | string

文章目录 一、数组1.一维数组2.多维数组 二、vector三、string 一、数组 1.一维数组 在C中,数组用于存储具有相同类型和特定大小的元素集合。数组在内存中是连续存储的,并且支持通过索引快速访问元素。 数组的声明: 数组的声明指定了元素的…

【基础技能】Windows常用快捷键

最近做知识管理,梳理了下个人技能,存在好多基础技能都是一知半解,用的时候都是现搜现查,没有形成一个完整的知识体系,导致一些基础不牢靠,需要再次筑基! 于是就翻阅了微软的官网,撸…

5.13网络编程

只要在一个电脑中的两个进程之间可以通过网络进行通信那么拥有公网ip的两个计算机的通信是一样的。但是一个局域网中的两台电脑上的虚拟机是不能进行通信的,因为这两个虚拟机在电脑中又有各自的局域网所以通信很难实现。 socket套接字是一种用于网络间进行通信的方…

Linux进程间几种通信机制

一. 简介 经过前一篇文章的学习, 我们知道Linux下有两种标准:system V标准和 Posix标准。 System V 和 POSIX 标准是操作系统提供的接口标准,它们规定了操作系统应该如何实现一些基本功能,比如线程、进程间通信、文件处理等。 …

【APM】在Kubernetes中搭建OpenTelemetry+Loki+Tempo+Grafana链路追踪(一)

文章目录 1、最终效果2、前提准备2、环境信息3、服务集成(Opentelemetry ->Tempo)3.1 上报链路数据3.1.1 下载opentelemetry-agent3.1.2 启动配置业务app3.1.3 配置opentelemetry输入输出3.1.4 配置grafana datasource3.1.4.1 配置tempo3.1.4.2 配置l…

基于RK3568的鸿蒙通行一体机方案项目

鸿蒙通行一体机方案以鸿蒙版AIoT-3568X人工智能主板为核心平台,搭载OpenHarmony操作系统,使用自研算法和国产芯片,可管可控,并提供身份识别以及其他外设配件生态链支持。 01 项目概述 项目使用场景 鸿蒙版通行一体机方案凭借自主…

【云计算小知识】云管理的作用是什么?

云计算已经成为推动企业数字化转型,提升运营效率的重要力量。而在这个过程中,云管理作为确保云计算环境稳定、高效运行的关键环节,其作用愈发凸显。今天我们小编就给大家详细介绍一下云管理的作用是什么? 云管理的作用是什么&…

探索渲染农场的高性能奥秘

在当今数字化的时代,渲染农场正逐渐成为许多行业不可或缺的强大工具。那么,为什么我们说渲染农场是高性能的计算机系统呢?让我们深入剖析其中关键要点。 “渲染农场”拥有大规模的计算资源。它由众多高性能的计算机节点组成,这些…

Maven、JavaWeb基础开发

1 Maven介绍 1、标准化的项目结构 2、标准化的构建流程 3、依赖管理 4、依赖范围 2 JavaWeb基础开发 2.1 Http协议 1 Http请求数据格式 2 Http响应数据格式 2.2 Web服务器(Tomcat) VTS、FileServer使用Tomcat部署; 其他服务单元TESLA S…

vue3.0(七) 计算属性(computed)

文章目录 1 计算属性(computed )1.1 computed使用1.2 computed使用场景1.4 computed的注意点1.4 computed的原理1.5 computed的示例 computed 和 Methods 的区别 1 计算属性(computed ) 在 Vue 3 中,computed 是一个用…

【AI大模型】自动生成红队攻击提示--GPTFUZZER

本篇参考论文为: Yu J, Lin X, Xing X. Gptfuzzer: Red teaming large language models with auto-generated jailbreak prompts[J]. arXiv preprint arXiv:2309.10253, 2023. https://arxiv.org/pdf/2309.10253 一 背景 虽然LLM在今天的各个领域得到了广泛的运用…

Nginx安全扫描借助lua-nginx-module模块增加授权

一、问题描述 某次安全扫描通过Dirsearch工具发现,nginx代理访问某后端业务时,发现:Springboot未授权漏洞,存在信息泄露风险,危险等级:中危; 相关资源:openresty官网、/lua-nginx-m…

结构体补充-位段

文章目录 位段介绍位段内存分配位段的使用注意事项结束 位段介绍 为什么会有位段呢? 我们直到一个int是4个字节表示32个bit位,但是比如2,3这样的整数,我们只需要2个bit位就可以了,那30个比特位不就是浪费掉了吗,所以位段就产生了 位段通过结构体来实现,位段表示方法…

Hive表数据优化

Hive表数据优化 1.文件格式 为Hive表中的数据选择一个合适的文件格式,对提高查询性能的提高是十分有益的。 (1)Text File 文本文件是Hive默认使用的文件格式,文本文件中的一行内容,就对应Hive表中的一行记录。 可…

C++之Eigen库基本使用(下)

1、常见变换 Eigen::Matrix3d //旋转矩阵(3*3) Eigen::AngleAxisd //旋转向量(3*1) Eigen::Vector3d //欧拉角(3*1) Eigen::Quaterniond //四元数(4*1) Eigen::Isom…

K8s:二进制安装k8s(单台master)

目录 一、安装k8s 1、拓扑图 2、系统初始化配置 2.1关闭防火墙selinx以及swap 2.2设置主机名 2.3在每台主机中添加hosts,做映射 2.4调整内核参数,将桥接的ipv4流量传递到iptables,关闭ipv6 2.4时间同步 3、部署docker引擎&#xff0…

【Kali Linux工具篇】wpscan的基本介绍与使用

介绍 WPScan是Kali Linux默认自带的一款漏洞扫描工具,它采用Ruby编写,能够扫描WordPress网站中的多种安全漏洞,其中包括主题漏洞、插件漏洞和WordPress本身的漏洞。最新版本WPScan的数据库中包含超过18000种插件漏洞和2600种主题漏洞&#x…