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

Implement a Sigmoid.standard_parameters method #169

Merged
merged 9 commits into from
Nov 28, 2024

Conversation

pberkes
Copy link
Collaborator

@pberkes pberkes commented Nov 26, 2024

Fix #160

Once I implemented the standard parameters, there was no reason to have the hand-written formulas for the rest around. I changed all sigmoids to use the scipy.stats implementation of the distribution, which are more optimized and use numerically robust equations.

As a result, the code is simpler now.

@pberkes
Copy link
Collaborator Author

pberkes commented Nov 26, 2024

To get the parameters estimate as standard parameters from a Result object, one needs to do:

sigmoid = result.configuration.make_sigmoid()
sigmoid.standard_parameters(res.parameter_estimate['threshold'], res.parameter_estimate['width'])

It's not very convenient, we might want to add a method Result.standard_parameters_estimate once #161 is merged

@otizonaizit
Copy link
Collaborator

This looks good @pberkes : I like the fact that you are finally leveraging the object hierarchy already available in scipy.stats instead of cooking our own solution like we were doing before this PR.

One thing I am left wondering about is: what happens if someone wants to implement a sigmoid that does not have a corresponding distribution in scipy.stats? Before it was relatively clear, now I am not sure how I would go about it... It is maybe just a matter of documenting the procedure in a bit more detail in the docs of the sigmoids.py module? Or is the shift to using the methods of the scipy distribution objects making this harder than before?

I am not sure that writing your own sigmoid is such an important use case, but it is at least worth a clear note in the docs of the module.

@otizonaizit
Copy link
Collaborator

And please feel free to merge after addressing my comment :-)

@pberkes
Copy link
Collaborator Author

pberkes commented Nov 26, 2024

@otizonaizit I wondered the same...

I thought I could do:

  1. have a base class Sigmoid with abstract _value, _slope, _threshold, and _standard_parameters
  2. a subclass ScipySigmoid with the current implementation
  3. all of the sigmoids as subclasses of ScipySigmoids

Idk in my opinion the probability that someone writes their own sigmoid is low, and that some writes one that does not correspond to one of the distributions in scipy even lower (but that's my uneducated guess). The low probability does not justify a complex hierarchy, in my opinion.

Another possibility is to merge 1)+2) and have a base class Sigmoid with abstract _value, _slope, _threshold, and _standard_parameters, and also the current implementation with _scipy_distr. That would allow defining a new subclass that has a bogus _scipy_distr and implements _value, _slope, _threshold, and _standard_parameters directly. Architecturally it's not very clean, it's kind of a compromise solution.

what do you think?

@otizonaizit
Copy link
Collaborator

another option is to just document what is the expected public API of a Sigmoid object.

If I look at the code it seems to me that we are only using Sigmoid.__call__, Sigmoid.inverse and Sigmoid.standard_parameters, and for plotting Sigmoid.slope.

So what about explaining in the docs what these methods are supposed to return? We can then say that in the case of a distribution that is already available in scipy.stats it is even easier, because then it is enough to override the Sigmoid._scipy_distr and Sigmoid._standard_parameters methods.

So, just change the docs but leave the code as it is in this PR?

@pberkes
Copy link
Collaborator Author

pberkes commented Nov 27, 2024

@otizonaizit ok so if I understand, option 2 is what we want. I reintroduced _value, _slope, and _inverse, and explain in the docstring what are the options for defining a new sigmoid. what do you think?

@otizonaizit
Copy link
Collaborator

Yes, this is cool! Before merging you could still add the method to the Result object that you were mentioning in #169 (comment)?
Also, given that this is a serious refactoring of the sigmoid code, wouldn't it be worth it to address also #170 ? Otherwise merging this PR will trigger changes in the docs and tutorials, that then would have to be changed again after #170 is addressed?
But given that your time is limited, I would be fine with merging this PR as-is, and addressing your comment and #170 later.

@pberkes
Copy link
Collaborator Author

pberkes commented Nov 28, 2024

Added Results.standard_parameters_estimate
I'll do #170 in a separate PR, if it's ok -- I won't have time for a few days

@otizonaizit otizonaizit merged commit 5a67f9d into wichmann-lab:main Nov 28, 2024
6 checks passed
@pberkes pberkes deleted the standard-params branch November 28, 2024 16:39
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.

Get Standard Parameters
2 participants