高斯多元分布 - 第 1 部分
多元高斯分布 - 第 1 部分
引言
在本文中,我们将探讨多元高斯分布。
- 多元高斯分布由均值向量 µ 和协方差矩阵 Σ 参数化。fx(x1, …, xk) = 1 / √(2π)k |Σ| exp(−1/2 (x − μ)T Σ−1 (x − μ)) ,
其中
μ 是一个 Nx1 的均值向量
Σ 是一个 NxN 的协方差矩阵
|Σ| 是 Σ 的行列式 - 多元高斯分布也被用作向量 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow class="MJX-TeXAtom-ORD"> <mi>X 的概率密度函数。
- 一种朴素的实现方法是直接按照公式进行计算以获得结果。
- 高斯分布的定义
- 由于我将使用大量的 OpenCV 转换例程,这些例程是为 OpenCV
cv::Mat
数据结构定义的,转换为Eigen::MatrixXf
数据结构。 - 在加载协方差矩阵时,也会计算行列式、逆矩阵等,这些将在后续的概率计算中用到。
void setMean(Mat &v) { Map<Eigen::Matrix<float,Dynamic,Dynamic,Eigen::RowMajor> > mappedMat((float *)v.data(),1,v.size()) ; _mu=mappedMat; } void setSigma(cv::Mat &v) { Map<Eigen::Matrix<float,Dynamic,Dynamic,Eigen::RowMajor> > mappedMat((float *)v.data,v.rows,v.cols) ; _Sigma=mappedMat; _dim=v.rows; _det=_Sigma.determinant(); _scale=1.f/(pow(2*PI*_dim*_det,0.5)); _invsigma=_Sigma.inverse(); } MatrixXf setData(cv::Mat &v) { Map<Eigen::Matrix<float,Dynamic,Dynamic,Eigen::RowMajor> > mappedMat((float *)v.data,1,v.cols) ; MatrixXf ref=mappedMat; return ref; }
- 概率计算只是简单地写出公式。
void validate(float &res) { if(res<0) res=0; if(res>1) res=1; if(isnan(res)) res=0; } float Prob(Mat &x) { MatrixXf tmp=setData(x); float res=0; MatrixXf tmp1=(tmp-_mu); MatrixXf tmp2=tmp1*_invsigma*tmp1.transpose(); res=scale*tmp2(0,0); validate(res); return res; }
- 协方差矩阵是正半定且对称的。
- 对称正定矩阵 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi mathvariant="bold">Σ 的 Cholesky 分解将其分解为下三角矩阵 L 及其转置的乘积。
- 因此,乘积 <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> <mtable columnalign="right center left" columnspacing="0 thickmathspace" displaystyle="true" rowspacing="3pt"> <mtr> <mtd> <mtd> <mi mathvariant="bold">Σ=LLT
Σ−1=(LLT)−1=L−TL−1
yTΣ−1y
yTΣ−1y
yTL−TL−1y
(L−1y)T(L−1y)<mtr><mtd><mrow><mo> - 因此,我们只需要计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow> <mo>(L−1y)<mo> 并取其转置。
- 因此,我们可以对协方差矩阵执行 Cholesky 分解来找到 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow class="MJX-TeXAtom-ORD"> <mi mathvariant="bold">L。
- 然后,我们取 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow class="MJX-TeXAtom-ORD"> <mi mathvariant="bold">L 的逆。
float Prob(Mat &x) { MatrixXf tmp=setData(x); float res=0; MatrixXf tmp1=(tmp-_mu).transpose(); tmp1=_LI*tmp1; MatrixXf tmp2=tmp1.transpose()*tmp1; res=tmp2(0,0); validate(res); return res; }
源代码
代码可以在 git 仓库 https://github.com/pi19404/OpenVision 的 ImgML/gaussian.hpp 和 ImgML.gaussian.cpp 文件中找到。
本文档的 PDF 版本可以在下面找到