Python 如何在散点图中对点进行加权以获得拟合?

Python 如何在散点图中对点进行加权以获得拟合?,python,numpy,data-fitting,Python,Numpy,Data Fitting,因此,我在Python中的polyfit(numpy.polynomy.polynomy.polyfit)函数中查找了有关权重参数的信息,它似乎与与各个点相关的错误有关。() 然而,我试图做的与误差无关,而是权重。我有一个numpy阵列形式的图像,它显示了探测器中沉积的电荷量。我把图像转换成散点图,然后进行拟合。但我希望这种适合能给那些有更多电荷沉积的积分更多的权重,而给那些电荷更少的积分更少的权重。这就是权重参数的作用吗 下面是一个示例图像: 这是我的密码: def get_best_fit(

因此,我在Python中的polyfit(numpy.polynomy.polynomy.polyfit)函数中查找了有关权重参数的信息,它似乎与与各个点相关的错误有关。()

然而,我试图做的与误差无关,而是权重。我有一个numpy阵列形式的图像,它显示了探测器中沉积的电荷量。我把图像转换成散点图,然后进行拟合。但我希望这种适合能给那些有更多电荷沉积的积分更多的权重,而给那些电荷更少的积分更少的权重。这就是权重参数的作用吗

下面是一个示例图像: 这是我的密码:

def get_best_fit(image_array, fixedX, fixedY):
    weights = np.array(image_array)
    x = np.where(weights>0)[1]
    y = np.where(weights>0)[0]
    size = len(image_array) * len(image_array[0])
    y = np.zeros((len(image_array), len(image_array[0])))
    for i in range(len(np.where(weights>0)[0])):
        y[np.where(weights>0)[0][i]][np.where(weights>0)[1][i]] = np.where(weights>0)[0][i]
    y = y.reshape(size)
    x = np.array(range(len(image_array)) * len(image_array[0]))
    weights = weights.reshape((size))
    b, m = polyfit(x, y, 1, w=weights)
    angle = math.atan(m) * 180/math.pi
    return b, m, angle
让我向你解释一下代码:

第一行指定存储在称为权重的变量中的电荷。接下来的两行得到了电荷沉积大于0的点,因此有一些电荷沉积用于捕捉散点图的坐标。然后我得到整个图像的大小,稍后转换为一个一维数组进行打印。然后,我浏览图像并尝试获得电荷沉积点的坐标(记住电荷量存储在变量
权重中)。然后我重塑y坐标以获得一维数组,并从图像中获得所有对应y坐标的x坐标,然后将权重的形状也更改为一维


编辑:如果有一种方法可以使用
np.linalg.lstsq
函数来实现这一点,那将非常理想,因为我也在尝试通过绘图的顶点进行拟合。我可以重新定位绘图,使顶点为零,然后使用
np.linalg.lstsq
,但这不允许我使用权重

因此,我可能误解了这个问题,但我只是尝试将一条直线拟合到散点图,然后使用权重参数更改拟合以确定特定点的优先级。
我尝试了这一点,我希望它们的行为都是一样的,因为它们都在最小化平方误差(至少这是我的理解)。
然而,两者的配合却大不相同,见下文。我不太清楚该怎么办

代码 np.polyfit 无权重(或全部设置为1)

当第二个点的权重设置为12时,所有其他权重均为1

np.多项式.多项式.多元拟合 无重量

当第二个点的权重设置为12时,所有其他权重均为1

因此,np.polyfit的行为与我预期的一样,但是我不知道np.polymone.polyfit到底发生了什么,即使没有任何权重的拟合对我来说也没有任何意义。
但我认为np.polyfit能满足你的需求吗?更改权重参数显然会为权重较高的点赋予更多权重。

您可以使用。它允许您不适合截距(即,线穿过原点,或通过一些欺骗,通过您选择的点)。它还处理加权数据

e、 (大部分是从@Hiho的回答中无耻地偷来的)


你能看一下数据,大致了解一下绘图应该是什么样子吗?你的结果合理吗?我的结果看起来确实合理,但并非所有事件都合理。对于一些图像,它在拟合角度方面做得很好(如问题中所给出的),但对于其他图像,它却做得不好。作为一种技巧:如果电荷是离散的或大小相似,你可以在更多电荷分布的地方添加额外的点。再看看这个:你能提供一个可运行的示例,包括一些示例数据吗?@Hiho我使用的不是同一个数据文件,但数据的格式是相同的:。具体来说,我使用的是名为“test_10k.root”的文件,当你说“一些欺骗”时,你的意思是向我试图使拟合通过的顶点添加更多权重吗?不。你只需提前从所有数据中减去该点,然后再将其添加回来。例如,对于给定的拟合线性模型y=Ax,您可以将其更改为(y-y_0)=a(x-x_0):::y=Ax+(y_0-Ax_0)。其中(x_0,y_0)是您希望模型通过的点。正如我所说的,您需要从所有数据中减去该点,然后执行
fit_intercept=False
。。。。so
y=y-y_0;安装前的x=x-x_0
import numpy as np
import matplotlib.pyplot as plt

def func(p1, p2, x):
    return  p1 * x + p2

y = np.array([1.0, 3.3, 2.2, 4.25, 4.8, 5.1, 6.3, 7.5])
x = np.arange(y.shape[0])

plt.scatter(x, y)

w = np.ones(x.shape[0])
w[1] = 12
# p1, p2 = np.polyfit(x, y, 1, w=w)
p1, p2 = np.polynomial.polynomial.polyfit(x, y, 1, w=w)
print(p1, p2, w)

plt.plot(x, func(p1, p2, x))

plt.show()
import numpy as np
import matplotlib.pyplot as plt
import sklearn.linear_model

y = np.array([1.0, 3.3, 2.2, 4.25, 4.8, 5.1, 6.3, 7.5])
x = np.arange(y.shape[0]).reshape((-1,1))
w = np.linspace(1,5,y.shape[0])

model = sklearn.linear_model.LinearRegression(fit_intercept=False)
model.fit(x, y, sample_weight=w)

line_x = np.linspace(min(x), max(x), 100).reshape((-1,1))
pred = model.predict(line_x)

plt.scatter(x, y)
plt.plot(line_x, pred)

plt.show()