Skip to content

Logistic regression with time-varying coefficients: cannot construct sampler #90

@lucasgautheron

Description

@lucasgautheron

Description of your problem or feature request

I want to perform a classification task which consists in predicting whether a document $i$ published at a time $t_i$ belongs to a certain class ( $y_i=1$ ) or not ( $y_i=0$ ). The contents of $i$ is given by a bag of words $b_{ij}$. The predictive features are encoded into a sparse tensor $x_{ijt} = b_{ij} \delta_{t,t_i}$. For this task I am considering a logistic regression with time-varying coefficients, such that the coefficients evolve through a random walk:

$$\text{logit} (p_{i}) = \sum_{jt} x_{ijt} \beta_{jt}$$

$$y_{i} \sim \text{Bernouilli}(p_i)$$

$$\beta_{j,t+1} \sim \text{Normal}(\beta_{j,t},\sigma_j^{-1})$$

$$\beta_{j,0} \sim \text{Normal}(0,\sigma_{j,0}^{-1})$$

$$\sigma_j \sim \text{Exponential}(1)$$

$$\sigma_{j,0} \sim \text{Exponential}(1)$$

For the sake of simplicity below I assume $\sigma_{j,0}=\sigma_j$, although I do not see any compelling reason to do so.

However:

  • I cannot construct a sampler for this model (see details below)
  • I wonder if there could be a more efficient implementation anyway: $x_{ijt}$ is very sparse, and at.tensordot(X, beta_t_rv, 2) involves too many needless operations. I would not have done that with Stan but in this case I found it easier to write the model this way.

Please provide a minimal, self-contained, and reproducible example.

As a clueless user, I tried to build a sampler based on my generative model by looking at other examples; which means I could be doing something completely idiotic!
Here is what I came up with:

import numpy as np

import aesara
import aesara.tensor as at
from aemcmc.basic import construct_sampler
from aesara.tensor.random.utils import RandomStream

def logistic_fit(X_val, y_val):
    N, M, T = X_val.shape

    srng = RandomStream(0)
    X = at.tensor3("X")

    sigma_rv = srng.exponential(1, size=X.shape[1])
    beta_t_rv = at.cumsum(srng.normal(0, 1/sigma_rv, size=(X.shape[1],X.shape[2])), axis=1)

    eta = at.tensordot(X, beta_t_rv, 2)
    p = at.sigmoid(-eta)
    Y_rv = srng.bernoulli(p, name="Y")

    y_vv = Y_rv.clone()
    y_vv.name = "y"

    sample_vars = [sigma_rv, beta_t_rv]

    sample_steps, updates, initial_values = construct_sampler({Y_rv: y_vv}, srng)

# X_val = np.load("X_val.npy")
# y_val = np.load("y_val.npy")

X_val = np.zeros((1000, 50, 10))
y_val = np.zeros(1000)

beta = logistic_fit(X_val, y_val)

Although thus far the script does not actually use the data, if at some point you want to try with actual data, download and unzip these files (X_val.npy and y_val.npy) to the folder the script is executed from: data.zip

However, this crashes:

Please provide the full traceback of any errors.

ERROR (aesara.graph.rewriting.basic): Rewrite failure due to: local_elemwise_dimshuffle_subsume
ERROR (aesara.graph.rewriting.basic): node: Elemwise{true_div,no_inplace}(InplaceDimShuffle{x}.0, exponential_rv{0, (0,), floatX, False}.out)
ERROR (aesara.graph.rewriting.basic): TRACEBACK:
ERROR (aesara.graph.rewriting.basic): Traceback (most recent call last):
  File "/Users/acristia/anaconda3/lib/python3.8/site-packages/aesara/graph/rewriting/basic.py", line 1933, in process_node
    replacements = node_rewriter.transform(fgraph, node)
  File "/Users/acristia/anaconda3/lib/python3.8/site-packages/aesara/graph/rewriting/basic.py", line 1092, in transform
    return self.fn(fgraph, node)
  File "/Users/acristia/anaconda3/lib/python3.8/site-packages/aemcmc/rewriting.py", line 345, in local_elemwise_dimshuffle_subsume
    new_op = SubsumingElemwise(new_inputs, new_outputs, inline=True)
  File "/Users/acristia/anaconda3/lib/python3.8/site-packages/aemcmc/rewriting.py", line 189, in __init__
    OpFromGraph.__init__(self, inputs, outputs, *args, **kwargs)
  File "/Users/acristia/anaconda3/lib/python3.8/site-packages/aesara/compile/builders.py", line 343, in __init__
    raise TypeError(f"Constants not allowed as inputs; {i}")
TypeError: Constants not allowed as inputs; TensorConstant{1}

Traceback (most recent call last):
  File "examples/gibbs_sample.py", line 61, in <module>
    beta = logistic_fit(X_val, y_val)
  File "examples/gibbs_sample.py", line 26, in logistic_fit
    sample_steps, updates, initial_values = construct_sampler({Y_rv: y_vv}, srng)
  File "/Users/acristia/anaconda3/lib/python3.8/site-packages/aemcmc/basic.py", line 108, in construct_sampler
    raise NotImplementedError(
NotImplementedError: Could not find a posterior samplers for {exponential_rv{0, (0,), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out}

Versions and main components

  • Aesara version: 2.8.9
  • Aemcmc version: 0.06
  • Python version: 3.8.10
  • Operating system: macOS 10.15.4
  • How did you install Aesara: pip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions