Generation of free running list of lapse rate and guess rate for psychometric curve fitting (Scipy)

耗尽温柔 提交于 2019-12-12 03:28:19

问题


As a new user to the curve fitting function from scipy and a relatively new user of python, I am a little confused as to what *popt and p0 exactly generates (with reference to this)

So I am trying to plot a psychometric fitting here based of a customized sigmoid function formula that accounts for a guess and lapse rate (Both with values between 0 and 1 to account for participant guessing and performance lapse rates in an experiment. These values would define the fit on the lower and upper end of the curve fit respectively.)

I can get the function to generate the best lapse rate it could fit to the curve when a fixed guess rate was set outside the function. But when I want the function to generate both the best lapse rate and guess rate, it couldn't, and gave the following error:-

File "C:\Users\Aaron\Anaconda2\lib\site-packages\scipy\optimize\minpack.py", line 447, in _general_function return function(xdata, params) - ydata TypeError: sigmoidscaled() takes exactly 5 arguments (4 given)

Now I am aware that this means that there was no value coming from the 'guess rate' variable and thus this error. So how is it that the function was able to generate a 'lapse rate' but not a 'guess rate' here?

These are the codes when the guess rate is a prefixed value and the curve fit is successful:-

import numpy as np
import pylab
from scipy.optimize import curve_fit
from matplotlib.pyplot import *

n = 20 #20 trials
ydata = [0/n, 9.0/n, 9.0/n, 14.0/n, 17.0/n] #Divided by n to fit to a plot of y =1
xdata = np.array([ 1.0, 2.0, 3.0, 4.0, 5.0])

guess = 0.05 #Set the minimum chance level

#The scaled sigmoid function
def sigmoidscaled(x, x0, k, lapse):
    F = (1 + np.exp(-k*(x-x0))) 
    z = guess + (1-guess-lapse)/F
    return z

p0=[1,1,-10] 
popt, pcov = curve_fit(sigmoidscaled, xdata, ydata, p0, maxfev = 3000)

#Start and End of x-axis, in spaces of n. The higher the n, the smoother the curve.
x = np.linspace(1,5,20)
#The sigmoid values along the y-axis, generated in relation to the x values and the 50% point.
y = sigmoidscaled(x, *popt)

pylab.plot(xdata, ydata, 'o', label='Psychometric Raw', color = 'blue')
pylab.plot(x,y, label='Psychometric Fit', color = 'blue')
#y axis range.
pylab.ylim(0, 1)
#Replace x-axis numbers as labels and y-axis numbers as percentage
xticks([1., 2., 3., 4., 5.], ['C1','CN2','N3','CN4','S5'])
yticks([0.0, 0.2, 0.4, 0.6, 0.8, 1.0], ['0%','20%','40%','60%','80%','100%'])
pylab.legend(loc='best')
xlabel('Conditions')
ylabel('% perceived more sin like')
pylab.show()

Whereas when I tried to have the formula try to find the best 'guess' value, it couldn't. (Here, 'guess = 0.05 #Set the minimum chance level' was removed and a guess variable inserted into the sigmoid function.) :-

import pylab
from scipy.optimize import curve_fit
from matplotlib.pyplot import *

n = 20 #20 trials
ydata = [0/n, 9.0/n, 9.0/n, 14.0/n, 17.0/n] #Divided by n to fit to a plot of y =1
xdata = np.array([ 1.0, 2.0, 3.0, 4.0, 5.0])


#The scaled sigmoid function
def sigmoidscaled(x, x0, k, lapse, guess):
    F = (1 + np.exp(-k*(x-x0))) 
    z = guess + (1-guess-lapse)/F
    return z

p0=[1,1,-10] 
popt, pcov = curve_fit(sigmoidscaled, xdata, ydata, p0, maxfev = 3000)

#Start and End of x-axis, in spaces of n. The higher the n, the smoother the curve.
x = np.linspace(1,5,20)
#The sigmoid values along the y-axis, generated in relation to the x values and the 50% point.
y = sigmoidscaled(x, *popt)

pylab.plot(xdata, ydata, 'o', label='Psychometric Raw', color = 'blue')
pylab.plot(x,y, label='Psychometric Fit', color = 'blue')
#y axis range.
pylab.ylim(0, 1)
#Replace x-axis numbers as labels and y-axis numbers as percentage
xticks([1., 2., 3., 4., 5.], ['C1','CN2','N3','CN4','S5'])
yticks([0.0, 0.2, 0.4, 0.6, 0.8, 1.0], ['0%','20%','40%','60%','80%','100%'])
pylab.legend(loc='best')
xlabel('Conditions')
ylabel('% perceived more sin like')
pylab.show() 

回答1:


p0 is the starting point for the fit procedure. popt is the resulting best-fit values of the parameters.

Note that curve_fit assumes that the signature of your function if f(x, *parameters): the first argument is an independent variable for which you have xdata, and the rest are parameters that you want optimized.

In your first example, sigmoidscaled takes four arguments, and you provide a length-three list for p0. This way, the fitting starts with x0 = 1; k = 1; lapse = -10.

In your second example, sigmoidscaled takes five arguments, meaning you're fitting four parameters for which you need initial values.

Quick check:

In [22]: p0 = [1, 1, -10, 0]    # add the 4th element

In [23]: popt, pcov = curve_fit(sigmoidscaled, xdata, ydata, p0, maxfev = 3000)

In [24]: popt
Out[24]: array([ -1.97865387e+01,   3.31731590e-01,  -1.03275740e-01,
        -1.05595226e+03])


来源:https://stackoverflow.com/questions/37044905/generation-of-free-running-list-of-lapse-rate-and-guess-rate-for-psychometric-cu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!