1

我想知道是否有一种方法可以在多项式拟合中排除一个或多个数据区域。目前这似乎不像我预期的那样工作。这里有一个小例子:

import numpy as np
import pandas as pd
import zfit

# Create test data
left_data = np.random.uniform(0, 3, size=1000).tolist()
mid_data = np.random.uniform(3, 6, size=5000).tolist()
right_data = np.random.uniform(6, 9, size=1000).tolist()
testsample = pd.DataFrame(left_data + mid_data + right_data, columns=["x"])

# Define fit parameter
coeff1 = zfit.Parameter('coeff1', 0.1, -3, 3)
coeff2 = zfit.Parameter('coeff2', 0.1, -3, 3)

# Define Space for the fit
obs_all = zfit.Space("x", limits=(0, 9))

# Perform the fit
bkg_fit = zfit.pdf.Chebyshev(obs=obs_all, coeffs=[coeff1, coeff2], coeff0=1)
new_testsample = zfit.Data.from_pandas(obs=obs_all, df=testsample.query("x<3 or x>6"), weights=None)
nll = zfit.loss.UnbinnedNLL(model=bkg_fit, data=new_testsample)
minimizer = zfit.minimize.Minuit()
result = minimizer.minimize(nll)

测试样例.png

在这里,我创建了一个包含 3 个均匀分布数据的小型测试样本。我只想使用 x < 3 OR x > 6 中的数据并忽略其间的“峰值”。由于它们的形状和高度相同,我希望 coeff1 和 coeff2 将(几乎)为零,并且拟合曲线将是一条直线,水平线。显然这不会发生,因为 zfit 假设 3 到 6 之间没有条目。

我还尝试使用 MultiSpaces 通过忽略该区域

limit1 = zfit.Space("x", limits=(0, 3))
limit2 = zfit.Space("x", limits=(6, 9))
obs_data = limit1 + limit2

但这会导致

ValueError: obs need to be a Space with exactly one limit if rescaling is requested.

任何人都知道如何解决这个问题?

提前谢谢^^

4

1 回答 1

0

确实,这是一个棘手的问题,但这可能只需要在 zfit 中进行一个小的更新。

您所做的是正确的:仅使用所需区域中的数据。然而,这还不是全部,因为有一个“标准化范围”:从概率上讲,这就像对某个区域的条件化,因为我们知道数据只能在特定区域中。因此,PDF 的规范化应该只在包含的(LOW 和 HIGH)区域上集成。

这通常可以通过两种方式完成:

使用多空间

像你一样使用多空间属性。这应该可以工作(尽管很可能不是将来要走的路),除了多项式函数中的一个怪癖:多项式定义为从-1到1。目前,数据只是简单地重新缩放,因此在 - 1 和 1(为此它应该使用 PDF 的“空格”属性)。目前,这需要一个简单的空间(原则上也可以允许,使用限制的最小值和最大值)。

同时配合

正如@jtlz2 的评论中提到的,您可以同时进行拟合。这没什么好担心的,它只是将可能性分成两部分。由于它是概率的乘积,我们可以在概念上将其拆分为两个乘积并相乘(或相加它们的对数)。

因此,您可以让 pdf 同时适合下部区域和上部区域。然而,这并没有解决规范化的问题:PDF 应该被规范化成什么?我们会遇到同样的问题。

解决方案一:不同的空间和范数

然而,空间和归一化范围并不相同。默认情况下,空格(通常称为“obs”)也用作默认归一化范围,但不是必需的。因此,您可以使用从最低点到最大点的一个空间作为 obs,然后使用您的多空间设置标准范围set_norm应该这样做,或者set_norm_range如果您使用的不是最新版本)。我认为,这应该可以解决问题。

解决方案 2:手动重新缩放

实际问题是它抱怨无法重新缩放到 -1 和 1。每个这样做的多项式也可以通过使用apply_scaling=False参数被告知不要这样做。这样,您有责任在 -1 和 1 内缩放数据(因为多项式未在外部定义)并且不应该有任何错误。

于 2022-01-13T11:06:59.993 回答