beni
beni

Reputation: 11

Minimize two variables with scipy optimize

I want to fit two learning rates (alpha), one for the first half of the data and one for the second half of the data. I was able to do this for just one learning but am running into errors when attempting to fit two.

These functions work when minimizing one variable:

optimize.fminbound(sse_f,0,1)

minimize_scalar(sse_f, bounds=(0,1), method='bounded')

I'm not sure if I can use fminbound/minimize_scalar or if I should use minimize() for two learning rates (alphas).

My function looks something like this, I've removed a few lines for simplicity but basically, I want to minimize SSE for the first half of the data and the second half separately.

def sse_f(a_1,a_2):
    data = []
    for _, row in temp.iterrows():
        alpha = a_1 #for first 120 rows use one alpha
        if row['trial_nr'] == 120: #for rows after 120 use second alpha
            alpha = a_2
        #calculate diff variables removed for simplicity 
        data.append([phase,pi,abs_PE])
    col = ['phase','abs_PE','congruency']
    df_ = pd.DataFrame(data, columns= col)
    df_a = df[(df['phase']=='a')]
    df_b =  df[(df['phase']=='b')]

    x = np.array(df_a[['congruency','abs_PE']]) #run linear regression for first half
    y = df_a['RT'] 
    sse_a = lin_reg(x,y)

    x_b = np.array(df_b[['congruency','abs_PE']]) #run linear regression for second half
    y_b = df_b['RT'] 
    sse_b = lin_reg(x_b,y_b) #calculate SSE
    return sse_a,sse_b #return SSE for first half and second half of data

The output of this function would be a tuple e.g:

sse_f(.43,.43)
(54487466.6875101, 17251575.11206138)

If i use the minimize() I get this error:

minimize(sse_f, x0=(0,0), bounds=[(0,0),(1,1)])

TypeError: sse_f() missing 1 required positional argument: 'a_2'

And if I use minimize_scalar() I get this error:

ValueError: Optimisation bounds must be scalars or array scalars.

Any pointers regarding how to fit two alphas or how why I get these errors would be greatly appreciated!

Upvotes: 0

Views: 529

Answers (1)

Andreas B
Andreas B

Reputation: 42

I just changed your function definition so that the list of tuples is given to alpha1 and alpha2 individualy. I wanted to test but i don't know what the variable temp is. But I think that the list is now put into the variables like follows [minimum(alpha1 , alpha2),maximum((alpha1 , alpha2)].

def sse_f(a):
    a_1=a[0]
    a_2=a[1]
    data = []
    for _, row in temp.iterrows():
        alpha = a_1 #for first 120 rows use one alpha
        if row['trial_nr'] == 120: #for rows after 120 use second alpha
            alpha = a_2
        #calculate diff variables removed for simplicity 
        data.append([phase,pi,abs_PE])
    col = ['phase','abs_PE','congruency']
    df_ = pd.DataFrame(data, columns= col)
    df_a = df[(df['phase']=='a')]
    df_b =  df[(df['phase']=='b')]

    x = np.array(df_a[['congruency','abs_PE']]) #run linear regression for first half
    y = df_a['RT'] 
    sse_a = lin_reg(x,y)

    x_b = np.array(df_b[['congruency','abs_PE']]) #run linear regression for second half
    y_b = df_b['RT'] 
    sse_b = lin_reg(x_b,y_b) #calculate SSE
    return sse_a,sse_b #return SSE for first half and second half of data

Let me know if it helped.

Upvotes: 1

Related Questions