如何在Python中生成Log Uniform Distribution?

时间:2017-05-15 10:57:42

标签: python numpy uniform-distribution

我找不到Python中的内置函数来生成一个给定最小值和最大值的对数均匀分布(R等价值为here),如:loguni [n,exp(min), exp(max),base]返回n log,均匀分布在exp(min)和exp(max)范围内。

我发现的最接近的是numpy.random.uniform

7 个答案:

答案 0 :(得分:13)

来自http://ecolego.facilia.se/ecolego/show/Log-Uniform%20Distribution

  

在loguniform分布中,假设logtransformed随机变量是均匀分布的。

因此

logU(a, b) ~ exp(U(log(a), log(b))

因此,我们可以使用numpy

创建对数均匀分布
def loguniform(low=0, high=1, size=None):
    return np.exp(np.random.uniform(low, high, size))

如果你想选择不同的基础,我们可以按如下方式定义一个新函数:

def lognuniform(low=0, high=1, size=None, base=np.e):
    return np.power(base, np.random.uniform(low, high, size))

答案 1 :(得分:3)

我相信scipy.stats.reciprocal是你想要的发行版 来自文档:

  

倒数的概率密度函数是:

f(x, a, b) = \frac{1}{x \log(b/a)}
     

对于< = x< = b和a,b> 0

     

互惠将ab作为形状参数。

答案 2 :(得分:2)

SciPy v1.4包含一个loguniform随机变量:https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.loguniform.html

这里是使用方法:

from scipy.stats import loguniform

rvs = loguniform.rvs(10**-2, 10**0, size=1000)

这将创建均匀分布在0.01和1之间的随机变量。可视化对数刻度直方图可以最好地显示这一点:

此“对数缩放”有效,与基础无关。 loguniform.rvs(2**-2, 2**0, size=1000)还会产生对数均匀的随机变量。更多详细信息,请参见loguniform的文档。

答案 3 :(得分:0)

这是一个带有.rvs()方法的类:

class LogUniform(HyperparameterDistribution):
    """Get a LogUniform distribution.
    For example, this is good for neural networks' learning rates: that vary exponentially."""

    def __init__(self, min_included: float, max_included: float):
        """
        Create a quantized random log uniform distribution.
        A random float between the two values inclusively will be returned.
        :param min_included: minimum integer, should be somehow included.
        :param max_included: maximum integer, should be somehow included.
        """
        self.log2_min_included = math.log2(min_included)
        self.log2_max_included = math.log2(max_included)
        super(LogUniform, self).__init__()

    def rvs(self) -> float:
        """
        Will return a float value in the specified range as specified at creation.
        :return: a float.
        """
        return 2 ** random.uniform(self.log2_min_included, self.log2_max_included)

    def narrow_space_from_best_guess(self, best_guess, kept_space_ratio: float = 0.5) -> HyperparameterDistribution:
        """
        Will narrow, in log space, the distribution towards the new best_guess.
        :param best_guess: the value towards which we want to narrow down the space. Should be between 0.0 and 1.0.
        :param kept_space_ratio: what proportion of the space is kept. Default is to keep half the space (0.5).
        :return: a new HyperparameterDistribution that has been narrowed down.
        """
        log2_best_guess = math.log2(best_guess)
        lost_space_ratio = 1.0 - kept_space_ratio
        new_min_included = self.log2_min_included * kept_space_ratio + log2_best_guess * lost_space_ratio
        new_max_included = self.log2_max_included * kept_space_ratio + log2_best_guess * lost_space_ratio
        if new_max_included <= new_min_included or kept_space_ratio == 0.0:
            return FixedHyperparameter(best_guess).was_narrowed_from(kept_space_ratio, self)
        return LogUniform(2 ** new_min_included, 2 ** new_max_included).was_narrowed_from(kept_space_ratio, self)

如果您也感兴趣,原始项目还将包括LogNormal发行版。

来源:

许可证:

  • Apache License 2.0,版权所有2019 Neuraxio Inc。

答案 4 :(得分:0)

signed char

示例输出:

  

0.004532

这正在使用Neuraxle

答案 5 :(得分:0)

更好的方法是代替直接从对数均匀度生成样本,而应创建对数均匀度密度。

用统计数据来说,这是SciPy中已经存在的倒数分布:scipy.stats.reciprocal。例如,要构建一个10^{x~U[-1,1]}的示例,您可以这样做:

rv = scipy.stats.reciprocal(a=0.1,b=10)
x = rv.rvs(N)

或者,我编写并使用以下代码对任何scipy.stats型(冻结)随机变量进行对数转换

class LogTransformRV(scipy.stats.rv_continuous):
    def __init__(self,rv,base=10):
        self.rv = rv
        self.base = np.e if base in {'e','E'} else base
        super(LogTransformRV, self).__init__()
        self.a,self.b = self.base ** self.rv.ppf([0,1])

    def _pdf(self,x):
        return self.rv.pdf(self._log(x))/(x*np.log(self.base)) # Chain rule

    def _cdf(self,x):
        return self.rv.cdf(self._log(x)) 

    def _ppf(self,y):
        return self.base ** self.rv.ppf(y)

    def _log(self,x):
        return np.log(x)/np.log(self.base)

答案 6 :(得分:-1)

from random import random
from math import log

def loguniform(lo,hi,seed=random()):
    return lo ** ((((log(hi) / log(lo)) - 1) * seed) + 1)

您可以使用特定种子值进行检查:lognorm(10,1000,0.5)返回100.0