如何创建多元偏斜法线函数,然后通过输入x和y点,我们可以在3d(x,y和z坐标)中创建表面图
答案 0 :(得分:1)
我为此写了一个 blog post,但这里是完整的工作代码:
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import (multivariate_normal as mvn,
norm)
class multivariate_skewnorm:
def __init__(self, a, cov=None):
self.dim = len(a)
self.a = np.asarray(a)
self.mean = np.zeros(self.dim)
self.cov = np.eye(self.dim) if cov is None else np.asarray(cov)
def pdf(self, x):
return np.exp(self.logpdf(x))
def logpdf(self, x):
x = mvn._process_quantiles(x, self.dim)
pdf = mvn(self.mean, self.cov).logpdf(x)
cdf = norm(0, 1).logcdf(np.dot(x, self.a))
return np.log(2) + pdf + cdf
xx = np.linspace(-2, 2, 100)
yy = np.linspace(-2, 2, 100)
X, Y = np.meshgrid(xx, yy)
pos = np.dstack((X, Y))
fig = plt.figure(figsize=(10, 10), dpi=150)
axes = [
fig.add_subplot(1, 3, 1, projection='3d'),
fig.add_subplot(1, 3, 2, projection='3d'),
fig.add_subplot(1, 3, 3, projection='3d')
]
for a, ax in zip([[0, 0], [5, 1], [1, 5]], axes):
Z = multivariate_skewnorm(a=a).pdf(pos)
ax.plot_surface(X, Y, Z, cmap=cm.viridis)
ax.set_title(r'$\alpha$ = %s, cov = $\mathbf{I}$' % str(a), fontsize=18)
该代码将生成此图:
答案 1 :(得分:0)
您可以通过添加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]])
然后将其传递到您的multivariate_normal
:
dist = multivariate_normal(mu, sigma)
通过以下方式将其放入2D映射中:
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)
然后,您将在矩阵上具有倾斜的多元正态分布。我建议您缩放此矩阵,因为值会很小。