Search code examples
python-3.xcurve-fittinglmfit

Use lmfit Model - function has dataframe as argument


I want to use lmfit in order to fit my data.

The function I am using, has only one argument features. The content of features will be different (both columns and values), so I can't initialize parameters.

I tried to create a dataframe as here, but I can't use the guess method because this is for LorentzianModel and I just want to use Model.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import lmfit
from sklearn.linear_model import LinearRegression


df = {'a': [0, 0.2, 0.3], 'b':[14, 10, 9], 'target':[100, 200, 300]}
df = pd.DataFrame(df)

X = df[['a', 'b']]
y = df[['target']]

model = LinearRegression().fit(X, y)

features = pd.DataFrame({"a": np.array([0, 0.11, 0.36]),
                         "b": np.array([10, 14, 8])})

def eval_custom(features):
    res = model.predict(features)
    return res


x_val = features[["a"]].values

def calling_func(features, x_val):
    pred_custom = eval_custom(features)
    df = pd.DataFrame({'x': np.squeeze(x_val), 'y': np.squeeze(pred_custom)})

    themodel = lmfit.Model(eval_custom)
    params = themodel.guess(df['y'], x=df['x'])
    result = themodel.fit(df['y'], params, x = df['x'])
       
    result.plot_fit()


calling_func(features, x_val)

Solution

  • The model function needs to take independent variables and the individual model parameters as arguments. You're wrapping all of that into a single pandas Dataframe and then sending that. Don't do that.

    If you need to create a dataframe from the current values of the model, do that inside your model function.

    Also: a generic model function does not have a working guess function. Use model.make_params() and definitely, definitely (no exceptions, nope not ever) provide actual initial values for every parameter.