问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

从度量张量、相关系数生成椭圆参数

创作时间:
作者:
@小白创作中心

从度量张量、相关系数生成椭圆参数

引用
CSDN
1.
https://blog.csdn.net/apd_csdn/article/details/143392095

度量张量、高斯随机变量相关系数都可以用椭圆来进行可视化,下面讲一下两者的本质和联系,以及绘制椭圆可视化过程中的常见问题。都以二维平面的椭圆为例。

度量张量

又叫黎曼度量,物理学译为度规张量,是指一用来衡量度量空间中距离,面积及角度的二阶张量。$x_i$为欧几里得空间中一点的坐标,在其构成的局部坐标系统中,对$x_i$附近(切空间)的的点有$x = x_i + dx$,度量张量可记为$G(x_i)$,满足

$$
ds^2 = dx^T G(x_i )dx
$$

如果对这个度量张量进行可视化,可以用$dx^T G(x_i) dx = 1$的椭圆来绘制。


图1. 一个典型的黎曼空间中度量张量的椭圆可视化,其中不同位置的张量有显著差别

相关系数

对于多维高斯随机变量$X = (X_1, X_2, ..., X_n)$,其概率密度函数是

$$
p(X) = \frac{1}{{(2\pi)}^{\frac{n}{2}}\left| \Sigma\right|^{\frac{1}{2}} }\exp{-\frac{1}{2}(X-\mu)^T\Sigma^{-1}(X-\mu)}
$$

该分布的图像包含多个同心椭圆构成的等值面,选取其中的一个椭圆进行绘制,就是要绘制$(X-\mu)^T\Sigma^{-1}(X-\mu) = 1$

必须知道其中的相关系数矩阵$\Sigma$,才能画出椭圆。


图2. 二维高斯分布概率密度函数可视化

二者的区别和联系:度量张量是几何概念,高斯分布的相关系数是统计概念。对于一个含有随机变量的系统而言,如果其观测结果是非均匀的,观测空间可以是一个概率分布描述的空间,也可以是一个度量张量刻画的几何流形对应空间。具体的例子如机器学习特征的高维流形、人的色彩感知平面等。注意$G = \Sigma^{-1}$,具有对称性。

椭圆参数

通常用方程$x^TGx=1$表示一个椭圆,所以$G$中就包含了全部所需参数。然而,很多画椭圆函数(例如python中plt.patch.Ellipse)提供的参数是长轴长、短轴长和逆时针长轴旋转角度。如何从$G$解析这些参数是一个关键问题。

考虑二维平面上的椭圆,有长半轴长度$a$,短半轴长度$b$,逆时针逆时针长轴旋转角度$\theta$。对于$\theta = 0$的普通椭圆,容易写出

$$
\frac{x^2}{a^2}+\frac{y^2}{b^2}=1
$$

对应的$G$就是:

$$
\begin{bmatrix}
\frac{1}{a^2} & 0 \
0 & \frac{1}{b^2}
\end{bmatrix}
$$

可以直接从对角阵元素计算得到长短轴半轴长度。

然而,当旋转角度不为0时,我们考虑当前椭圆是由普通椭圆旋转而来的,旋转前的椭圆上某点坐标记为$Y$,有

$$
Y = Q^TX
$$

其中$Q^T$为

$$
\begin{bmatrix}
\cos \theta & \sin \theta \
-\sin \theta & \cos \theta
\end{bmatrix}
$$

$Y$满足椭圆方程$Y^T U Y=1$,$U = diag(\frac{1}{a^2},\frac{1}{b^2})$

进一步有$X^TQUQ^TX=1$,所以可以得到$G = QUQ^T$。对称矩阵$G$分解得到这种形式,只需要做正交对角化就可以了(或调用SVD分解的函数)。最后,根据分解出的$U$求$a, b$,根据$Q$求$\theta$。

但是,这里有个坑,分解出的矩阵$Q$只保证了列向量的是特征向量、满足正交性。这样的向量有两种可能解:$(\cos \theta, \sin \theta)$和$(-\cos \theta, -\sin \theta)$。所以,求解$\theta$应该用$arctan( \frac{q_{12}}{q_{11}})$,解出的$\hat{\theta}=\theta+k\pi$,对椭圆而言旋转$\pi$没有任何变化。

代码举例:从相关系数给出椭圆参数,可直接用于plt画椭圆

import numpy as np 
import matplotlib.pyplot as plt
import matplotlib.patches as patches

def sigma_to_abtheta(mat22):
    U,Sigma,V = np.linalg.svd(mat22,full_matrices=True)
    a = np.sqrt(Sigma[0])
    b = np.sqrt(Sigma[1])
    theta = np.arctan(U[0,1]/U[0,0]) # U = QT, row is feature vector
    return a,b,theta

mat22 = np.array([[ 0.00287626, -0.00084234],
 [-0.00084234,  0.00604468]])

a,b,theta = sigma_to_abtheta(mat22)

ellipse_1 = patches.Ellipse((0.5,0.5),
                                 width=2*a, height=2*b, 
                                 facecolor='#00FF00', angle=theta/np.pi*180., 
                                 edgecolor='#00FF00', linewidth=1, fill=False)

fig,ax = plt.subplots()
ax.add_patch(ellipse_1)
plt.show()
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号