Python 创建多元斜正态分布

Python 创建多元斜正态分布,python,matplotlib,gaussian,surface,Python,Matplotlib,Gaussian,Surface,如何创建多元斜正态函数,然后通过输入x和y点,我们可以在3d(x、y和z坐标)中创建曲面图。您可以通过添加sigma协方差矩阵为多元正态分布添加方向: import numpy as np from scipy.stats import multivariate_normal mu = [20,20] # center of distribution. sigma_size_top, sigma_size_bot = np.random.uniform(5, 20, size=2) cov_m

如何创建多元斜正态函数,然后通过输入x和y点,我们可以在3d(x、y和z坐标)中创建曲面图。

您可以通过添加sigma协方差矩阵为多元正态分布添加方向:

import numpy as np
from scipy.stats import multivariate_normal

mu = [20,20] # center of distribution.
sigma_size_top, sigma_size_bot = np.random.uniform(5, 20, size=2)
cov_max = np.sqrt(sigma_size_top * sigma_size_bot) * 0.9 # Cov max can't be larger than sqrt of the other elements
sigma_cov = np.random.uniform(-cov_max, cov_max)
sigma = np.array([[sigma_size_top, sigma_cov],[sigma_cov, sigma_size_bot]])
然后将其传递到您的
多变量\u normal

dist = multivariate_normal(mu, sigma)
通过以下方式将其放入二维映射:

x = np.linspace(0, 40, 41)
y = x.copy()
xx, yy = np.meshgrid(x, y)
pos = np.empty(xx.shape + (2,))
pos[:, :, 0] = xx
pos[:, :, 1] = yy
my_map = dist.pdf(pos)

然后在矩阵上有一个偏斜的多元正态分布。我建议您缩放此矩阵,因为值会很小。

您可以通过添加西格玛协方差矩阵为多元正态分布添加方向:

import numpy as np
from scipy.stats import multivariate_normal

mu = [20,20] # center of distribution.
sigma_size_top, sigma_size_bot = np.random.uniform(5, 20, size=2)
cov_max = np.sqrt(sigma_size_top * sigma_size_bot) * 0.9 # Cov max can't be larger than sqrt of the other elements
sigma_cov = np.random.uniform(-cov_max, cov_max)
sigma = np.array([[sigma_size_top, sigma_cov],[sigma_cov, sigma_size_bot]])
然后将其传递到您的
多变量\u normal

dist = multivariate_normal(mu, sigma)
通过以下方式将其放入二维映射:

x = np.linspace(0, 40, 41)
y = x.copy()
xx, yy = np.meshgrid(x, y)
pos = np.empty(xx.shape + (2,))
pos[:, :, 0] = xx
pos[:, :, 1] = yy
my_map = dist.pdf(pos)
然后在矩阵上有一个偏斜的多元正态分布。我建议您缩放此矩阵,因为值很小。

我写了一篇关于此的文章,但下面是完整的工作代码:

从matplotlib导入cm
将matplotlib.pyplot作为plt导入
将numpy作为np导入
从scipy.stats导入(作为mvn的多变量正常值,
(标准)
类多元_-skewnorm:
定义初始值(self、a、cov=None):
self.dim=len(a)
self.a=np.asarray(a)
self.mean=np.zero(self.dim)
self.cov=np.eye(self.dim),如果cov不是其他np.asarray(cov)
def pdf(self,x):
返回np.exp(self.logpdf(x))
def logpdf(self,x):
x=mvn.\u进程\u分位数(x,self.dim)
pdf=mvn(self.mean,self.cov).logpdf(x)
cdf=norm(0,1).logcdf(np.dot(x,self.a))
返回np.log(2)+pdf+cdf
xx=np.linspace(-2,2100)
yy=np.linspace(-2,2100)
十、 Y=np.meshgrid(xx,yy)
位置=np.dstack(X,Y))
图=plt.图(图尺寸=(10,10),dpi=150)
轴=[
图添加_子图(1,3,1,projection='3d'),
图添加_子图(1,3,2,projection='3d'),
图添加_子图(1,3,3,投影='3d')
]
对于压缩中的轴([[0,0],[5,1],[1,5]],轴):
Z=多元随机变量(a=a).pdf(pos)
X.plot_曲面(X,Y,Z,cmap=cm.viridis)
ax.set_title(r'$\alpha$=%s,cov=$\mathbf{I}$'%str(a),fontsize=18)
该代码将生成以下图形:

我写了一篇关于这一点的文章,但下面是完整的工作代码:

从matplotlib导入cm
将matplotlib.pyplot作为plt导入
将numpy作为np导入
从scipy.stats导入(作为mvn的多变量正常值,
(标准)
类多元_-skewnorm:
定义初始值(self、a、cov=None):
self.dim=len(a)
self.a=np.asarray(a)
self.mean=np.zero(self.dim)
self.cov=np.eye(self.dim),如果cov不是其他np.asarray(cov)
def pdf(self,x):
返回np.exp(self.logpdf(x))
def logpdf(self,x):
x=mvn.\u进程\u分位数(x,self.dim)
pdf=mvn(self.mean,self.cov).logpdf(x)
cdf=norm(0,1).logcdf(np.dot(x,self.a))
返回np.log(2)+pdf+cdf
xx=np.linspace(-2,2100)
yy=np.linspace(-2,2100)
十、 Y=np.meshgrid(xx,yy)
位置=np.dstack(X,Y))
图=plt.图(图尺寸=(10,10),dpi=150)
轴=[
图添加_子图(1,3,1,projection='3d'),
图添加_子图(1,3,2,projection='3d'),
图添加_子图(1,3,3,投影='3d')
]
对于压缩中的轴([[0,0],[5,1],[1,5]],轴):
Z=多元随机变量(a=a).pdf(pos)
X.plot_曲面(X,Y,Z,cmap=cm.viridis)
ax.set_title(r'$\alpha$=%s,cov=$\mathbf{I}$'%str(a),fontsize=18)
该代码将生成以下图形:


我想这就是你需要的。谢谢你!但我怎么能给它加上歪斜呢?通过调节协方差?@SohrabSalimian,你有机会解决你的问题吗?我正在寻找完全相同的东西。我在库中发现了一些在R中完成的工作,我刚刚意识到scipy.stats.skewnorm需要2dinput@simon,这不是你想要的
skewnorm(a=1).pdf(x=[1,1])
返回两个概率,而不是一个。因此,它使用相同的单变量分布来评估
x
的每个分量。我想这就是你需要的谢谢你!但我怎么能给它加上歪斜呢?通过调节协方差?@SohrabSalimian,你有机会解决你的问题吗?我正在寻找完全相同的东西。我在库中发现了一些在R中完成的工作,我刚刚意识到scipy.stats.skewnorm需要2dinput@simon,这不是你想要的
skewnorm(a=1).pdf(x=[1,1])
返回两个概率,而不是一个。因此,它使用相同的单变量分布来评估
x
的每个组件。我认为这很有意义。你能提供完整的代码来实现这一点吗?我从未使用过这个库,所以我在实现itdist=multivariable\u normal(mu,sigma)时遇到一些困难ValueError:输入矩阵必须是正半定义的。我在图表中也看不到倾斜,我希望它倾斜到外围,但在这个图表中我看不到。谢谢你的帮助,如果你不能提供更多的帮助我完全理解我很感激:)@SohrabSalimian这个错误是我的错误,现在已经修复了。
cov_max
必须小于对角线乘法的sqrt,并以此运行。显示你的图像由代码> PLT。IsSee(MyxMax)< /Cl> >我得到的输出是一个小圆圈在图的中间,我再也看不见歪斜的领域,但我会继续努力。如果您有任何其他建议,请随时提供,甚至可以向我展示您在plt.imshow(my_map)时的可视化效果。我认为这很有意义。您是否能够提供完整的代码来实现这一点,我从未使用过此库,因此我在实现itdist=Multivariable_normal(mu,sigma)时遇到一些困难ValueError:输入矩阵必须是正半定义的。我在图表中也看不到扭曲,我希望它扭曲到周期中