ECSHackWeek / impedance.py

A Python package for working with electrochemical impedance data
MIT License
212 stars 102 forks source link

Simple method for retrieving reduced Chi^2 value #142

Open FTHuld opened 3 years ago

FTHuld commented 3 years ago

Hi.

I'm wondering if there is a way to extract the reduced Chi^2 value calculated by the fit in a similar way to lmfit's output.result.redchi.

If it's already implemented I haven't been able to find it in the docs.

mdmurbach commented 3 years ago

Hi @FTHuld, I don't believe there is currently, but it should be relatively straightforward to implement and I'd be happy to help you out with a pull request.

FTHuld commented 3 years ago

Thank you @mdmurbach. I'm not quite sure how to calculate these values when the data is a complex value. I guess we would just take the real part and go from there?

krillin666 commented 3 years ago

Thank you @mdmurbach. I'm not quite sure how to calculate these values when the data is a complex value. I guess we would just take the real part and go from there?

Hello, any update on this ? i am trying to figure a way to obtain the chi square value but I'm having difficulty finding an way how. I know your "circuit_fit" function can return the standard deviation of the fit parameters, I have the two arrays of experimental and fitted data, but in the chi square function where I do the sum of the square of difference of the experimental data with the fitted data over the standard deviation, I'm not sure how to obtain the standard deviation for each value instead of the standard deviation of the fitted parameters. Just to be clear, I am not familiar with this type of statistical analysis so I may be getting things a little bit confused !

If you can help me in any direction with this it would be of great help !

Thank you !

FTHuld commented 3 years ago

*Edit: the code published below was incorrect (missing **2 in Chi_square, used complex value instead of real portion) when I submitted it yesterday.

Hi @krillin666.

I don't have a background in statistics, so I can't say that my method is completely correct, but I've been calculating the reduced Chi square using the following code:

# Circuit 
circuit = CustomCircuit(equivalent_circuit, initial_guess=initial_guess) 
circuit.fit(frequencies, Z)
Z_fit = circuit.predict(frequencies)

Re_Z = np.real(Z)                                        # Extract real part of Z
Re_Z_fit = np.real(Z_fit)                                # Extract real part of Z_fit

dof = len(Re_Z)-len(initial_guess)                        # Degrees of freedom - i.e. number of data points - number of variables
variance = sum((Re_Z-Re_Z.mean())**2) / (len(Re_Z)-1)    # Variance
Chi_square = sum(((Re_Z-Re_Z_fit)**2)/variance)          # Chi squared
red_Chi_sq = Chi_square / dof                            #Reduced Chi squared

The formula for the reducd Chi square is taken from https://en.wikipedia.org/wiki/Reduced_chi-squared_statistic

This outputs reduced Chi squared value for the real part of the fitting

I think it would be great to be able to extract these values directly from the fitting, but I honestly don't know where the above code needs to be placed (once it's been confirmed to be correct, of course).