Metadata-Version: 2.1
Name: como-ebnm
Version: 0.0.13
Summary: Covariate moderated EBNM
Author-email: Karl Tayeb <ktayeb@uchicago.edu>
License: MIT License
        
        Copyright (c) 2022 Karl Tayeb
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://github.com/karltayeb/como
Project-URL: Bug Tracker, https://github.com/karltayeb/como/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE.txt

# como (Covariate moderated EBNM)

Python implimentation of various covariate moderated EBNM

### Problem set-up

$$
\begin{align}
\hat\beta \sim N(\beta, s^2) \\
\beta \sim \pi_0(x) f_0 + \pi_1(x) f_1 \\
\log \frac{\pi_1(x)}{\pi_0(x)} = {\bf \beta}^T {\bf x}
\end{align}
$$


1. A logistic regression model $\log \frac{\pi_1({\bf x})}{\pi_0({\bf x})} = {\bf b}^T {\bf x}$
1. A null component distribution $f_0$
1. A alternative component distribution $f_1$

### TwoComponentCoMo

`TwoComponentCoMo` is an abstract class that encapsulates the logic for fitting two component covariate moderated EBNM.
It's constructor requires a dictionary 
1. `data` a dictionary
1. `f0` and `f1` two `ComponentDistribution` object (described below)
1. `logreg` a `LogisticRegression` object (described below)


### ComponentDistribution

We've implmented a few options for $f_0$ and $f_1$ that can be flexibly recombined. `ComponentDistribution`

1. `convolved_log_pdf(self, beta, se)`: compute $\log p(\hat\beta | s^2) = \log \int N(\hat\beta | \beta, s^2) f(\beta) d\beta$
1. `update(self, data)`: update the parameters of `ComponentDistribution` using `data`. Importantly, in practice this function should weight our observations according to the assignment probabilities.


So far we've implimented the following component distributions:

1. `PointMassComponent`: a point mass, usual choice for $f_0$
1. `NormalFixedLocComponent`: a normal distribution with fixed location parameter (default `loc=0`)-- we estimate the scale parameter
1. `UnimodalNormalMixtureComponent`: a scale mixture of normals, we estimate the mixture distribution $\pi$

### LogisticRegression

`LogisticRegression.predict()`: return (expected) predicted log odds given current parameter estimates
`LogisticRegression.evidence()`: compute the log likelihood or lower bound for current parameter estimates
`LogisticRegression.update()`: update the logistic regression, accounting for the current assignment probabilities

So far we've implimented the following classes inheriting `LogisticRegression`:

1. `LogisticSuSiE`: log odds are modeled with a sparse regression $\beta^T x$ where $\beta$ has the sum of single effects prior.
1. `InterceptOnly`: ignore the covariates, just estimate a constant mixture proprotion for all observations

### Putting it all together
We can easily specify a new two component model, inheriting from the base `TwoComponentCoMo` class

```
class PointNormalSuSiE(TwoComponentCoMo):
    def __init__(self, data, scale=1.0):
        """
        Initialize Point Normal SuSiE
        (Covariatiate EBNM with "point-normal" effects,
        and SuSiE prior on the mixture proportion)

        Parameters:
            data: dictionary with keys
                'beta' and 'se' for observations and standard errors,
                'X' and 'Z' for annotations and (fixed) covariates resp.
            scale: (initial) scale parameter for the normal mixture component
        """
        f0 = PointMassComponent(0.0)
        f1 = NormalFixedLocComponent(0, scale)
        
        # TODO: make sure `y` is a key in data, otherwise make it
        logreg = LogisticSusie(data, L=10)
        super().__init__(data, f0, f1, logreg)
```
