web-dev-qa-db-ja.com

Pythonでログ均一分布を生成するにはどうすればよいですか?

Pythonに組み込み関数が見つからなかったため、最小値と最大値(Rの同等物は here )を指定すると、対数均一分布を生成できます)は次のようになります。 loguni [n、exp(min)、exp(max)、base]は、exp(min)とexp(max)の範囲に均一に分布したn logを返します。

私が見つけた最も近いものは numpy.random.uniform

14
jkrish

http://ecolego.facilia.se/ecolego/show/Log-Uni​​form%20Distribution から:

対数一様分布では、対数変換された確率変数は一様に分布していると想定されます。

したがって

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))
15
Scott Gigante

私は scipy.stats.reciprocal は、希望する分布です。
ドキュメントから:

逆数の確率密度関数は次のとおりです。

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

a <= x <= bおよびaの場合、b> 0

逆数は、形状パラメータとしてaおよびbを取ります。

2
joaoFaria

より良いアプローチは、対数均一から直接サンプルを生成する代わりに、対数均一密度を作成することです。

統計的に言えば、これはすでに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)
0
Justin Winokur

ここに1つあります:

提供されている.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、Copyright 2019 Neuraxio Inc.
0
from neuraxle.hyperparams.distributions import LogUniform

# Create a Log Uniform Distribution that ranges from 0.001 to 0.1: 
learning_rate_distribution = LogUniform(0.001, 0.1)

# Get a Random Value Sample (RVS) from the distribution: 
learning_rate_sample = learning_rate_distribution.rvs()

print(learning_rate_sample)

出力例:

0.004532

これは Neuraxle を使用しています。

0