如何找到函数中的最优值以获得最佳结果?
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
。再次注意负数是因为我们从函数返回负数。
这是一个更大数据的示例,但想象一下我有这样一个 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
。再次注意负数是因为我们从函数返回负数。