model: use guess method where present to automatically populate parameters when appropriate #886
Replies: 11 comments 3 replies
-
@jagerber48 Models are independent of particular parameter values, so that it is really the combination of a Model (an idealized "Guassian" or "Decaying Sine Wave") and set of independent data, and a set of Parameter values that give a representation of a dataset: "A Gaussian centered at 4000 with a width of 12" or "A Decaying Sinewave with frequency of 1030 kHz", for example.
Parameter hints are really intended to indicate characteristics of Parameters for a Model in order for the Model to make sense. In general, Parameters do not need boundaries, but for most of the Peak-like models there are Parameters that correspond to a width (typically called When you do a fit, the result includes update parameter values, so that you can compare the initial parameters and the best-fit parameters. |
Beta Was this translation helpful? Give feedback.
-
@newville
But the suggestion is to be able to do:
with the same result. Right now the second version runs, but seems to populate the initial parameters with some default value for the model. I guess my suggestion is that, rather than use default parameters which may or may not exist and which have no relation to the data set Basically if a parameter is not supplied by the user then it uses the guess value (extracted by running Alternatively, if excluding parameters in fit requests is to be discouraged, maybe ALL implicit auto-population of parameters should be removed... But that doesn't seem user-friendly. |
Beta Was this translation helpful? Give feedback.
-
I would be very much against that. If the user does not pass in parameters, the initial values should not be guessed automatically. The values will take the default values defined by the model.
I am strongly opposed. There should be less magic in setting Parameters and more enforcement of creating parameters. If a user wants to use
I am strongly opposed to having a finite default value for parameters. It is OK if a model function sets a default for some parameters. If we are ever in a position where we are going to set initial values because neither the user nor the person who wrote the model gave one, the only values I would be in favor of using are -np.inf or np.nan.
I would be strongly opposed to removing parameters. |
Beta Was this translation helpful? Give feedback.
-
They are only given default parameters if those are in the definition of the model function. So, as if the person writing the model wanted there to be default values.
If you strongly prefer using guessed parameter values, then guess parameter values and use them. Good choice. Don't rely on that being done automatically. Sometimes the guesses are not very good. There should be a step in your code between "guess values" and "use those guessed values".
I do not think that. I think automagically setting values is the opposite of a virtue.
Initial values for Parameters are always dependent on the data and it is always the responsibility of the user to provide initial values. One of the most frustrating parts about supporting this library or helping people with
The downside of magic is the illusion.
I would not be in favor of that. The only change I might ever favor would be to have initial default values be np.nan or -np.inf unless explicitly set by the user when creating parameters. Currently, parameter values that are unspecified (by the input Parameters or function definition) do get an initial value of -np.inf. All fits would then immediately fail. Changing from using initial values as set in the function definition to ignoring initial values set in the function definition and setting those values to -np.inf (including for the sort of "optional variables") would probably break many existing scripts, and not be widely seen as a positive change. I'm okay with the code as it is. |
Beta Was this translation helpful? Give feedback.
-
I'm fine with doing less magic, so if automatically implementing guesses is off the table the fine. I guess I would reframe the discussion then. See this code at the top of Lines 1008 to 1011 in 502cc9b I feel like you already addressed by points below, but now that I understand you stance I just want to clarify directly: If the entirety of your answer is "it would break backwards compatibility" then I understand, but I would also suggest (but not insist, I realize there are lots of good reasons not to break people's code) that the function could be changed over time with a deprecation schedule. If there are defenses of having Actually, a softer solution is to give a warning anytime the user doesn't pass in |
Beta Was this translation helpful? Give feedback.
-
@jagerber48 Well, for the gentle users who go to the trouble to read the documentation and examples, they will see that they can do this:
I would like to not break that. This is a fairly mature and stable project. We are mostly out of the design phase and focused on fixing problems. Features might be added as they are needed but with a strong emphasis on not breaking existing usage. When we do change things, we generally are solving documented problems. You seem sort of committed to trying to change something. I think it would be necessary to identify a problem that you are having and want to solve. If that problem involves setting initial values for parameters, I think you will get only get a response of "the user needs to ensure that good initial values are provided" unless you can document a convincing use case that shows a real problem. |
Beta Was this translation helpful? Give feedback.
-
So there are two cases, one (1) where the users somehow provides initial values for all required parameters to seed the minimization algorithm and one (2) where the user omits one or more initial values for required parameters. Note that for the purposes of this discussion, I'm considering the required parameters to be the ones that appear in the function signature. I realize that when additional parameters are defined and constrained via algebraic relations the list of required parameters may differ from the list of parameters in the function signature. But to simplify things, let's just consider a model that has a function with N parameters in its signature and the user is trying to do a fit with N lmfit parameters that are 1:1 with those parameters in the function signature. The former case (1) (where the user provides initial values for all N required parameters) I think you and I are both happy with. Especially after your initial comments, I gather that you want to encourage users to always be working in the former case. I don't deeply care if the initial values are passed in a formal But, in this thread, I'm investigating the behavior of the package in the LATTER case (2), in which the user has NOT provided sufficient initial value to seed the minimization routine. The package has two options in this case, (2A) it can either fail, and raise some kind of error, or (2B) it can try to patch the list of initial values so that it can proceed. My reading is that (2A) would be more in line with the spirit of "encouraging users to pass parameters". But indeed, the package actually takes option (2B). If the user fails to pass in parameters, then the package patches the missing parameters with default values from the function. Taking options (2B) over (2A) is all about convenience because it allows the user to be more lazy. So upon seeing that the package takes option (2B), I wanted to suggest that it would be more convenient for the package to attempt to patch missing initial parameters with guess values rather than function default values, because, for generic data, the guess values have a much higher chance of resulting in a successful fit than the function default values. You shot that idea down as being too "magic" which I accept. But I think that chain of reasoning leaves the package in a hypocritical state. You say that you don't want there to be magic under the hood that does stuff automatically, but the patching with default function parameters is exactly this. So in my eyes, the current behavior is the WORST of both worlds. The user can be lazy and pass nothing in, but what they'll get back is a really bad guess. The documentation warns against this, but I'm suggesting to put more protections in code. Either raising errors when users don't pass in enough initial parameters, or at least printing warnings.
Consider this code:
It's obvious why the fit failed, it's initial parameter is 0 (which appears nowhere in the code block, but only deeply inside the The code to detect if the users pass in all parameters would look something like taking the union of the parameters passed in in the Your response could just be: "The fit failed because the user passed in bad guess parameters", no changes to the code are necessary. But what I'm suggesting is helping the user by telling them, in code, not just documentation, what they are doing wrong. |
Beta Was this translation helpful? Give feedback.
-
@jagerber48 as we say REPEATEDLY, a fit that gives a bad result is not an error. Initial values always matter. Not 90% of the time, not 99.99% of the time. Initial values matter for every single fit. The total number of exceptions to this rule over the lifetime of the universe is ZERO. In addition, it is DEFINITELY NOT A BUG if a fit gives a bad result. Not something that needs fixing.
No, we do not. How would we know that at run time?
Um, read the fit report. |
Beta Was this translation helpful? Give feedback.
-
If this feature is out of scope for this project at it's level of maturity for some reason then that is fine I guess, though I don't fully understand the argument since it can be done in a backwards compatible way and is only the addition of a warning. It is a suggestion to make the tool more user-friendly. If you think it will not make the tool more user-friendly, or it will make it more user-friendly but it is not worth it anyways, then that is ok, we can leave it there. |
Beta Was this translation helpful? Give feedback.
-
@jagerber48 I am simply unable to keep up with your changing suggestions. You seem intent to change something, quite possibly with the goal being to change something. I am not in favor of that. You said earlier today that it "was obvious" why a fit failed when an initial value was "out of range". The code you propose does not try to catch that. Without knowing the details of the function itself, it is basically impossible to tell what a Parameter does, so it's not surprising that you don't try to catch this -- that would be very, very hard. But you did say it was obvious. The person writing the function might have reasons to give default initial values to variables. For example, one reason might be to give "typical values", or so that keyword arguments can be clearly distinguished between "numerical arguments to be turned into parameters" vs "non-numeric arguments that are not to be turned into parameters". That is, default values for arguments in a model function are definitely allowed because those are Python functions that allow them, and we are definitely going to continue to support code that relies on that advertised feature. That doesn't mean or imply in any way that those default values are suitable for all situations. |
Beta Was this translation helpful? Give feedback.
-
@newville sorry for any harsh/direct tones in the last message. I was getting a little frustrated since I felt you were missing or mischaracterizing my points. I feel like I make it sound like everything is terrible. In fact, it's the opposite. I think |
Beta Was this translation helpful? Give feedback.
-
Not necessarily something I think should definitely be in lmfit, but curious to have a discussion to see if it makes sense. A nice behavior would be that if I try to perform a fit with a model that the model auto-populates any parameters I have explicitly supplied using the model's guess method. I can see that these parameters get auto-populated now already but I'm not sure where their values come from. Would this behavior conflict with other existing functionality? Maybe parameter hints (I don't understand these yet)?
Beta Was this translation helpful? Give feedback.
All reactions