Decorator for PyMC3

Overview

Build Status Coverage Status

sampled

Decorator for reusable models in PyMC3

Provides syntactic sugar for reusable models with PyMC3. This lets you separate creating a generative model from using the model.

Here is an example of creating a model:

import numpy as np
import pymc3 as pm
from sampled import sampled
import theano.tensor as tt

@sampled
def linear_model(X, y):
    shape = X.shape
    X = pm.Normal('X', mu=tt.mean(X, axis=0), sd=np.std(X, axis=0), shape=shape)
    coefs = pm.Normal('coefs', mu=tt.zeros(shape[1]), sd=tt.ones(shape[1]), shape=shape[1])
    pm.Normal('y', mu=tt.dot(X, coefs), sd=tt.ones(shape[0]), shape=shape[0])

Now here is how to use the model:

X = np.random.normal(size=(1000, 10))
w = np.random.normal(size=10)
y = X.dot(w) + np.random.normal(scale=0.1, size=1000)

with linear_model(X=X, y=y):
    sampled_coefs = pm.sample(draws=1000, tune=500)

np.allclose(sampled_coefs.get_values('coefs').mean(axis=0), w, atol=0.1) # True

You can also use this to build graphical networks -- here is a continuous version of the STUDENT example from Koller and Friedman's "Probabilistic Graphical Models", chapter 3:

import pymc3 as pm
from sampled import sampled
import theano.tensor as tt

@sampled
def student():
    difficulty = pm.Beta('difficulty', alpha=5, beta=5)
    intelligence = pm.Beta('intelligence', alpha=5, beta=5)
    SAT = pm.Beta('SAT', alpha=20 * intelligence, beta=20 * (1 - intelligence))
    grade_avg = 0.5 + 0.5 * tt.sqrt((1 - difficulty) * intelligence)
    grade = pm.Beta('grade', alpha=20 * grade_avg, beta=20 * (1 - grade_avg))
    recommendation = pm.Binomial('recommendation', n=1, p=0.7 * grade)

Observations may be passed into any node, and we can observe how that changes posterior expectations:

# no prior knowledge
with student():
    prior = pm.sample(draws=1000, tune=500)

prior.get_values('recommendation').mean()  # 0.502

# 99th percentile SAT score --> higher chance of a recommendation
with student(SAT=0.99):
    good_sats = pm.sample(draws=1000, tune=500)

good_sats.get_values('recommendation').mean()  # 0.543

# A good grade in a hard class --> very high chance of recommendation
with student(difficulty=0.99, grade=0.99):
    hard_class_good_grade = pm.sample(draws=1000, tune=500)

hard_class_good_grade.get_values('recommendation').mean()  # 0.705

References

  • Koller, Daphne, and Nir Friedman. Probabilistic graphical models: principles and techniques. MIT press, 2009.
You might also like...
A Runtime method overload decorator which should behave like a compiled language

strongtyping-pyoverload A Runtime method overload decorator which should behave like a compiled language there is a override decorator from typing whi

Comments
  • The example code does not work.

    The example code does not work.

    I get the error message when using the example code: I used python3.5 and

    numpy version: 1.13.3 pymc3 version: 3.2

    ValueError: Input dimension mis-match. (input[0].shape[1] = 1000, input[1].shape[1] = 10)

    import numpy as np import pymc3 as pm from sampled import sampled

    @sampled def linear_model(X, y): shape = X.shape X = pm.Normal('X', mu=np.mean(X, axis=0), sd=np.std(X, axis=0), shape=shape) coefs = pm.Normal('coefs', mu=np.zeros(shape[1]), sd=np.ones(shape[1]), shape=shape[1]) pm.Normal('y', mu=np.dot(X, coefs), sd=np.ones(shape[0]), shape=shape[0])

    X = np.random.normal(size=(1000, 10)) w = np.random.normal(size=10) y = X.dot(w) + np.random.normal(scale=0.1, size=1000)

    with linear_model(X=X, y=y): sampled_coefs = pm.sample(draws=500, tune=500)

    np.allclose(sampled_coefs.get_values('coefs').mean(axis=0), w, atol=0.1) # True

    opened by MooersLab 3
  • Throws error AttributeError: module 'sampled.sampled' has no attribute 'Model'

    Throws error AttributeError: module 'sampled.sampled' has no attribute 'Model'

    I have been using this deocrator to run the same generative model on datasets of different size but now it suddenly throws the error :

    AttributeError: module 'sampled.sampled' has no attribute 'Model'

    Can reproduce it with your example:

    import numpy as np 
    import pymc3 as pm
    from sampled import sampled
    import theano.tensor as tt
    
    @sampled
    def linear_model(X, y):
        shape = X.shape
        X = pm.Normal('X', mu=tt.mean(X, axis=0), sd=np.std(X, axis=0), shape=shape)
        coefs = pm.Normal('coefs', mu=tt.zeros(shape[1]), sd=tt.ones(shape[1]), shape=shape[1])
        pm.Normal('y', mu=tt.dot(X, coefs), sd=tt.ones(shape[0]), shape=shape[0])`
    
    X = np.random.normal(size=(1000, 10))
    w = np.random.normal(size=10)
    y = X.dot(w) + np.random.normal(scale=0.1, size=1000)
    
    with linear_model(X=X, y=y):
        sampled_coefs = pm.sample(draws=1000, tune=500)
    
    Traceback (most recent call last):
    
      File "<ipython-input-9-2012d7efa2d1>", line 5, in <module>
        with linear_model(X=X, y=y):
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/sampled/sampled.py", line 20, in wrapped_f
        with ObserverModel(observed) as model:
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/pymc3/model.py", line 274, in __call__
        instance = cls.__new__(cls, *args, **kwargs)
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/pymc3/model.py", line 739, in __new__
        instance._parent = cls.get_context(error_if_none=False)
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/pymc3/model.py", line 213, in get_context
        candidate = cls.get_contexts()[idx] # type: Optional[T]
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/pymc3/model.py", line 234, in get_contexts
        context_class = cls.context_class
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/pymc3/model.py", line 260, in context_class
        cls._context_class = resolve_type(cls._context_class)
    
      File "/home/vr308/anaconda3/lib/python3.6/site-packages/pymc3/model.py", line 254, in resolve_type
        c = getattr(modules[cls.__module__], c)
    
    AttributeError: module 'sampled.sampled' has no attribute 'Model'
    
    

    pymc3 version 3.8

    opened by vr308 0
  • Status

    Status

    What's the status of this project? It seems like the API solves a major problem in pymc2/3, in which it's generally hard to make a model that supports passing through variables that are observed or unobserved. It seems like something like this ought to be integrated into pymc3 somehow, although it's unclear whether this is a standalone API for syntatic sugar or a feature enhancement for the existing Model API.

    opened by kyleabeauchamp 2
Owner
Colin
Colin
A Runtime method overload decorator which should behave like a compiled language

strongtyping-pyoverload A Runtime method overload decorator which should behave like a compiled language there is a override decorator from typing whi

null 20 Oct 31, 2022
THIS IS THE **OLD** PYMC PROJECT. PLEASE USE PYMC3 INSTEAD:

Introduction Version: 2.3.8 Authors: Chris Fonnesbeck Anand Patil David Huard John Salvatier Web site: https://github.com/pymc-devs/pymc Documentation

PyMC 7.2k Jan 7, 2023
A Flask inspired, decorator based API wrapper for Python-Slack.

A Flask inspired, decorator based API wrapper for Python-Slack. About Tangerine is a lightweight Slackbot framework that abstracts away all the boiler

Nick Ficano 149 Jun 30, 2022
decorator

Decorators for Humans The goal of the decorator module is to make it easy to define signature-preserving function decorators and decorator factories.

Michele Simionato 734 Dec 30, 2022
API Rate Limit Decorator

ratelimit APIs are a very common way to interact with web services. As the need to consume data grows, so does the number of API calls necessary to re

Tomas Basham 574 Dec 26, 2022
API Rate Limit Decorator

ratelimit APIs are a very common way to interact with web services. As the need to consume data grows, so does the number of API calls necessary to re

Tomas Basham 575 Jan 5, 2023
esguard provides a Python decorator that waits for processing while monitoring the load of Elasticsearch.

esguard esguard provides a Python decorator that waits for processing while monitoring the load of Elasticsearch. Quick Start You need to launch elast

po3rin 5 Dec 8, 2021
Python decorator for `TODO`s

Python decorator for `TODO`s. Don't let your TODOs rot in your python projects anymore !

Klemen Sever 74 Sep 13, 2022
Python @deprecat decorator to deprecate old python classes, functions or methods.

deprecat Decorator Python @deprecat decorator to deprecate old python classes, functions or methods. Installation pip install deprecat Usage To use th

null 12 Dec 12, 2022
This package tries to emulate the behaviour of syntax proposed in PEP 671 via a decorator

Late-Bound Arguments This package tries to emulate the behaviour of syntax proposed in PEP 671 via a decorator. Usage Mention the names of the argumen

Shakya Majumdar 0 Feb 6, 2022