Python 关于ODR曲线拟合的几个问题

Python 关于ODR曲线拟合的几个问题,python,scipy,curve-fitting,Python,Scipy,Curve Fitting,我试图找出描述观测数据集的8个特征之间的相关性。我选择使用SciPy的正交距离回归实现,因为它可以处理两个变量中的错误。问题在于,并非所有这些特征都有与其值相关的误差,除极少数组合外,没有理论依据预测这些特征如何或是否相关。发现后一种信息实际上是我研究的一个关键点。我遇到了一些问题,我需要知道问题是与我的实现有关,还是存在更深层次的问题 首先,我将发布我的实现中的一些代码,以便我可以引用它。这不是一个最低限度的工作示例;这可能是我创建的最复杂的代码,我不知道如何将其精简为合理的代码,但它应该能让

我试图找出描述观测数据集的8个特征之间的相关性。我选择使用SciPy的正交距离回归实现,因为它可以处理两个变量中的错误。问题在于,并非所有这些特征都有与其值相关的误差,除极少数组合外,没有理论依据预测这些特征如何或是否相关。发现后一种信息实际上是我研究的一个关键点。我遇到了一些问题,我需要知道问题是与我的实现有关,还是存在更深层次的问题

首先,我将发布我的实现中的一些代码,以便我可以引用它。这不是一个最低限度的工作示例;这可能是我创建的最复杂的代码,我不知道如何将其精简为合理的代码,但它应该能让您了解我是如何实现ODR的

import numpy as np
import matplotlib.pyplot as plt
from scipy.odr import ODR, Model, Data, RealData
%matplotlib notebook

# Define a linear function to fit.
def linear_func(C, x):
    return C[0] * x + C[1]

# Now we need to determine the actual correlations.  Loop over the combinations and find the functional form of the
# correlation.
for keys in key_list:

    ### SORT DATA ###

    # Create an array to hold the data for this combination of characteristics.
    data_array = np.ones((n_rows, 4))

    # Determine the first columns for both characteristics.
    a = first_column_dict[keys[0]]
    b = first_column_dict[keys[1]]

    # Put the raw data for the two characteristics into their proper place.
    data_array[:, 0] = sample_data[:, a]
    data_array[:, 2] = sample_data[:, b]

    # Now fill in the weights (if such exist).  We will need to find an "average" error if there are unequal errors.
    # Start with the first characteristic.
    if (keys[0] in one_error_list) == True:
        data_array[:, 1] = sample_data[:, a + 1]
    elif (keys[0] in two_error_list) == True:
        data_array[:, 1] = (sample_data[:, a + 1] + sample_data[:, a + 2]) / 2

    # Now do the same with the second characteristic.
    if (keys[1] in one_error_list) == True:
        data_array[:, 3] = sample_data[:, b + 1]
    elif (keys[1] in two_error_list) == True:
        data_array[:, 3] = (sample_data[:, b + 1] + sample_data[:, b + 2]) / 2

    # Define a mask to remove rows with values of NaN.
    mask = ~np.isnan(data_array[:, 0]) & ~np.isnan(data_array[:, 2])

    ### DETERMINE CORRELATIONS ###

    # Define the data being fit.
    data = RealData(data_array[mask][:, 0], data_array[mask][:, 2], sx=data_array[mask][:, 1], sy=data_array[mask][:, 3])

    # Define the model being fit.
    model = Model(linear_func)

    # Define the ODR that will be used to fit the data.
    odr_obj = ODR(data, model, beta0=[1, 0])
    odr_obj.set_job(fit_type=0, deriv=0)

    # Run the model.
    fit = odr_obj.run()
我只是想找到我已经确定(使用斯皮尔曼的秩相关系数)具有相关性的特征对的拟合方程。有时候,ODR发现的契合有时明显是荒谬的,这取决于我如何设置代码来运行ODR。一个示例是一对特征,其中x轴变量具有与其相关的错误,而y轴变量没有。我输入已知的x变量错误,并将y变量的值设置为1;根据文档,这应该将y变量的权重设置为1,并且考虑到x变量中的错误,x变量的权重非常小。我怀疑这可能是问题的原因,但我不知道如何解决它。下面是我刚才描述的拟合数据图:

这显然没有道理;这件衣服一点也不合适。但是,如果我将两个轴上的所有权重设置为1,我将获得以下相关图:

这是一个更好的匹配,但它忽略了错误,这是我当初选择ODR的原因之一!如果我在set_job命令中将fit_type设置为2,强制程序执行普通的最小二乘拟合,我会得到与第二个相似的外观不同的拟合:

这看起来还是很合适,但我不知道它是否比我的第二个结果更好或更准确。我更信任哪一个?更糟糕的是,在消除误差时,并非所有特征都遵循这种精度提高的趋势。只有当我像第一个例子中那样完全包含错误时,一些拟合才有意义。并不是所有的特征都是线性相关的,因为有些特征显然是对数相关的


关于这一点,我有两个问题。我是否应该使用ODR,或者在尝试确定这些相关性时是否有更合适的例程?我定义错误的实现是否正确,特别是在其中一个特征没有相关错误的情况下?

我正在努力理解您真正想要的是什么。是不是更像?在这种情况下,我不会使用ODR。这是我想要确定这些特征是否相关的一部分。我已经这样做了,没有任何问题。另一部分是,如果我发现特征与前一步相关,则确定它们是如何相关的。这就是我的问题所在,也是这个问题所涉及的。我试图找到一种关系的数学形式,它提供了比仅仅知道有关系更多的信息。好吧,很公平。我想,在这种情况下,你还需要检查拟合度的好坏?我可以想象,如果你的数据是如此嘈杂,你必须决定,例如,线性函数是否足够,或者是否有理由添加一个额外的参数并使其二次。因此,如果你只有y误差,标准拟合是可以的。如果只是x错误,您只需交换数据。在这两种情况下,ODR都可以。但是Python ODR存在一些问题;例如,在我的评论中,有一个链接是手工制作的ODR版本。也许这对你有用。