Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asymmetric laplace distribution added #4392

Merged
merged 7 commits into from
Jan 5, 2021
Merged

asymmetric laplace distribution added #4392

merged 7 commits into from
Jan 5, 2021

Conversation

chandan5362
Copy link
Contributor

Asymmetric Laplace distribution added for #4351
please do let me know if there are any unnecessary changes or any changes that are yet to be made.

@codecov
Copy link

codecov bot commented Dec 29, 2020

Codecov Report

Merging #4392 (d333141) into master (aabec02) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4392      +/-   ##
==========================================
+ Coverage   88.15%   88.17%   +0.01%     
==========================================
  Files          88       88              
  Lines       14564    14587      +23     
==========================================
+ Hits        12839    12862      +23     
  Misses       1725     1725              
Impacted Files Coverage Δ
pymc3/distributions/__init__.py 100.00% <ø> (ø)
pymc3/distributions/continuous.py 94.59% <100.00%> (+0.14%) ⬆️

Copy link
Member

@ricardoV94 ricardoV94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few comments. I think you also need tests for the random method in test_distributions_random.py

pymc3/distributions/continuous.py Show resolved Hide resolved
pymc3/tests/test_distributions.py Outdated Show resolved Hide resolved
@ricardoV94
Copy link
Member

Great work @chandan5362!

One other minor thing you should do once you fix everything is to run pre-commit to auto-format your code to be in line with the rest of the PyMC3 codebase. You have some information here, in case this is new for you. That addresses the test that is currently failing.

@chandan5362
Copy link
Contributor Author

Hey @ricardoV94 , I have been trying to add unit test for random module for laplace_asymmetric but I ended up comparing numpy variable with theano.tensor varibale. which is giving following error.:unamused:
TypeError: Variables do not support boolean operations.
Here is the code that I have been trying to add

  def test_laplace_asymmetric(self):
          def ref_rand(size,kappa,b):
              u = np.random.uniform(size=size)
              x = -np.log((1 - u) * (1 + kappa ** 2)) / (kappa * b) * (
                  u > ((kappa ** 2) / (1 + kappa ** 2))
              ) + kappa * np.log(
                  u * (1 + kappa ** 2) / (kappa ** 2)
              ) / b * (
                  u < ((kappa ** 2) / (1 + kappa ** 2))
              )
  
              return x
  
          pymc3_random(pm.AsymmetricLaplace,{"b":Domain([0,1,np.inf]),"kappa":Rplus}, ref_rand=ref_rand)

would you please help me here a little ?

Copy link
Member

@Sayam753 Sayam753 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great so far @chandan5362. Coming to the error message, you can try out the comments below and check if the test passes.
The pymc3_random function checks if samples from distribution's random method and ref_rand come from same distribution. We need to have tests to check for shape consistencies as well. You can add a test for this very similar to how Normal distribution is tested here.

pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
@ricardoV94
Copy link
Member

ricardoV94 commented Dec 31, 2020

Also, you might have already done this, but if not, you should also implement the BaseTest. Here is the code for the Laplace distribution:

https://github.com/pymc-devs/pymc3/blob/master/pymc3/tests/test_distributions_random.py#L373-L376

Something similar should work for your distribution. I think this takes care of testing if random works with different sizes/shapes

Edit: This was probably what @Sayam753 was saying. Sorry for the repetition :)

@chandan5362
Copy link
Contributor Author

Thanks a lot @Sayam753 @ricardoV94 , It was really helpful.
Now that I know what actually was happening, I edited the random function and as Sayam said, values were supposed to be drawn with respect to the model, I did the same and the test is running perfectly fine.

@@ -218,7 +220,12 @@ def build_model(distfam, valuedomain, vardomains, extra_args=None):
distfam("value", shape=valuedomain.shape, transform=None, **vals)
return m


def laplace_asymmetric_logpdf(value, symmetry,scale = None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this taken from scipy? If so I would mention that in the doc-string and also add a TODO that it should be removed once scipy adds it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this taken from scipy?
yeah @twiecki , It has been taken from SciPy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK cool, then just add those notes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not properly black formatted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @twiecki ,
Wish you a very very Happy New Year.
please do review the PR and let me know if anything is yet to be added or removed.

pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
Copy link
Member

@Sayam753 Sayam753 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I addressed some changes to be made. I need some time to review the maths behind random method. Meanwhile you can work on the suggestions.

One more thing, you can give a mention of AsymmetricLaplace distribution in api source continuous.rst. Then we can have this distribution to show up in docs.
There also needs to be mention of Support, Mean and Variance in docstring for consistency.

Also, scipy 1.6.0 has been released a few days ago. It contains the asymmetric laplace distribution. In order to use it in test cases, we have to upgrade PyMC3 requirements. Ping @MarcoGorelli to ask if upgrading scipy will break anything or not.

pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
See also: https://en.wikipedia.org/wiki/Asymmetric_Laplace_distribution
"""

def __init__(self, b, kappa, testval=0.0, *args, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PyMC3 base Distribution class already handles testval that can be passed through kwargs. So, I think testval should not be there.
While building str representation of a distribution/model, PyMC3 inspects all arguments passed in __init__ method. With this way, testval may come up in the representation and can certainly be confusing to someone not familiar with test values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, Thanks
I will have a look at it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once I remove the testval , unit test outputs an error. I think, testval should be there. Please have a look at it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does something like this at the end of __init__ fix it?

self.mode = mu

Assuming you are already using mu (and have converted it to a tensor_variable)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I am curious to know how testval interacts self.mode.

Copy link
Member

@ricardoV94 ricardoV94 Jan 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it uses the mode to define the testval. If the mean or median is provided, one of those is used instead.

pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/tests/test_distributions.py Outdated Show resolved Hide resolved
pymc3/tests/test_distributions.py Outdated Show resolved Hide resolved
Copy link
Member

@Sayam753 Sayam753 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is turning out to be in good shape. The random, logp method and their tests need to be updated to also account for mu parameter.

pymc3/distributions/continuous.py Outdated Show resolved Hide resolved
pymc3/distributions/continuous.py Show resolved Hide resolved
@MarcoGorelli
Copy link
Contributor

MarcoGorelli commented Jan 5, 2021

In order to use it in test cases, we have to upgrade PyMC3 requirements. Ping @MarcoGorelli to ask if upgrading scipy will break anything or not.

My suggestion would be to first merge #4374, so that we test on the oldest supported scipy version, and then skip any tests which use a too modern scipy (see that same PR for an example) and run those tests during, say, the arviz-compat job, which uses the latest available versions of dependencies

I don't think the requirements should be updated if a feature from scipy is only needed to run the tests

@Sayam753
Copy link
Member

Sayam753 commented Jan 5, 2021

Last step would be to add this distribution for docs in api source continuous.rst and a mention in RELEASE-NOTES.md

@Sayam753 Sayam753 merged commit 044c407 into pymc-devs:master Jan 5, 2021
@Sayam753
Copy link
Member

Sayam753 commented Jan 5, 2021

Great work @chandan5362 🎉 . Thanks @twiecki @ricardoV94 for the helpful review.

@twiecki
Copy link
Member

twiecki commented Jan 5, 2021

What a great example of a high-quality PR and review! 💪

@chandan5362
Copy link
Contributor Author

Thanks a lot @ricardoV94 @twiecki @Sayam753 for being helpful and supportive .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants