# Poisson


Poisson family with log (canonical) link.


Usage

``` python
Poisson()
```


The Poisson family models the response as non-negative integer counts, such as the number of events observed in a fixed interval of time, space, or exposure. It is the standard choice for count data when the variance of the counts is approximately equal to their mean. The canonical log link guarantees positive fitted values on the response scale and gives the linear predictor a multiplicative interpretation: a one-unit increase in a covariate multiplies the expected count by `exp(coefficient)`.


## Notes

The canonical link is the natural logarithm:

 g(\mu) = \log(\mu) 

The variance function is V(\mu) = \mu, so the variance equals the mean. If the observed variance substantially exceeds the mean (overdispersion), consider [NegativeBinomial](NegativeBinomial.md#whittaker.NegativeBinomial) or [Tweedie](Tweedie.md#whittaker.Tweedie) instead. The deviance is

 D(y, \hat\mu) = 2 \sum_i \left\[ y_i \log\\\left(\frac{y_i}{\hat\mu_i}\right) - (y_i - \hat\mu_i) \right\] . 


## Examples

Fit a GAM to simulated count data with a smooth, log-linear trend:


``` python
import numpy as np
import whittaker as wk

rng = np.random.default_rng(0)
n = 200
x = np.linspace(0, 2 * np.pi, n)
mu = np.exp(0.5 * np.sin(x))
y = rng.poisson(mu)

data = {"x": x, "y": y}

model = wk.GAM("y ~ s(x)", family=wk.Poisson())
model.fit(data, method="REML")
print(model.summary())
```


    GAM fit summary
    ============================================================
    Formula:    y ~ s(x)
    Family:     Poisson(link='log')
    Inference:  REML
    Observations: 200
    Coefficients: 10

    Parametric coefficients:
      Term                       Estimate    Std.Err    z value    p-value
      ------------------------ ---------- ---------- ---------- ----------
      (Intercept)                  0.2113     0.0657      3.214    0.00131

    Approximate significance of smooth terms:
      Term                        EDF Ref.df     Chi.sq    p-value
      ------------------------ ------ ------ ---------- ----------
      s(x)                       4.18      5     37.260  5.312e-07

    Total EDF:  5.18
    Scale est:  1.000000
    Deviance:   187.0851
    Null dev:   230.5815
    Dev. expl:  18.9%
    GCV score:  0.985797
    AIC:        554.30
    BIC:        571.37


## Attributes

| Name | Description |
|----|----|
| [scale_known](#scale_known) | Whether the dispersion parameter is fixed. Always `True` for Poisson. |

------------------------------------------------------------------------


### scale_known


Whether the dispersion parameter is fixed. Always `True` for Poisson.


`scale_known: bool`


The Poisson distribution has no free dispersion parameter, so the scale is fixed at `1` and is never estimated during fitting. This affects how [GAM.summary()](GAM.md#whittaker.GAM.summary) reports the scale and how many degrees of freedom are attributed to dispersion estimation.


## Methods

| Name | Description |
|----|----|
| [deviance()](#deviance) | Total Poisson deviance, the (weighted) sum of `unit_deviance`. |
| [initialize()](#initialize) | Starting values for `mu`: `y` nudged away from zero. |
| [link()](#link) | Apply the log link: \eta = \log(\mu). |
| [link_derivative()](#link_derivative) | Derivative of the log link: g'(\mu) = 1/\mu. |
| [link_inverse()](#link_inverse) | Apply the inverse log link: \mu = e^{\eta}. |
| [log_likelihood()](#log_likelihood) | Poisson log-likelihood \ell_i = y_i \log(\mu_i) - \mu_i - \log(y_i!). |
| [simulate()](#simulate) | Simulate Poisson-distributed response values with mean `mu`. |
| [unit_deviance()](#unit_deviance) | Per-observation Poisson deviance contributions. |
| [variance()](#variance) | Poisson variance function: V(\mu) = \mu. |

------------------------------------------------------------------------


### deviance()


Total Poisson deviance, the (weighted) sum of `unit_deviance`.


Usage

``` python
deviance(
    y,
    mu,
    *,
    weights=None,
)
```


#### Parameters


`y: NDArray`  
Observed response values (counts), shape `(n,)`.

`mu: NDArray`  
Fitted conditional mean values, shape `(n,)`.

`weights: NDArray | None = None`  
Optional prior weights, shape `(n,)`.


#### Returns


`float`  
The total (weighted) deviance.


------------------------------------------------------------------------


### initialize()


Starting values for `mu`: `y` nudged away from zero.


Usage

``` python
initialize(y)
```


Since the log link requires strictly positive `mu`, small or zero counts are pushed away from zero to avoid `log(0)` on the first P-IRLS iteration.


#### Parameters


`y: NDArray`  
Observed response values (counts), shape `(n,)`.


#### Returns


`NDArray`  
Starting values for `mu`, shape `(n,)`.


------------------------------------------------------------------------


### link()


Apply the log link: \eta = \log(\mu).


Usage

``` python
link(mu)
```


#### Parameters


`mu: NDArray`  
Conditional mean values, shape `(n,)`. Should be positive; values are clipped to `_EPS` to avoid `log(0)`.


#### Returns


`NDArray`  
Linear predictor values \eta = \log(\mu), shape `(n,)`.


------------------------------------------------------------------------


### link_derivative()


Derivative of the log link: g'(\mu) = 1/\mu.


Usage

``` python
link_derivative(mu)
```


#### Parameters


`mu: NDArray`  
Conditional mean values, shape `(n,)`.


#### Returns


`NDArray`  
Derivative values 1/\mu, shape `(n,)`.


------------------------------------------------------------------------


### link_inverse()


Apply the inverse log link: \mu = e^{\eta}.


Usage

``` python
link_inverse(eta)
```


The linear predictor is clipped to `[-30, 30]` before exponentiating to guard against overflow while fitting.


#### Parameters


`eta: NDArray`  
Linear predictor values, shape `(n,)`.


#### Returns


`NDArray`  
Conditional mean values \mu = e^{\eta}, shape `(n,)`.


------------------------------------------------------------------------


### log_likelihood()


Poisson log-likelihood \ell_i = y_i \log(\mu_i) - \mu_i - \log(y_i!).


Usage

``` python
log_likelihood(
    y,
    mu,
    scale,
    *,
    weights=None,
)
```


The `scale` argument is accepted for interface compatibility but ignored, since the Poisson distribution has no free dispersion parameter (`scale_known` is `True`).


#### Parameters


`y: NDArray`  
Observed response values (counts), shape `(n,)`.

`mu: NDArray`  
Fitted conditional mean values, shape `(n,)`.

`scale: float`  
Ignored.

`weights: NDArray | None = None`  
Optional prior weights, shape `(n,)`.


#### Returns


`float`  
The total log-likelihood.


------------------------------------------------------------------------


### simulate()


Simulate Poisson-distributed response values with mean `mu`.


Usage

``` python
simulate(
    mu,
    scale,
    rng,
)
```


#### Parameters


`mu: NDArray`  
Mean (fitted values), shape `(n,)`.

`scale: float`  
Ignored (the Poisson distribution has no free dispersion parameter).

`rng: np.random.Generator`  
A `numpy.random.Generator` instance.


#### Returns


`NDArray`  
Simulated response values, shape `(n,)`.


------------------------------------------------------------------------


### unit_deviance()


Per-observation Poisson deviance contributions.


Usage

``` python
unit_deviance(
    y,
    mu,
)
```


Computes d_i = 2 \left\[ y_i \log(y_i / \hat\mu_i) - (y_i - \hat\mu_i) \right\], with the convention y_i \log(y_i / \hat\mu_i) = 0 when y_i = 0.


#### Parameters


`y: NDArray`  
Observed response values (counts), shape `(n,)`.

`mu: NDArray`  
Fitted conditional mean values, shape `(n,)`.


#### Returns


`NDArray`  
Per-observation deviance contributions, shape `(n,)`.


------------------------------------------------------------------------


### variance()


Poisson variance function: V(\mu) = \mu.


Usage

``` python
variance(mu)
```


The variance equals the mean, so `Var(Y) = phi * V(mu) = mu` since `phi = 1` for Poisson (see `scale_known`).


#### Parameters


`mu: NDArray`  
Conditional mean values, shape `(n,)`.


#### Returns


`NDArray`  
Variance values V(\mu) = \mu, shape `(n,)`.
