2

答えが見つからないデコレータに関する 3 つの質問があります。

Q1) PyMC (@Deterministic、@Stochastic) のデコレータへの引数は何を意味しますか?

Q2)

@pymc.stochastic(dtype=int)
def switchpoint(value=10, t_l=0, t_h=110):
    def logp(value, t_l, t_h):
        if value > t_h or value < t_l:
            return -np.inf
        else:
            return -np.log(t_h - t_l + 1)
    def random(t_l, t_h):
        from numpy.random import random
        return np.round( (t_l - t_h) * random() ) + t_l

1)print switchpoint.logp #log-probability を期待どおりに出力します

2)print switchpoint.random #乱数を生成しません

3)print switchpoint.random() # 乱数を生成

4) switchpoint.logp() #エラーを出力します

2 が機能せず、3 が機能した場合、1 は機能せず、代わりに 4 が機能するはずです (これは、私が観察したこととは逆です)。誰かが何が起こっているのか説明できますか?

Q3)

@pymc.stochastic(dtype=int)
def switchpoint(value=1900, t_l=1851, t_h=1962):
    if value > t_h or value < t_l:
        # Invalid values
        return -np.inf
    else:
        # Uniform log-likelihood
        return -np.log(t_h - t_l + 1)

ここでは、logp入力した場合でもswitchpoint.logp、このコードが実行されるとは指定されていません。

4

1 に答える 1

3

Q1) ストキャスティクスに対するすべての引数の意味は、ここに文書化されています。deterministic への引数は同じで、追加の引数はここに記載されています。

Q2) 動作の違いは、実際にswitchpoint.logp関数を実行して Python に変換propertyするPyMC 内にいくつかの魔法がありswitchpoint.random、この処理を受けず、関数として保持されることです。

実際に何が起こっているのか知りたい場合は、関連するソースの一部を次に示します。

def get_logp(self):
    if self.verbose > 1:
        print '\t' + self.__name__ + ': log-probability accessed.'
    logp = self._logp.get()
    if self.verbose > 1:
        print '\t' + self.__name__ + ': Returning log-probability ', logp

    try:
        logp = float(logp)
    except:
        raise TypeError, self.__name__ + ': computed log-probability ' + str(logp) + ' cannot be cast to float'

    if logp != logp:
        raise ValueError, self.__name__ + ': computed log-probability is NaN'

    # Check if the value is smaller than a double precision infinity:
    if logp <= d_neg_inf:
        if self.verbose > 0:
            raise ZeroProbability, self.errmsg + ": %s" %self._parents.value
        else:
            raise ZeroProbability, self.errmsg

    return logp

def set_logp(self,value):
    raise AttributeError, 'Potential '+self.__name__+'\'s log-probability cannot be set.'

logp = property(fget = get_logp, fset=set_logp, doc="Self's log-probability value conditional on parents.")

logp関数の間に a と呼ばれるものへの変換など、他にもいくつかのことが行われていますLazyFunctionが、それが基本的な考え方です。

Q3)stochasticデコレータには、コードのイントロスペクションを使用してrandomサブlogp関数が内部で定義されているかどうかを判断するいくつかの (より多くの) 魔法がありswitchpointます。そうである場合は、logpサブ関数を使用して計算logpし、そうでない場合は、それ自体を使用しswitchpointます。そのソースコードはここにあります:

# This gets used by stochastic to check for long-format logp and random:
if probe:
    # Define global tracing function (I assume this is for debugging??)
    # No, it's to get out the logp and random functions, if they're in there.
    def probeFunc(frame, event, arg):
        if event == 'return':
            locals = frame.f_locals
            kwds.update(dict((k,locals.get(k)) for k in keys))
            sys.settrace(None)
        return probeFunc

    sys.settrace(probeFunc)

    # Get the functions logp and random (complete interface).
    # Disable special methods to prevent the formation of a hurricane of Deterministics
    cur_status = check_special_methods()
    disable_special_methods()
    try:
        __func__()
    except:
        if 'logp' in keys:
            kwds['logp']=__func__
        else:
            kwds['eval'] =__func__
    # Reenable special methods.
    if cur_status:
        enable_special_methods()

for key in keys:
    if not kwds.has_key(key):
        kwds[key] = None

for key in ['logp', 'eval']:
    if key in keys:
        if kwds[key] is None:
            kwds[key] = __func__

繰り返しになりますが、さらにいくつかのことが行われており、かなり複雑ですが、それが基本的な考え方です。

于 2014-06-03T03:02:51.737 に答える