微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何创建 Hypsecant 分布以及与该分布一起使用的先验条件?

如何解决如何创建 Hypsecant 分布以及与该分布一起使用的先验条件?

我一直在使用以下链接Fitting empirical distribution to theoretical ones with Scipy。我一直在使用我的数据,发现常见的分布是 Hypsecant 分布。我在 pymc3 包中找不到发行版,因此,我决定用 scipy 看一下,以了解发行版是如何形成的。我在 pymc3 中为 Hypsecant 分布创建了一个自定义分布,但我有几个问题:

  • 我想知道我创建发行版的方法是否正确?
  • 如何在模型中实现自定义分发?
  • 关于先验分布,我是否在正态分布先验(mu 和 sigma)中使用相同的步骤?
  • 如何为随机变量和 logp 创建函数

我的自定义发行版:

import numpy as np
import theano.tensor as tt
from scipy import stats
from scipy.special import hyp1f1,nctdtr
import math
import warnings
from pymc3.theanof import floatX
from pymc3.distributions.dist_math import bound,gammaln
from pymc3.distributions.continuous import assert_negative_support,get_tau_sigma
from pymc3.distributions.distribution import Continuous,draw_values,generate_samples


class Hypsecant(Continuous):
    """
    Parameters
    ----------
    mu: float
        Location parameter.
    sigma: float
        Scale parameter (sigma > 0). Converges to the standard deviation as nu increases. (only required if lam is not specified)
    lam: float
        Scale parameter (lam > 0). Converges to the precision as nu increases. (only required if sigma is not specified)
    """

    def __init__(self,mu=0,sigma=1,lam=None,sd=None,*args,**kwargs):
        super().__init__(*args,**kwargs)
        super(Hypsecant,self).__init__(*args,**kwargs)
        if sd is not None:
            sigma = sd
            warnings.warn("sd is deprecated,use sigma instead",DeprecationWarning)
        lam,sigma = get_tau_sigma(tau=lam,sigma=sigma)
        self.lam = lam = tt.as_tensor_variable(lam)
        self.sigma = self.sd = sigma = tt.as_tensor_variable(sigma)
        self.mean = self.median = self.mode = self.mu = mu = tt.as_tensor_variable(mu)
        self.variance = tt.as_tensor_variable(1)

        assert_negative_support(lam,'lam (sigma)','Hypsecant')

    def random(self,point=None,size=None):
        """
        Draw random values from Hypsecant distribution.
        Parameters
        ----------
        point: dict,optional
            Dict of variable values on which random values are to be
            conditioned (uses default point if not specified).
        size: int,optional
            Desired size of random sample (returns one sample if not
            specified).
        Returns
        -------
        array
        """
        mu,lam = draw_values([self.mu,self.lam],point=point,size=size)
        return generate_samples(stats.hypsecant.rvs,loc=mu,scale=lam,dist_shape=self.shape,size=size)

    def logp(self,value):
        """
        Calculate log-probability of Hypsecant distribution at specified value.
        Parameters
        ----------
        value: numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or theano tensor
        Returns
        -------
        TensorVariable
        """
        
        mu = self.mu
        lam = self.lam

        return bound()

    def logcdf(self,value):
        """
        Compute the log of the cumulative distribution function for Hypsecant distribution
        at the specified value.
        Parameters
        ----------
        value: numeric
            Value(s) for which log CDF is calculated. If the log CDF for multiple
            values are desired the values must be provided in a numpy array or theano tensor.
        Returns
        -------
        TensorVariable
        """
        mu = self.mu
        lam = self.lam
        
        return 2.0 / math.pi * tt.math.atan(tt.math.exp(value))

我的自定义模型

with pm.Model() as model:
                # Prior distributions for unkNown model parameters:
                mu = pm.normal('mu',sigma=1)
                sd = pm.Halfnormal('sd',sigma=1)

                # Observed data is from a Likelihood distributions (Likelihood (sampling distribution) of observations):
                observed_data = Hypsecant('observed_data',mu=mu,sd=sd,observed=data_list)
                
                # draw 5000 posterior samples
                trace_S = pm.sample(draws=5000,tune=2000,chains=3,cores=1)
        
                # Obtaining Posterior Predictive Sampling:
                post_pred_S = pm.sample_posterior_predictive(trace_S,samples=3000)
                print(post_pred_S['observed_data'].shape)
                print('\nSummary: ')
                print(pm.stats.summary(data=trace_S))
                print(pm.stats.summary(data=post_pred_S))

编辑 1:

我编辑了 logp 部分和自定义模型。请找到以下代码

class Hypsecant(Continuous):
    """
    Parameters
    ----------
    mu: float
        Location parameter.
    sigma: float
        Scale parameter (sigma > 0). Converges to the standard deviation as nu increases. (only required if lam is not specified)
    lam: float
        Scale parameter (lam > 0). Converges to the precision as nu increases. (only required if sigma is not specified)
    """

    def __init__(self,value):
        """
        Calculate log-probability of Hypsecant distribution at specified value.
        Parameters
        ----------
        value: numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or theano tensor
        Returns
        -------
        TensorVariable
        """
        
        mu = self.mu
        lam = self.lam

        Px = 1.0/(math.pi * tt.math.cosh(value))
        return bound(Px,mu,lam)

    def logcdf(self,value):
        """
        Compute the log of the cumulative distribution function for Hypsecant distribution
        at the specified value.
        Parameters
        ----------
        value: numeric
            Value(s) for which log CDF is calculated. If the log CDF for multiple
            values are desired the values must be provided in a numpy array or theano tensor.
        Returns
        -------
        TensorVariable
        """
        mu = self.mu
        lam = self.lam
        
        return 2.0 / math.pi * tt.math.atan(tt.math.exp(value))

型号:

with pm.Model() as model:
                # Prior distributions for unkNown model parameters:
                mu = pm.normal('mu',sigma=1)
                sd = pm.normal('sd',sigma=1)
                
                # Custom distribution:
                # observed_data = pm.Densitydist('observed_data',NonCentralStudentT,observed=data_list)

                # Observed data is from a Likelihood distributions (Likelihood (sampling distribution) of observations):
                observed_data = Hypsecant('observed_data',observed=data)
                
                # draw 5000 posterior samples
                trace = pm.sample(draws=5000,tune=3000,chains=2,cores=1)
        
                # Obtaining Posterior Predictive Sampling:
                post_pred = pm.sample_posterior_predictive(trace,samples=3000)
                print(post_pred['observed_data'].shape)
                print('\nSummary: ')
                print(pm.stats.summary(data=trace))
                print(pm.stats.summary(data=post_pred))

编辑 2:

我将类修改为以下内容

class Hypsecant(Continuous):
    """
    Parameters
    ----------
    mu: float
        Location parameter.
    sigma: float
        Scale parameter (sigma > 0). Converges to the standard deviation as nu increases. (only required if lam is not specified)
    lam: float
        Scale parameter (lam > 0). Converges to the precision as nu increases. (only required if sigma is not specified)
    """

    def __init__(self,mu=None,sigma=None,**kwargs):
        # super().__init__(*args,**kwargs)
        # super(Hypsecant,sigma=sigma)
        self.lam = lam = tt.as_tensor_variable(lam)
        self.sigma = self.sd = sigma = tt.as_tensor_variable(sigma)
        self.mean = self.median = self.mode = self.mu = mu = tt.as_tensor_variable(mu)
        self.variance = tt.as_tensor_variable(1)

        assert_negative_support(mu,'mu','Hypsecant')
        assert_negative_support(sigma,'sigma (lam)','Hypsecant')
        
        # return super(Hypsecant,self).__init__(shape=[mu,sigma],**kwargs)
        return super().__init__(*args,**kwargs)

    def random(self,optional
            Desired size of random sample (returns one sample if not
            specified).
        Returns
        -------
        array
        """
        # mu = self.mu
        # lam,sigma=sigma)
        
        mu,value):
        """
        Calculate log-probability of Hypsecant distribution at specified value.
        Parameters
        ----------
        value: numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or theano tensor
        Returns
        -------
        TensorVariable
        """
        
        # mu = self.mu
        # lam = self.lam
        # sigma = self.sigma
        # # sd = self.sd
        # mu = self.mu
        # lam,sigma = get_tau_sigma(sigma=sigma)

        Px = pm.math.log(1.0/(math.pi * pm.math.cosh(value)))
        return bound(Px)
        # return bound(Px,lam,sigma)

    def logcdf(self,value):
        """
        Compute the log of the cumulative distribution function for Hypsecant distribution
        at the specified value.
        Parameters
        ----------
        value: numeric
            Value(s) for which log CDF is calculated. If the log CDF for multiple
            values are desired the values must be provided in a numpy array or theano tensor.
        Returns
        -------
        TensorVariable
        """
        
        # # mu = self.mu
        # # lam = self.lam
        # # # self.sigma = self.sd = sigma = tt.as_tensor_variable(sigma)
        # mu = self.mu
        # lam = self.lam
        # sigma = self.sigma
        # # sd = self.sd
        # mu = self.mu
        # lam,sigma = get_tau_sigma(sigma=sigma)
        
        # return bound(pm.math.log(2.0 / math.pi * tt.math.atan(tt.math.exp(value))),sigma)
        return bound(pm.math.log(2.0 / math.pi * tt.math.atan(tt.math.exp(value))))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。