根据概率分布生成随机变量

问题描述 投票:1回答:3

我已经从python数据集中提取了一些变量,我想从我的分布中生成更大的数据集。问题是我试图在保持相似行为的同时为新数据集引入一些可变性。这是我的提取数据示例,包含400个观察值:

Value    Observation Count     Ratio of Entries
1        352                    0.88
2        28                     0.07
3        8                      0.02
4        4                      0.01
7        4                      0.01
13       4                      0.01

现在,我正在尝试使用此信息来生成具有2,000个观测值的相似数据集。我知道numpy.random.choicerandom.choice函数,但是我不想使用完全相同的分布。相反,我想根据分布生成随机变量(值列),但可变性更大。我希望我的较大数据集如何显示的示例:

Value         Observation Count        Ratio of Entries
1             1763                     0.8815
2             151                      0.0755
3             32                       0.0160
4             19                       0.0095
5             10                       0.0050
6             8                        0.0040
7             2                        0.0010
8             4                        0.0020
9             2                        0.0010
10            3                        0.0015
11            1                        0.0005
12            1                        0.0005
13            1                        0.0005
14            2                        0.0010
15            1                        0.0005

因此,如果我用指数衰减函数拟合原始数据,则可以估计新分布,但是,我对连续变量不感兴趣。我该如何解决这个问题,并且有一种与我尝试做的事情相关的特定方法或数学方法吗?

python numpy math random normal-distribution
3个回答
2
投票

如果您有指数衰减,则潜在的离散概率分布为geometric distribution。 (这是连续exponential distribution的离散对应项。)这样的几何分布使用参数p并具有一次尝试成功的概率(例如偏向抛硬币)。该分布描述了获得成功所需的试验次数。

分布的预期平均值为1/p。因此,我们可以计算观测值的平均值来估计p

该函数作为scipy.stats.geom构成scipy的一部分。要对分布进行采样,请使用scipy.stats.geom

这里有一些代码演示了该方法:

geom.rvs(estimated_p, size=2000)

输出:

from scipy.stats import geom
import matplotlib.pyplot as plt
import numpy as np
from collections import defaultdict

observation_index = [1, 2, 3, 4, 7, 13]
observation_count = [352, 28, 8, 4, 4, 4]

observed_mean = sum([i * c for i, c in zip(observation_index, observation_count)]) / sum(observation_count)

estimated_p = 1 / observed_mean
print('observed_mean:', observed_mean)
print('estimated p:', estimated_p)

generated_values = geom.rvs(estimated_p, size=2000)
generated_dict = defaultdict(int)
for v in generated_values:
    generated_dict[v] += 1
generated_index = sorted(list (generated_dict.keys()))
generated_count = [generated_dict [i] for i in  generated_index]
print(generated_index)
print(generated_count)

2
投票

听起来您想基于第二张表中所述的PDF生成数据。 PDF有点像

observed_mean: 1.32
estimated p: 0.7575757575757576
new random sample:
    [1, 2, 3, 4, 5, 7]
    [1516, 365, 86, 26, 6, 1]

0 for x <= B A*exp(-A*(x-B)) for x > B 定义分布的宽度,该宽度将始终标准化为面积为1。A是水平偏移量,在您的情况下为零。您可以通过使用B进行装箱使其成为整数分布。

归一化衰减指数的CDF为ceil。通常,进行自定义分发的一种简单方法是生成统一编号并通过CDF映射它们。

幸运的是,您不必这样做,因为1 - exp(-A*(x-B))已经提供了您要查找的实现。您所要做的就是将最后一列的数据拟合为scipy.stats.exponscipy.stats.expon显然为零)。您可以使用A轻松完成此操作。请记住,B映射为scipy PDF语言。[]

这里是一些示例代码。通过在整数输入中计算从curve_fitcurve_fit的目标函数的积分,我在这里添加了一层额外的复杂性,在进行拟合时会考虑分箱。

A

0
投票

应该有更优雅的方法来做到这一点,但是您可以尝试一些简单的方法。

© www.soinside.com 2019 - 2024. All rights reserved.