如何找到函数中的最优值以获得最佳结果?

How to find the optimal value in a function to get the best result?

这是一个更大数据的示例,但想象一下我有这样一个 DataFrame:

import pandas as pd
from sklearn.metrics import r2_score

df = pd.DataFrame({'x':[0.04, 0.08, 0.09, 0.07, 0.07],
                   'y':[0.67, 0.46, 0.41, 0.43, 0.40]})

我有一个公式可以计算新的 'y' 值,我将在此处将其称为 'y_pred':

# y_pred = (1 - x) / (1 + c * x)

我的目标是定义 'c' 的最佳值(因为它是一个常数),但我不能每次都手动更改 'c'。比如这里我把'c'当成10:

df['y_pred'] = (1 - df['x']) / (1 + 10 * df['x'])
    
r2 = r2_score(df['y'], df['y_pred'])

有没有一种方法或函数可以用来为我设置最佳 'c',从而使我的数据获得最佳 r2 分数?

这个问题有点棘手,因为 scipy.optimize 中的 minimize 只接受单个参数的函数。那个参数必须是初始值。

首先让我们定义你的函数:

def my_func(df, c):
    df['y_pred'] = (1 - df['x']) / (1 + c * df['x'])
    return -r2_score(df['y'], df['y_pred'])

请注意,返回负值是因为我们要使用最小化例程。因此,整体效果是我们正在最大化函数。

现在为了解决单参数的问题,我们可以使用 functools 中的 partial

from functools import partial
cost_function = partial(my_func, df)

现在cost_function只能接受一个参数,因为df已经被吸收了。您可以使用 cost_function(c=10) 来测试它,它给出 -0.14321448901325817.

Rest 是标准的最小化代码。我使用了 Nelder-Mead,但您可以尝试使用 scipy.

中的许多其他例程
from scipy.optimize import minimize
x0 = 10 #initial guess
res = minimize(cost_function, x0, method='Nelder-Mead', tol=1e-6)

这给出:

 final_simplex: (array([[14.30974102],
       [14.30974197]]), array([-0.80003086, -0.80003086]))
           fun: -0.8000308591966453
       message: 'Optimization terminated successfully.'
          nfev: 48
           nit: 24
        status: 0
       success: True
             x: array([14.30974102])

函数为 c = res[x] = array([14.30974102]) 最大化,其中值为 res[fun] = -0.8000308591966453。再次注意负数是因为我们从函数返回负数。