pymc-devs / pymc-experimental

https://pymc-experimental.readthedocs.io
Other
77 stars 49 forks source link

CDF of GenExtreme gives zero instead of one for larger values #347

Open souvikpaul33 opened 3 months ago

souvikpaul33 commented 3 months ago

Hi I am using GEV for classification. Here in the example below, I wanted to check a few things like logcdf and cdf works for GenExtreme. Though, now I am able to find logcdf or cdf, some logcdf values are coming -inf (i.e. cdf 0), which should be 0 (i.e. cdf 1).

My Random Variable is GEV($\mu$ = 0, $\sigma$ = 1, $\xi$ = -0.5). So, range of the RV is ($-\infty, -1/\xi$)=($-\infty$, 2). So, logcdf should come as 0 (i.e. cdf 1) for RV>=2. But see the below example it’s -\infty$ for RV>=2.

Please help to find out what is wrong and how solve it! I could make some conditions for checking and could make 0 to 1, but I will run it inside pm.Model(),this kind of condition can make it slow. Thank you.

import numpy as np import pymc as pm import pymc_experimental.distributions as pmx

rv = pmx.GenExtreme.dist(mu=0, sigma=1, xi=-0.5) # range of x: (-inf, 2) x = np.array([-100,-50,-40, -30, -10,-5,-2,-1,0,1,1.5,1.7,1.9,1.99,2,3,4,5]) lcdf_gev = pm.logcdf(rv, x) print(x) [-100. -50. -40. -30. -10. -5. -2. -1. 0.

  1. 1.5 1.7 1.9 1.99 2. 3. 4. 5. ]

print(lcdf_gev.eval()) [-2.601e+03 -6.760e+02 -4.410e+02 -2.560e+02 -3.600e+01 -1.225e+01 -4.000e+00 -2.250e+00 -1.000e+00 -2.500e-01 -6.250e-02 -2.250e-02 -2.500e-03 -2.500e-05 -inf -inf -inf -inf]

print(np.exp(lcdf_gev.eval())) [0.00000000e+000 2.61174176e-294 2.99318445e-192 6.61626106e-112 2.31952283e-016 4.78511739e-006 1.83156389e-002 1.05399225e-001 3.67879441e-001 7.78800783e-001 9.39413063e-001 9.77751237e-001 9.97503122e-001 9.99975000e-001 0.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000]

image

ricardoV94 commented 3 months ago

The logcdf implementation seems to have no special logic for out of bounds x: https://github.com/pymc-devs/pymc-experimental/blob/main/pymc_experimental/distributions/continuous.py#L203-L213

CC @ccaprani

souvikpaul33 commented 3 months ago

Thank you very much. I updated it on my local machine. Now, it works perfectly. Previously, it was

image

Now I updated it in my local machine to - image

i.e. I replace -np.inf by pt.switch(xi>0,-np.inf,0)

ricardoV94 commented 3 months ago

Want to open a PR to contribute the fix to the codebase?

ccaprani commented 3 months ago

@souvikpaul33 you should! It's a great find & fix. I'll do it otherwise, but really appreciate your work on it 👍

souvikpaul33 commented 3 months ago

@ricardoV94 @ccaprani thank you very much! It would be great if I could open a PR and contribute. What do I need to do?

ricardoV94 commented 3 months ago

@ricardoV94 @ccaprani thank you very much! It would be great if I could open a PR and contribute. What do I need to do?

This guide may help: https://www.pymc.io/projects/docs/en/stable/contributing/pr_tutorial.html

It's for pymc, but instructions should be similar for pymc-experimental. Let us know if you have any questions after reading it

souvikpaul33 commented 3 months ago

@ricardoV94 Thank you! I was trying it. Firstly, I fork the repository to my Github (souvikpaul33). Then when I tried to clone it using the command: git clone git@github.com:souvikpaul33/pymc-experimental.git , it's showing some 'access denied' and need for access.

How can I get the access ?

Screenshot 2024-06-11 011659

souvikpaul33 commented 3 months ago

Hi @ricardoV94 @ccaprani I have sent this pull request https://github.com/pymc-devs/pymc-experimental/pull/349 branch name: souvik

Please review!

Thank you very much!!