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 + 12
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 + 44     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 + 23     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 Polynomialp3 = 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 pltplt.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 PolynomialPolynomial.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 pltplt.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函数来完成同样的操作,在此不详细介绍啦~~~

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记-跨域方式实现原理

websocket Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后&#xff…

vue3 中 使用 antd中的select 组件的带搜索框 展开后可对选项进行筛选搜索功能

鼠标进入以后下拉显示&#xff1a; 输入字符串以后&#xff1a; 可以看出对数据进行了筛选。 具体代码&#xff1a; 结构上&#xff1a;<a-selectv-model:value"formState.formFlow"show-searchallowClearplaceholder"输入选择流程":options"op…

OpenCV人脸识别,报错缺少haarcascade_frontalface_default.xml文件解决方案(随手记)

使用pip安装的opencv库可能会缺少进行人脸识别的haarcascade_frontalface_default.xml等文件。 可以通过github直接进行下载&#xff0c;再放到需要使用的python文件目录下 单击连接&#xff0c;github人脸识别库-link 找到对应需要的xml文件&#xff0c;这里我举例为haarcas…

[图解]EA从数据库逆向得到分析类模型-01

1 00:00:00,840 --> 00:00:02,400 今天&#xff0c;我们来说一下 2 00:00:02,670 --> 00:00:06,320 一个最近几天不止一个同学问的问题 3 00:00:06,490 --> 00:00:11,410 就是说&#xff0c;怎样把一个数据库 4 00:00:13,740 --> 00:00:16,720 转到分析类图 5 …

Docker 的 Ubuntu 操作系统镜像

Debian 和 Ubuntu 都是目前较为流行的 Debian 系列 的服务器操作系统&#xff0c;十分适合研发场景。 Debian 和 Ubuntu 属于同一系列的发行版。Debian 是由 Ian Murdock 在 1993 年创建的最初的发行版。Ubuntu 是 Mark Shuttleworth 在 2004 年基于 Debian 创建的发行版。 Li…

Android 按键消息流程源码分析

在Android系统中&#xff0c;键盘按键事件是由SystemServer服务来管理的&#xff1b;然后在以消息的形式分发给应用程序处理。产生键盘按键事件则是有Linux kernel的相关驱动来实现。键盘消息有别于其他类型的消息&#xff1b;需要从Linux kernel drivers产生由上层APP来处理。…

MWM触摸屏工控机维修TEM-EV0 EN00-Z312yy-xx

触摸屏维修是一个比较复杂的过程&#xff0c;并且其中会涉及到各个部件的问题&#xff0c;这对于操作人员来说&#xff0c;关键在于是否可以找到问题所在。维修过程中建议先检查各接线接口是否出现松动&#xff0c;然后检查串口及中断号是否有冲突&#xff0c;若有冲突&#xf…

Ubuntu20.04 设置路由器

1. 网络拓扑图 双网卡单Lan口拓扑图 多网卡多Lan口带网桥拓扑图 2. 查看网卡信息 ip a得出如下网卡信息列表&#xff0c;共四个网络信息&#xff0c;忽略第一个本地环回地址 一共存在三个网卡分别为enp1s0、enp2s0、wlo&#xff0c;以及其他详细信息&#xff0c;当前我们只需…

【Linux系统编程】第十八弹---进程状态(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、操作系统进程 1.1、进程背景 1.2、进程如何在CPU上运行的&#xff1f; 1.2、进程状态 2、Linux的进程状态 2.1、如何描…

U盘打不开提示格式化怎么办?(含数据恢复及U盘修复教程)

引言&#xff1a; 随着数字化时代的发展&#xff0c;U盘已成为我们日常生活和工作中不可或缺的数据存储工具。然而&#xff0c;有时我们可能会遇到U盘突然无法打开&#xff0c;并提示需要格式化的问题。这不仅会打乱我们的工作节奏&#xff0c;还可能会导致重要数据丢失。本文…

【SpringSecurity源码】过滤器链加载流程

theme: smartblue highlight: a11y-dark 一、前言及准备 1.1 SpringSecurity过滤器链简单介绍 在Spring Security中&#xff0c;过滤器链&#xff08;Filter Chain&#xff09;是由多个过滤器&#xff08;Filter&#xff09;组成的&#xff0c;这些过滤器按照一定的顺序对进…

基于SpringBoot+Vue的法律咨询系统

课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不可跨域的鸿沟&#xff0c;信息的传播速度极慢&#xff0c;信息处理的速…

Kafka应用Demo:按主题订阅消费消息

安装环境 Kafka安装可参考官方网站的指导(https://kafka.apache.org/quickstart), 按步骤解压压缩包&#xff0c;修改配置。然后再启动zookeeper和kafka-server即可。 需要注意的一点&#xff1a;如果是在VMware虚拟机上启动的kafka, 需要修改一下server.properties配置文件&am…

AI浪潮再起,2024年中国大模型产业深度解析

国内 AI大模型产业发展深度分析 2024 人工智能技术的迅猛发展&#xff0c;使AI大模型成为科技竞争的核心、产业变革的先锋、经济增长的新动力。我国已将人工智能列为国家战略&#xff0c;出台系列政策扶持其发展&#xff0c;为AI大模型产业创造优越环境&#xff0c;展现巨大潜力…

CentOS 7安装配置docker

CentOS 7、8安装、配置docker 这里宿主机的型号选择是centos7.9.2009的版本 1.宿主机关闭防火墙和selinux&#xff0c;配置ipv4 #设置SELinuxdisabled vim /etc/selinux/config SELinuxdisabled 查看防火墙状态&#xff1a;firewall-cmd --state 关闭防火墙&#xff1a;syst…

FloodFill算法---BFS

目录 一、前言 二、算法模板套路 2.1 创建所需的全局变量&#xff1a; 2.2 BFS模板&#xff1a; 2.3 细节处理&#xff1a; 三、例题练习 3.1 例题1&#xff1a;图像渲染 3.2 例题2&#xff1a;岛屿数量 3.3 例题3&#xff1a;岛屿的最大面积 3.4 例题4&#xff1a;被…

在做题中学习(54):点名

LCR 173. 点名 - 力扣&#xff08;LeetCode&#xff09; 此题有不同的几种解法&#xff1a; 解法一&#xff1a;暴力枚举 O(n); 解法二&#xff1a;哈希表 把原数组丢入哈希表&#xff0c;遍历哈希表&#xff0c;看看哪个数值为0即可。 O(n)空间O(n)时间 解法三&…

OpenAI推出新模型GPT-4o:可实时交互,检测人的情绪,支持多模态输出

GPT-4o作为OpenAI新发布的人工智能模型&#xff0c;据官方及媒体报道&#xff0c;是面向全球用户发布的&#xff0c;包括中国在内的用户理论上应该能够通过相应平台和应用访问。不过&#xff0c;实际可用性还需考虑地区政策、网络访问限制以及具体平台是否在中国有本地化服务等…

1694jsp宿舍管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 宿舍管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库…

网络安全快速入门(十一)vi/vim

11.1 了解vi 前面我i们已经在基础命令中大致了解了vi&#xff0c;本章我们针对vi来细讲一下&#xff0c;vi和vim 11.1.1 什么是vi/vim&#xff1f; vi和vim&#xff0c;都是一个模块化的文本编辑工具&#xff0c;换句话讲&#xff0c;通过vi下的一系列的命令&#xff0c;可以实…