2016-04-05 1 views
2

У меня есть функция из нескольких аргументов. Я хочу оптимизировать его по отношению к одной переменной, сохраняя при этом константу. Для этого я хочу использовать minim_scalar из spicy.optimize. Я прочитал документацию, но я все еще смущен, как сказать minim_scalar, что я хочу свести к минимуму по переменной: w1. Ниже приведен минимальный рабочий код.Как использовать scipy.optimize minim_scalar, когда объектная функция имеет несколько аргументов?

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)) 

ответ

12

Вы можете использовать функцию лямбда

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

Вы можете также использовать частичную функцию.

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

В случае, если вам интересно о производительности ... это то же самое, что и с лямбдами.

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 
Смежные вопросы