(1)NumPy基本使⽤,矩阵运算及矩阵求导
关于NumPy中array和Mat两种对象类型的选取,此处进⾏简单说明:
NumPy中的matrix类型对象和MATLAB中的matrix类型等价,和NumPy中数组类型对象底层基本结构不同;
在NumPy中,针对⼤规模数据,array对象的计算速度要快于Mat类型对象,故⼀般使⽤array进⾏计算
矩阵类型对象可以通过运算符直接进⾏矩阵乘法,⽽⼆维数组要进⾏矩阵乘法(及其他矩阵运算),则必须要使⽤包括linalg(线性代数运算)模块在内的相关函数a1 = np.arange(1, 7).reshape(2, 3)
print(a1)
print(a1.T) # 转置
(3)) # 创建单位矩阵
a = np.arange(1, 6)
print(np.diag(a)) # 创建对⾓矩阵,将输⼊的array的数值转换为对⾓矩阵
print(np.diag(a, -1)) # 对⾓线向下偏移⼀位,此时变为6x6⽅阵
a2 = np.arange(1,10).reshape(3, 3)
iu(a2)) # 取上三⾓矩阵
iu(a2, -1)) # 上三⾓矩阵向左下⾓偏移⼀位
iu(a2, 1)) # 上三⾓矩阵向右上⾓偏移⼀位
il(a2)) # 取下三⾓矩阵,剩余操作与上三⾓矩阵类似
print(a2 * a2) # 两个规格相同的矩阵,对应位置元素相乘
# 向量的点积,向量或矩阵对应位置元素相乘后相加
print(np.dot(a, a))
print((a*a).sum())
print(np.vdot(a, a))
print(np.inner(a, a))
# 矩阵点积,只有vdot⼀种⽅式实现
print(np.vdot(a2, a2))
# 矩阵乘法,有matmul,dot,@三种⽅法
print(np.matmul(a1, a2))
print(np.dot(a1, a2))
print(a1 @ a2)
# 计算矩阵的迹:主对⾓线元素之和
# 对于矩阵的迹,计算不需要是⽅阵
ace(a2))
# 计算矩阵的秩矩阵中⾏或列2的极⼤线性⽆关数
print(a2)
print(np.linalg.matrix_rank(a2))
# 矩阵的⾏列式,矩阵若不满秩,其⾏列式为0,故也可以⽤⾏列式数值去判断是否满秩
A = np.array([[1, 1], [1, 1]])
print(np.linalg.det(A))
A = np.array([[1, 2], [4, 5]])
print(np.linalg.det(A))
# 矩阵的逆,只有矩阵满秩才有与之对应的逆矩阵
B = np.linalg.inv(A)
print(B)
print(A@B)
A = np.array([[3, 4], [9, 7]])
B = np.array([[28, 12]]).T
print(np.linalg.inv(A).dot(B))
# 矩阵求解⽅程,第⼀个参数为系数矩阵,第⼆个参数为取值矩阵
print(np.linalg.solve(A, B))
将求解⽅程组转换为求解矩阵
若有⽅程组
3w+4b-28=0\\9w+7b-12=0
令
Loading [MathJax]/jax/output/HTML-CSS/fonts/TeX/fontdata.js
A = \left [\begin{array}{cccc} 3 &4 \\ 9 &7 \\ \end{array}\right]
X = \left [\begin{array}{cccc} w \\ b \\ \end{array}\right]
B = \left [\begin{array}{cccc} 28 \\ 12 \\ \end{array}\right]
则有
A \cdot X = B
然后在矩阵⽅程左右两端同时左乘其逆矩阵,即可解出X的取值
A^{-1}AX=A^{-1}B
X=A^{-1}B
向量求导
设f(x)是⼀个关于x的函数,其中x是向量变元,并且x = [x_1, x_2,...,x_n]^T
则\frac{\partial f}{\partial x} = [\frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, ..., \frac{\partial f}{\partial x_n}]^T
⽽该表达式也被称为向量求导的梯度向量形式
\nabla _xf(x) = \frac{\partial f}{\partial x} = [\frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, ..., \frac{\partial f}{\partial x_n}]^T
常见向量求导公式
(1)
\frac{\partial a}{\partial x} = 0
(2)
\frac{\partial(x^T \cdot A)}{\partial x} = \frac{\partial(A^T \cdot x)}{\partial x} = A
(3)
\frac{\partial (x^T \cdot x)}{\partial x} = 2x,此处x^Tx也被称为向量的交叉乘积(crossprod)
(4)
\frac{\partial (x^T A x)}{x} = Ax + A^Tx
最⼩⼆乘法推导过程及使⽤
令$w = [w_1,w_2,...w_d]^T$,$x = [x_1,x_2,...x_d]^T$,则上式可写为\\f(x) = w^Tx+b
并且,假设现在总共有m条观测值,$x^{(i)} = [x_1^{(i)}, x_2^{(i)},...,x_d^{(i)}]$,则带⼊模型可构成m个⽅程:\\ \left [\begin{array}{cccc} w_1x_1^{(1)}+w_2x_2^{(1)}+...+w_dx_d^{(1)}+b \\ w_1x_1^{(2)}+w_2x_2^{(2)}+...+w_dx_d^{(2)}+b \\ . \\ . \\ . \\ w_1x_1^{(m)}+w_2x_2^{(m)}+...+w_dx_d^{(m)}+b \\ \end{array}\right] = \left [\begin{array}{cccc} \hat y_1 \\ \hat y_2 \\ . \\ . \\ . \\ \hat y_m \\ \end{array}\right]
我们令
\hat w = [w_1,w_2,...,w_d,b]^T\\\hat x = [x_1,x_2,...,x_d,1]^T\\\hat X = \left [\begin{array}{cccc} x_1^{(1)} &x_2^{(1)} &... &x_d^{(1)} &1 \\ x_1^{(2)} &x_2^{(2)} &... &x_d^{(2)} &1 \\ ... &... &... &... &1 \\ x_1^{(m)} &x_2^{(m)} &... &x_d^{(m)} &1 \\ \end{array}\right]\\ y= \left [\begin{array}{cccc} y_1 \\ y_2 \\ . \\ . \\ . \\ y_m \\ \end{array}\right]\\ \hat y = \left [\begin{array}{cccc} \hat y_1 \\ \hat y_2 \\ . \\ . \\ . \\ \hat y_m \\ \end{array}\right]
其中,
- \hat w:⽅程系数所组成的向量,并且我们将⾃变量系数和截距放到了⼀个向量;
-
\hat x:⽅程⾃变量和1共同组成的向量;
- \hat X:样本数据特征构成的矩阵,并在最后⼀列添加⼀个全为1的列;
- y:样本数据标签所构成的列向量;
- \hat y:预测值的列向量。
因此,上述⽅程组可改写为
\hat X \cdot \hat w = \hat y
线性模型可进⼀步改写为
f(\hat x) = \hat w^T \cdot \hat x
构造损失函数
在⽅程组的矩阵表⽰基础上,我们可以以SSE作为损失函数基本计算流程构建关于\hat w的损失函数:
SSELoss(\hat w) = ||y - X\hat w||_2^2 = (y - X\hat w)^T(y - X\hat w)
需要补充两点基础知识:
向量的2-范数计算公式
上式中,||y - X\hat w^T||_2为向量的2-范数的计算表达式。向量的2-范数计算过程为各分量求平⽅和再进⾏开平⽅。例如a=[1, -1,],则||a||_2= \sqrt{1^2+(-1)^2}=\sqrt{2}。
2-范数计算转化为内积运算
向量的2-范数计算结果其实就是向量(将其是做矩阵)的交叉乘积计算结果后开平⽅。例如,a=[1, -1],则a的交叉乘积为a \cdot a^T = [1, -1] \cdot \left [\begin{array}{cccc} 1 \\ -1 \\ \end{array}\right]=2,开平⽅后等于其2-范数计算结果。
最⼩⼆乘法求解损失函数的⼀般过程
矩阵转置的⼀些运算规则:
(A-B)^T=A^T-B^T\\(AB)^T=B^TA^T
接下来,对SSELoss(w)求导并令其等于0:
matlab求导
\begin{aligned} \frac{SSELoss(\hat w)}{\partial{\boldsymbol{\hat w}}} &= \frac{\partial{||\boldsymbol{y} - \boldsymbol{X\hat w}||_2}^2}{\partial{\boldsymbol{\hat w}}} \\ &=
\frac{\partial(\boldsymbol{y} - \boldsymbol{X\hat w})^T(\boldsymbol{y} - \boldsymbol{X\hat w})}{\partial{\boldsymbol{\hat w}}} \\ & =\frac{\partial(\boldsymbol{y}^T - \boldsymbol{\hat w^T X^T})(\boldsymbol{y} - \boldsymbol{X\hat w})}{\partial{\boldsymbol{\hat w}}}\\ &=\frac{\partial(\boldsymbol{y}^T\boldsymbol{y} - \boldsymbol{\hat w^T X^Ty}-
\boldsymbol{y}^T\boldsymbol{X \hat w} +\boldsymbol{\hat w^TX^T}\boldsymbol{X\hat w})}{\partial{\boldsymbol{\hat w}}}\\ & = 0 - \boldsymbol{X^Ty} - \boldsymbol{X^Ty}+X^TX\hat w+ (X^TX)^T\hat w \\ &= 0 - \boldsymbol{X^Ty} - \boldsymbol{X^Ty} + 2\boldsymbol{X^TX\hat w}\\ &= 2(\boldsymbol{X^TX\hat w} - \boldsymbol{X^Ty}) = 0 \end{aligned}
即X^TX\hat w = X^Ty
要使得此式有解,等价于X^TX(也被称为矩阵的交叉乘积crossprod存在逆矩阵,若存在,则可解出
\hat w = (X^TX)^{-1}X^Ty
最⼩⼆乘的简单实现
利⽤矩阵表达式进⾏改写
特征矩阵:
\hat X = \left [\begin{array}{cccc} 1 &1 \\ 3 &1 \\ \end{array}\right]
标签矩阵:
y = \left [\begin{array}{cccc} 2 \\ 4 \\ \end{array}\right]
参数向量:
\hat w = \left [\begin{array}{cccc} w \\ b \\ \end{array}\right]
求解公式:
\begin{aligned} \hat w &= (X^TX)^{-1}X^Ty \\ &= (\left [\begin{array}{cccc} 1 &1 \\ 3 &1 \\ \end{array}\right]^{T} \left [\begin{array}{cccc} 1 &1 \\ 3 &1 \\ \end{array}\right])^{-1} \left
[\begin{array}{cccc} 1 &1 \\ 3 &1 \\ \end{array}\right]^{T} \left [\begin{array}{cccc} 2 \\ 4 \\ \end{array}\right] \\ \end{aligned}
代码实现:
X = np.array([[1, 1], [3, 1]])
y = np.array([2, 4]).reshape(2, 1)
print(np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y))
# 解出 w与b的值
# NumPy独⽴的最⼩⼆乘法计算函数
# 返回的第⼀个参数为最⼩⼆乘计算结果,第⼆个参数为SSE结算结果,第三个为矩阵X的秩,第四个为矩阵X的奇异值
print(np.linalg.lstsq(X, y, rcond=-1))
发布评论