9

I have a function of multiple arguments. I want to optimize it with respect to a single variable while holding others constant. For that I want to use minimize_scalar from spicy.optimize. I read the documentation, but I am still confused how to tell minimize_scalar that I want to minimize with respect to variable:w1. Below is a minimal working code.

import numpy as np
from scipy.optimize import minimize_scalar

def error(w0,w1,x,y_actual):
    y_pred = w0+w1*x
    mse = ((y_actual-y_pred)**2).mean()
    return mse

w0=50
x = np.array([1,2,3])
y = np.array([52,54,56])
minimize_scalar(error,args=(w0,x,y),bounds=(-5,5))
1
  • 1
    The error is a sum of squares and you are taking mean() which will divide by n which is not correct. Commented Apr 1, 2018 at 18:37

3 Answers 3

23

You can use a lambda function

minimize_scalar(lambda w1: error(w0,w1,x,y),bounds=(-5,5))
Sign up to request clarification or add additional context in comments.

Comments

6

You can also use a partial function.

from functools import partial
error_partial = partial(error, w0=w0, x=x, y_actual=y)
minimize_scalar(error_partial, bounds=(-5, 5))

In case you are wondering about the performance ... it is the same as with lambdas.

import time
from functools import partial
import numpy as np
from scipy.optimize import minimize_scalar

def error(w1, w0, x, y_actual):
    y_pred = w0 + w1 * x
    mse = ((y_actual - y_pred) ** 2).mean()
    return mse

w0 = 50
x = np.arange(int(1e5))
y = np.arange(int(1e5)) + 52

error_partial = partial(error, w0=w0, x=x, y_actual=y)

p_time = []
for _ in range(100):
    p_time_ = time.time()
    p = minimize_scalar(error_partial, bounds=(-5, 5))
    p_time_ = time.time() - p_time_
    p_time.append(p_time_  / p.nfev)

l_time = []
for _ in range(100):
    l_time_ = time.time()
    l = minimize_scalar(lambda w1: error(w1, w0, x, y), bounds=(-5, 5))
    l_time_ = time.time() - l_time_
    l_time.append(l_time_ / l.nfev)

print(f'Same performance? {np.median(p_time) == np.median(l_time)}')
# Same performance? True

Comments

1

The marked correct answer is actually minimizing with respect to W0. It should be:

minimize_scalar(lambda w1: error(w1,w0,x,y),bounds=(-5,5))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.