使用 NumPy 获取反向累积密度函数?
Get reverse cumulative density function with NumPy?
我对特定密度感兴趣,我需要以代表其形状(非随机)的方式对其进行采样 "regularly"。
形式上,f
是我的密度函数,F
是对应的累积密度函数(F' = f
),其反函数rF = F^-1
确实存在。我有兴趣通过 F^-1
将 [0, 1]
中的常规样本投射到我的可变域中。类似于:
import numpy as np
uniform_sample = np.linspace(0., 1., 256 + 2)[1:-1] # source sample
shaped_sample = rF(uniform_sample) # this is what I want to get
numpy
是否有专门的方法来执行此操作,还是我应该手动执行此操作?这是指数定律的 'by hand' 方式:
l = 5. # exponential parameter
# f = lambda x: l * np.exp(-l * x) # density function, not used
# F = lambda x: 1 - np.exp(-l * x) # cumulative density function, not used either
rF = lambda y: np.log(1. / (1. - y)) / l # reverse `F^-1` function
# What I need is:
shaped_sample = rF(uniform_sample)
我知道,理论上,rF
在调用 np.random.exponential
时在内部用于抽取随机样本,例如(来自 [0, 1]
的均匀随机样本被转换为rF
以获得实际结果)。所以我的猜测是 numpy.random
确实知道它提供的每个发行版的 rF
函数。
如何访问它? numpy
是否提供如下功能:
np.random.<any_numpy_distribution>.rF
或
np.random.get_reverse_F(<any_custom_density_function>)
.. 还是我应该自己推导出/近似它们?
据我所知,没有办法直接在 numpy 中执行此操作。对于累积分布是解析的但不是反函数的函数,我通常使用样条曲线进行数值反演。
from scipy.interpolate import UnivariateSpline
x = np.linspace(0.0, 1.0, 1000)
F = cumulative_distn(x) #This we know and is analytic
rF = UnivariateSpline(F, x) #This will then be the inverse
请注意,如果您可以手动将 F
反转为 rF
,那么您 应该 。此方法仅适用于无法以封闭形式找到逆的情况。
scipy 具有 numpy.random
.
中所有(我认为)概率分布的概率分布对象
http://docs.scipy.org/doc/scipy/reference/stats.html
它们都有一个 ppf()
方法可以满足您的需求。
http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.ppf.html
在你的例子中:
import scipy.stats as st
l = 5. # exponential parameter
dist = st.expon(0., l) # distribution object provided by scipy
f = dist.pdf # probability density function
F = dist.cdf # cumulative density function
rF = dist.ppf # percent point function : reverse `F^-1` function
shaped_sample = rF(uniform_sample)
# and much more!
我对特定密度感兴趣,我需要以代表其形状(非随机)的方式对其进行采样 "regularly"。
形式上,f
是我的密度函数,F
是对应的累积密度函数(F' = f
),其反函数rF = F^-1
确实存在。我有兴趣通过 F^-1
将 [0, 1]
中的常规样本投射到我的可变域中。类似于:
import numpy as np
uniform_sample = np.linspace(0., 1., 256 + 2)[1:-1] # source sample
shaped_sample = rF(uniform_sample) # this is what I want to get
numpy
是否有专门的方法来执行此操作,还是我应该手动执行此操作?这是指数定律的 'by hand' 方式:
l = 5. # exponential parameter
# f = lambda x: l * np.exp(-l * x) # density function, not used
# F = lambda x: 1 - np.exp(-l * x) # cumulative density function, not used either
rF = lambda y: np.log(1. / (1. - y)) / l # reverse `F^-1` function
# What I need is:
shaped_sample = rF(uniform_sample)
我知道,理论上,rF
在调用 np.random.exponential
时在内部用于抽取随机样本,例如(来自 [0, 1]
的均匀随机样本被转换为rF
以获得实际结果)。所以我的猜测是 numpy.random
确实知道它提供的每个发行版的 rF
函数。
如何访问它? numpy
是否提供如下功能:
np.random.<any_numpy_distribution>.rF
或
np.random.get_reverse_F(<any_custom_density_function>)
.. 还是我应该自己推导出/近似它们?
据我所知,没有办法直接在 numpy 中执行此操作。对于累积分布是解析的但不是反函数的函数,我通常使用样条曲线进行数值反演。
from scipy.interpolate import UnivariateSpline
x = np.linspace(0.0, 1.0, 1000)
F = cumulative_distn(x) #This we know and is analytic
rF = UnivariateSpline(F, x) #This will then be the inverse
请注意,如果您可以手动将 F
反转为 rF
,那么您 应该 。此方法仅适用于无法以封闭形式找到逆的情况。
scipy 具有 numpy.random
.
http://docs.scipy.org/doc/scipy/reference/stats.html
它们都有一个 ppf()
方法可以满足您的需求。
http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.ppf.html
在你的例子中:
import scipy.stats as st
l = 5. # exponential parameter
dist = st.expon(0., l) # distribution object provided by scipy
f = dist.pdf # probability density function
F = dist.cdf # cumulative density function
rF = dist.ppf # percent point function : reverse `F^-1` function
shaped_sample = rF(uniform_sample)
# and much more!