【问题标题】:Fitting cubic polynomial coefficients with GridSearchCV用 GridSearchCV 拟合三次多项式系数
【发布时间】:2021-03-09 06:00:21
【问题描述】:

我有一个三次多项式,具有已知系数 a、b、c 和 d。

我想编写一个算法,根据一组提供的 x 和沿曲线对应的 y 坐标找到这些系数。

这似乎是一个非常简单的参数调整案例。我想指定一系列可能的值,并让 GridSearchCV 遍历所有组合,对结果进行评分并推荐具有最高得分(或最低成本函数)的值组合。

这是我的代码:

import numpy as np
from sklearn.model_selection import GridSearchCV


def poly(x,a=1,b=1,c=1,d=1):
    
    """A polynomial function that calculates a polynomial function for an array of x values
    a, b, c & d are the coefficients of the polynomial"""
    
    y = a*x**3 + b*x**2 + c*x + d
    
    return y

# Regular values along the x axis
x_range = np.arange(-10,11,1)

# The 'true' coefficients
a_t = 0.1; b_t = -0.5; c_t = 0.8; d_t = 10

# Y values of the 'true' polynomial along the x axis
y_true = poly(x_range, a_t,b_t,c_t,d_t)


######## Fit the parameters ########

model = poly(x=x_range)

# define a grid of parameters to sort through 

param_grid={
    'a' : [0,0.1,0.2],
    'b' : [-1,-0.5,0,0.5,1],
    'c' : [1,2],
    'd' : [0,10,20,30]}

grid = GridSearchCV(model, param_grid=param_grid, scoring='neg_mean_squared_error')

grid.fit(x_range, y_true)

我收到错误消息:“TypeError: estimator 应该是实现 'fit' 方法的估计器,array([-909, -656, -455, -300, -185, -104, -51, -20 , -5, 0, 1, 4、15、40、85、156、259、400、585、820、1111])通过了"

我想知道我需要向 grid.fit 函数提供什么,以使其遍历 param_grid 并根据提供的 y_true 值找到得分最高的参数组合。

【问题讨论】:

  • 错误是因为您将一个数组(poly 的输出)传递给GridSearchCV,而它需要一个 scikit 估计器,例如sklearn.svm.SVC()。是否可以澄清为什么要使用GridSearchCV 来获取系数而不是回归模型?在您使用的设置中,没有用于训练估计器的任何免费参数。如果您只有 4 个系数要估计,那么回归就足够了,除非您的问题是您正在研究的更大模型的一部分?

标签: scikit-learn curve-fitting hyperparameters model-fitting gridsearchcv


【解决方案1】:

事实证明,GridSearchCV 不是满足我要求的正确工具。感谢 balleveryday 的富有洞察力的评论。

我应该一直在使用 scipy.optimize 库。以下是使用 optimize.curve_fit 和 optimize.minimise 模块的两种解决方案:

两者的基本代码:

import numpy as np
import math

def poly(x,a,b,c,d):
    
    """A polynomial function that calculates y values for an array of x values.
    a, b, c & d are the coefficients of the polynomial"""
    
    y = a*x**3 + b*x**2 + c*x + d
    
    return y

# Regular values along the x axis
x_range = np.arange(-10,11,1)

# The 'true' coefficients
a_t = 0.1; b_t = -0.5; c_t = math.pi/3; d_t = math.pi*2

# Y values of the 'true' polynomial along the x axis
y_true = poly(x_range, a_t,b_t,c_t,d_t)

bounds = np.array( [(0,1), (-2,2), (-3,3), (0,20)] )

initial_guess = np.array([0.5,-1, 1.2, 10])

curve_fit解决方案:

from scipy.optimize import curve_fit

popt, pcov = curve_fit(poly, x_range, y_true, p0 = initial_guess, bounds = bounds.T)

print(popt)

minimize 解决方案有两种不同的最小化方法:

from scipy.optimize import minimize

def cost_fn(guess_array,true_array):
    
    diff = guess_array - true_array
    min_quad = np.mean(diff**4)
    
    return(min_quad)


def calculate_cost(params):
    
    y_trial = poly(x_range, a=params[0], b= params[1], c=params[2], d=params[3])
    
    cost = cost_fn(y_trial,y_true)
    
    return(cost)

for method in ['Powell', 'L-BFGS-B']:
    res = minimize(fun = calculate_cost, 
                   x0 = initial_guess,
                   bounds = bounds,
                   method = method,
                  )

    print(res.x)

【讨论】:

    猜你喜欢
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多