程序问答   发布时间:2022-05-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何从 Python 中的非正态多变量分布生成样本?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何从 Python 中的非正态多变量分布生成样本??

开发过程中遇到如何从 Python 中的非正态多变量分布生成样本?的问题如何解决?下面主要结合日常开发的经验,给出你关于如何从 Python 中的非正态多变量分布生成样本?的解决方法建议,希望对你解决如何从 Python 中的非正态多变量分布生成样本?有所启发或帮助;

我有一个包含 10 个变量和 100 行的输入数据帧 df_input。这些数据不是正态分布的。 我想生成一个包含 10 个变量和 10,000 行的输出数据帧,以便新数据帧的协方差矩阵和均值与原始数据帧的协方差矩阵和均值相同。输出变量不应呈正态分布,而应具有与输入变量相似的分布。 那是: Cov(df_output) = Cov(df_input) 和 平均值(df_输出)=平均值(df_输入) 是否有一个 Python 函数可以做到这一点?

注意:np.random.multivariate_normal(mean_input,Cov_input,10000) 几乎可以做到这一点,但输出变量是正态分布的,而我需要它们与输入具有相同(或相似)的分布。

解决方法

您是否虑过使用 GAN(生成对抗网络)?比仅使用预定义的函数需要更多的努力,但本质上它完全符合您的希望。这是原始论文:https://arxiv.org/abs/1406.2661

有许多 PyTorch/Tensorflow 代码可供您下载并适合您的目的,例如这个:https://github.com/eriklindernoren/PyTorch-GAN

这里还有一篇博文,我发现它对 GAN 的介绍很有帮助。 https://medium.com/ai-society/gans-from-scratch-1-a-deep-introduction-with-code-in-pytorch-and-tensorflow-cb03cdcdba0f

对于这个问题,GAN 可能有点矫枉过正,有更简单的方法可以放大样本量,在这种情况下,我很想了解它们。

,

更新

我刚刚注意到您提到了 np.random.multivariate_normal...它一下子就相当于下面的 gen_like()

我将把它留在这里是为了帮助人们理解这个机制,但总结一下:

  1. 您可以将经验分布的均值和协方差与(旋转、缩放、平移)正态相匹配;
  2. 为了更好地匹配更高的时刻,您应该查看连接词。

原答案

由于您只对匹配两个第一矩(均值、方差)感兴趣,您可以使用简单的 PCA 来获得初始数据的合适模型。请注意,新生成的数据将是一个正常的椭圆体,经过旋转、缩放和平移,以匹配初始数据的经验均值和协方差。

如果您想要对原始发行版进行更复杂的“复制”,那么您应该查看我在评论中所说的 Copula。

因此,仅针对前两个时刻,假设您的输入数据为 d0

from sklearn.decomposition import PCA

def gen_like(d0,n):
    pca = PCA(n_components=d0.shape[1]).fit(d0)
    z0 = pca.transform(d0)  # z0 is centered and uncorrelated (cov is diagonal)
    z1 = np.random.normal(size=(n,d0.shape[1])) * np.std(z0,0)

    # project BACk to input space
    d1 = pca.inverse_transform(z1)
    return d1

例:

# generate some random data

# arbitrary transformation matrix
F = np.array([
    [1,2,3],[2,1,4],[5,])
d0 = np.random.normal(2,4,size=(10000,3)) @ F.T

np.mean(d0,0)
# ex: array([12.12791066,14.10333273,17.95212292])

np.cov(d0.T)
# ex: array([[225.09691912,257.39878551,259.40288019],#            [257.39878551,338.34087242,373.4773562 ],#            [259.40288019,373.4773562,566.29288861]])
# try to match mean,variance of d0
d1 = gen_like(d0,10000)

np.allclose(np.mean(d0,0),np.mean(d1,rtol=0.1)
# often True (but not guaranteed)

np.allclose(np.cov(d0.T),np.cov(d1.T),rtol=0.1)
# often True (but not guaranteed)

有趣的是,您可以在圆孔中放置一个方钉(即,证明实际上只是平均值匹配,方差不匹配,而不是更高的矩):

d0 = np.random.uniform(5,10,size=(1000,3)) @ F.T
d1 = gen_like(d0,rtol=0.1)
# often True (but not guaranteed)
,

您是否尝试查看 NumPy 文档?: https://numpy.org/doc/stable/reference/random/generated/numpy.random.multivariate_normal.html

,

正如许多人所建议的那样,最好的方法确实是使用 Copulas。下面的链接中有一个简单的描述,它也提供了一个简单的 python 代码。 该方法保留协方差,同时增加数据。它允许泛化到非对称或非正态分布。感谢大家的帮助。

https://sdv.dev/Copulas/tutorials/03_Multivariate_DiStributions.html。

大佬总结

以上是大佬教程为你收集整理的如何从 Python 中的非正态多变量分布生成样本?全部内容,希望文章能够帮你解决如何从 Python 中的非正态多变量分布生成样本?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。