线性代数是一门被广泛运用于各个工程技术学科的数学分支,利用线性代数的相关概念和结论,可以极大的简化机器学习里相关公式的推导和表述。
-
标量: 一个单独的数, 通常使用斜体小写字母表示,例如$x=1$。
-
向量:可以看作是一个
有序
的一维
数组,通过索引能够唯一的确定向量中的某个值,通常使用斜体加粗的小写字母表示,例如$\boldsymbol{x} = \{1,2,3,4,5 \}$,其中第$i$个元素可以表示为$x_i$。 -
矩阵:矩阵是一个
有序
的二维
数组,其中每个元素由两个索引确定,分别表示它的行
和列
,通常使用斜体加粗的大写字母表示,例如$\boldsymbol{A} = \left[ \begin{matrix}1 & 2 \\ 3 & 4 \end{matrix} \right]$,一个$n$维向量可以看做是一个$1 \times n$的矩阵。 -
张量:张量表示一个
有序
的多维
数组,其中每个元素可以由多个索引确定,通常使用加粗的大写字母表示,例如$\bf{A}$,向量和矩阵可以分别看作是一维和二维的张量。
在numpy中,可以用以下方式生成各种维度的张量:
>>> import numpy as np
## 生成元素全为0的二维张量,两个维度分别为3,4
>>> np.zeros((3,4))
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
## 生成三维的随机张量,三个维度分别为2,3,4
>>> np.random.rand(2,3,4)
array([[[ 0.93187582, 0.4942617 , 0.23241437, 0.82237576],
[ 0.90066163, 0.30151126, 0.89734992, 0.56656615],
[ 0.54487942, 0.80242768, 0.477167 , 0.6101814 ]],
[[ 0.61176321, 0.11454075, 0.58316117, 0.36850871],
[ 0.18480808, 0.12397686, 0.22586973, 0.35246394],
[ 0.01192416, 0.5990322 , 0.34527612, 0.424322 ]]])
-
方阵:行数和列数相等的矩阵。
-
单位矩阵:对角线元素均为1,其他位置均为0的方阵,通常记为$\boldsymbol{I}_n$,$n$代表行列数,例如
>>> np.eye(4)
array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
- reshape:在数学中并没有reshape运算,但是在Numpy和Tensorflow等运算库中是一个非常常用的运算,用来改变一个张量的维度数和每个维度的大小,例如一个10x10的图片在保存时直接保存为一个包含100个元素的序列,在读取后就可以使用reshape将其从1x100变换为10x10,示例如下:
## 生成一个包含整数0~11的向量
>>> x = np.arange(12)
>>> x
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> x.shape
(12,)
## 将x转换成二维矩阵,其中矩阵的第一个维度为1
>>> x = x.reshape(1,12)
>>> x
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
>>> x.shape
(1, 12)
## 将x转换3x4的矩阵
>>> x = x.reshape(3,4)
>>> x
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
- 转置(transpose):向量和矩阵的转置是交换行列顺序,矩阵$\boldsymbol{A}$的转置记为$\boldsymbol{A}^T$,而三维及以上张量的转置就需要指定转换的维度,示例如下:
## 生成包含5个元素的向量x并将其转置
>>> x = np.arange(5).reshape(1,-1)
>>> x
array([[0, 1, 2, 3, 4]])
>>> x.T
array([[0],
[1],
[2],
[3],
[4]])
## 生成3*4的矩阵并转置
>>> A = np.arange(12).reshape(3,4)
>>> A
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> A.T
array([[ 0, 4, 8],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]])
## 生成2*3*4的张量
>>> B = np.arange(24).reshape(2,3,4)
>>> B
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
## 将B的01两个维度转置
>>> B.transpose(1,0,2)
array([[[ 0, 1, 2, 3],
[12, 13, 14, 15]],
[[ 4, 5, 6, 7],
[16, 17, 18, 19]],
[[ 8, 9, 10, 11],
[20, 21, 22, 23]]])
对于张量来说,transpose和reshape都是非常常见又容易混淆的概念,reshape改变的是张量的形状,即张量各个维度上元素个数的分配,但对每一个元素来说,它相对于张量首个元素的
间隔
是不变的,对任一个张量,无论怎么样reshape,它进行flatten之后都是不变的;而transpose改变的是维度的方向,而不改变张量的形状,但是flatten之后会发生变化。
- 矩阵乘法:记两个矩阵分别为A和B,$C=A*B$,则$C_{ij} = \sum_k {A_{i,k}B_{k,j}}$,由公式可以看到两个矩阵能够相乘的条件为第一个矩阵的列数等于第二个矩阵的行数,示例如下:
>>> A = np.arange(6).reshape(3,2)
>>> B = np.arange(6).reshape(2,3)
>>> A
array([[0, 1],
[2, 3],
[4, 5]])
>>> B
array([[0, 1, 2],
[3, 4, 5]])
>>> np.matmul(A,B)
array([[ 3, 4, 5],
[ 9, 14, 19],
[15, 24, 33]])
矩阵乘积服从分配率
$A(B+C)=AB+AC$ 、结合律$A(BC)=(AB)C$,但不满足交换律$AB = BA$。矩阵乘积的转置满足:$(AB) ^\top = B^ \top A ^ \top$
- 元素对应运算(Element-wise Operation):针对形状相同张量的运算统称,包括元素对应乘积、相加等,即对两个张量相同位置的元素进行加减乘除等运算。
>>> A = np.arange(6).reshape(3,2)
>>> A*A
array([[ 0, 1],
[ 4, 9],
[16, 25]])
>>> A + A
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
>>> A + A
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
在numpy和tensorflow等运算库中,通常将element-wise operation的符号记为对应的四则运算符号,例如A*B表示的是element-eise product,而矩阵乘法则用matmul表示
- 逆矩阵:方阵$\boldsymbol{A}$的逆矩阵记为$\boldsymbol{A}^{-1}$,它满足$\boldsymbol{A*A}^{-1}=\boldsymbol{I}$,任意向量与单位矩阵相乘都为其本身
$\boldsymbol{I x} = \boldsymbol{x}$ ,示例如下:
>>> A = np.arange(4).reshape(2,2)
>>> A
array([[0, 1],
[2, 3]])
>>> np.linalg.inv(A)
array([[-1.5, 0.5],
[ 1. , 0. ]])
-
线性无关:一组向量
$\boldsymbol{v_1},···,\boldsymbol{v_p}$ 称为线性无关的,若向量方程$x_1 \boldsymbol{v_1}+x_2 \boldsymbol{v_2}+···+x_p \boldsymbol{v_p} = \boldsymbol{0}$ 仅有平凡解(零解)。若存在不全为0的权$c_1,c_2,···,c_p$ 使得$c_1 \boldsymbol{v_1} + c_2 \boldsymbol{v_2}+···+ c_p \boldsymbol{v_p} = \boldsymbol{0}$ ,则这组向量为线性相关的。 -
范数:用于衡量向量大小
$L^p$ 范数定义为:$||\boldsymbol{x}||_p = (\sum_i |x_i|^{p})^{1/p}$,其中$p \in \mathbb{R}$ ,$p \ge 1$。-
当
$p = 2$ ,$L^2$ 范数为欧几里得范数。平方$L^2$ 范数也经常用于衡量向量大小,可简单用点积计算:$\boldsymbol{x}^\top\boldsymbol{x}$。 -
当
$p = 1$ ,$L^1$ 范数可简化为$||\boldsymbol{x}||_1 = \sum_i |\boldsymbol{x_i}|$。在零和非零元素之间的差异非常重要时,通常使用$L^1$ 范数,也经常用于表示非零元素数目的替代函数。 -
当
$p = \infty$ ,$L^\infty$ 范数(最大范数)表示向量中最大幅值的元素的绝对值$||x||_\infty = max_i {|x_i|}$
-
>>> A = np.arange(4).reshape(2,2)
>>> A
array([[0, 1],
[2, 3]])
>>> np.linalg.norm(A,ord=2) #计算矩阵2的范数
3.702459173643833
>>> np.linalg.norm(A,ord=1) #计算矩阵1的范数
4.0
>>> np.linalg.norm(A,ord=np.inf) #计算矩阵无穷的范数
5.0
向量
$\boldsymbol{x}$ 的范数衡量从原点到点$\boldsymbol{x}$ 的距离,为满足以下性质的任意函数:
$f( \boldsymbol{x}) = 0 \Rightarrow \boldsymbol{x} = \boldsymbol{0}$ ;
$f(\boldsymbol{x + y}) \le f(\boldsymbol{x}) + f(\boldsymbol{y})$ ; 三角不等式
$\forall \alpha \in \mathbb{R},f(a\boldsymbol{x}) = |a|f(\boldsymbol{x})$
- 特征分解:使用最广的矩阵分解之一,即将矩阵(方阵)分解成一组特征向量与特征值。假设方阵$A$有n个线性无关的特征向量${v_1,v_2,\cdots,v_n}$, 对应着特征值${\lambda_1,\lambda_2,\cdots,\lambda_n}$, 将特征向量连成一个矩阵$V$, 那么$A$的特征分解可以写为$A=Vdiag(\lambda)V^{-1}$.
然而不是每一个矩阵都可以进行特征分解。特别地,每个实对称矩阵都可以分解成实特征向量和实特征值:$A=Qdiag(\lambda)Q^T.$, 其中$Q$是正交矩阵,也就是满足$QQ^T=I$.
在python中,求矩阵的特征值和特征向量实例如下:
>>> A = np.arange(4).reshape(2,2)
>>> A
array([[0, 1],
[2, 3]])
>>> eigvals,eigvectors = np.linalg.eig(A)
>>> eigvals
array([-0.56155281, 3.56155281])
>>> eigvectors
array([[-0.87192821, -0.27032301],
[ 0.48963374, -0.96276969]])
-
奇异值分解:Singular value decmposition,SVD。
$\boldsymbol{A} = \boldsymbol{U} \boldsymbol{D}\boldsymbol{V}^{\top}$ ,$\boldsymbol{A}$ 为$m \times n$ 的矩阵$\boldsymbol{U}$ 为$m \times m$ 的矩阵,列向量为左奇异向量,为$\boldsymbol{A}\boldsymbol{A}^{\top}$ 的特征向量。$\boldsymbol{D}$ 为$n \times n$ 的矩阵,对角线上非零元素为奇异值,$\boldsymbol{A}^{\top}\boldsymbol{A}$ 的特征值的平方根,也是$\boldsymbol{A}\boldsymbol{A}^{\top}$ 特征值的平方根。$\boldsymbol{V}$ 为$m \times n$ 的矩阵,列向量为右奇异向量,为$\boldsymbol{A}^{\top}\boldsymbol{A}$ 的特征向量。
>>> A = np.array([[2,4],[1,3],[0,0],[0,0]])
>>> U,D,V = np.linalg.svd(A)
>>> U
array([[-0.81741556, -0.57604844, 0. , 0. ],
[-0.57604844, 0.81741556, 0. , 0. ],
[ 0. , 0. , 1. , 0. ],
[ 0. , 0. , 0. , 1. ]])
>>> D
array([5.4649857 , 0.36596619])
>>> V
array([[-0.40455358, -0.9145143 ],
[-0.9145143 , 0.40455358]])
-
迹运算:迹运算返回的是方阵对角元素的和:Tr(
$A$ )=$\sum\limits_iA_{ii}$. -
迹运算的性质:
1.矩阵转置之后迹保持不变:Tr($A$ )=Tr($A^T$ ).
2.多个矩阵相乘的顺序不改变乘积矩阵的迹(在保持乘积矩阵仍然是方阵情况下),例如假设矩阵$A\in R^{m\times n}$,$B\in R^{n\times m}$,则Tr($A$ )=Tr($BA$ ). -
迹运算实例如下:
>>> A = np.arange(4).reshape(2,2)
>>> A
array([[0, 1],
[2, 3]])
>>> np.trace(A)
3
- 行列式:记作det(
$A$ ).行列式等于特征值的乘积。行列式的绝对值可以看作是一个n维平行体的体积。实例如下:
>>> A = np.arange(4).reshape(2,2)
>>> A
array([[0, 1],
[2, 3]])
>>> np.linalg.det(A)
-2.0
- 主成分分析(PCA):在python中,可以利用sklearn库中的PCA函数进行主成分分析,实例如下
from sklearn.decomposition import PCA #加载PCA算法包
from sklearn.datasets import load_iris #加载数据
data=load_iris()
x=data.data
pca=PCA(n_components=k) #加载PCA算法,设置降维后主成分数目为k
reduced_x=pca.fit_transform(x) #对样本进行降维
ratio=pca.explained_variance_ratio_ #计算各个主成分贡献的方差比例,一般要求前k个主成分方差累积贡献率达80%以上