【问题标题】:Using lmfit minimize to fit a 3D line on a dataset of 3D points使用 lmfit minimize 在 3D 点的数据集上拟合 3D 线
【发布时间】:2017-06-30 05:20:26
【问题描述】:

我正在使用 lmfit minimize 在 3D 点数据集上拟合 3D 线。

from lmfit import minimize, Parameters, report_fit,fit_report, printfuncs
import numpy as np

#Parameters of parametric equations:  
#x = p[0] + p[1]*t;
#y = p[2] + p[3]*t;
#z = t;
params = Parameters()
params.add('x0',   value= 1)
params.add('x1',   value= 1)
params.add('y0',   value= 1)
params.add('y1',   value= 1)

#Function to be minimized - sum of distances between the line and each point    
def fun(params,x,y,z):
    x0 = params['x0'].value; x1 = params['x1'].value 
    y0 = params['y0'].value; y1 = params['y1'].value
    d = 0  

    v0 = np.array([x0, y0, 0.0])
    v1 = np.array([x0+x1, y0+y1, 1.])
    for point in range(len(x)):           
        p = np.array([x[point], y[point], z[point]])
        d += np.linalg.norm(np.cross(v1-v0,v0-p))/np.linalg.norm(v1-v0)  
    return d


result = minimize(fun, params,args=(x,y,z)))
result.params.pretty_print()
print(fit_report(result))

错误是 TypeError: Improper input: N=4 must not超过 M=1.

我知道这是因为只有 1 个残差(距离)和 4 个参数,但这正是我所需要的。我想优化 4 个参数以获得最小的距离总和。

【问题讨论】:

    标签: python 3d scipy minimize lmfit


    【解决方案1】:

    问题是在您的情况下fun 返回一个标量。对于某些方法来说这很好,但正如您正确指出的那样,least_squares 需要一个数组。我认为重写你的目标函数使其返回一个数组应该可以解决这个问题 - 查看描述和示例here

    【讨论】:

      【解决方案2】:

      似乎是方法问题。

      目标函数应该返回要最小化的值。对于来自 leastsq() 或 least_squares() 的 >Levenberg-Marquardt 算法,此 >返回值必须是一个数组,长度大于或等于 >模型中拟合变量的数量。

      使用 Nelder,我得到了结果。 虽然不正确。所以仍然不确定代码。

      【讨论】:

        【解决方案3】:

        对于使用 Levenberg-Marquardt 最小化(lmfit.minimize() 的默认方法),您应该返回距离的 ndarray。也就是说,不要对自己进行最小二乘求和。通过返回完整数组(一组特定参数值的所有距离观测值),您可以让拟合算法更好地探索参数对拟合质量的影响。

        【讨论】:

        • 谢谢!我接受了另一个答案,因为它是第一个,但你是绝对正确的。
        猜你喜欢
        • 2010-10-09
        • 2011-01-22
        • 1970-01-01
        • 1970-01-01
        • 2013-09-04
        • 1970-01-01
        • 2019-10-19
        • 2019-01-17
        • 2011-11-08
        相关资源
        最近更新 更多