计算两个叠加的高斯函数的质心

时间:2018-10-16 02:32:29

标签: statistics curve-fitting normal-distribution data-fitting centroid

我正在尝试找到以下问题的解决方案。我有一组点,它们应该模拟以不同点为中心的2个高斯函数的总和。我需要找到这两点。到目前为止,我的方法是找到整个集合的质心,并在其上下切割日期集合。然后,我计算出每个零件的质心,这些质心就是我的中心。但是,这种方法会切掉泄漏到数据右半部分的左高斯信息。当高斯人靠近时,这会使该过程失败。有办法更智能地做到这一点吗?由于计算困难,如果解决方案不涉及曲线拟合,我会更愿意。

1 个答案:

答案 0 :(得分:0)

由于OP不显示任何数据,因此尚不清楚数据有多嘈杂。此外,尚不清楚此处如何定义“紧密结合”。在下面的内容中,我有一个简单的近似值,可以在低噪声下工作,并且假设左侧数据由左高斯控制,而右侧数据由右高斯控制。这样会限制位置,高度,尤其是标准偏差。

它肯定适用于单个峰,但对于混合双峰(在上述限制内)完全可以。

#!/usr/bin/python
import matplotlib.pyplot as plt
import numpy as np

def gaussian( x, x0, s, a):
    return a * np.exp( -( x - x0 )**2 / ( 2 * s**2 ) ) / np.sqrt( 2 * np.pi * s**2 )

def get_x0( x1, x2, x3, y1, y2, y3 ):
    l12= np.log( y1 / y2 )
    l13= np.log( y1 / y3 )
    return ( ( x2 + x1 )/2. - ( x3 + x1 )/2. * l12/l13 * ( x3 - x1 ) / ( x2 - x1 ) ) / ( 1 - l12 / l13 * (x3 - x1 ) / ( x2 - x1 ) )


fig = plt.figure( )
ax = fig.add_subplot( 2, 1, 1 )

xL = np.linspace(-8, 8, 150 )
yL = np.fromiter( ( gaussian( x,-2.1, 1.2, 8 ) for x in xL ), np.float )
marker=[10,15,20]

x1 = xL[ marker[0] ]
x2 = xL[ marker[1] ]
x3 = xL[ marker[2] ]
y1 = yL[ marker[0] ]
y2 = yL[ marker[1] ]
y3 = yL[ marker[2] ]

print get_x0( x1, x2, x3, y1, y2, y3 )

ax.plot( xL, yL )
ax.scatter( [ x1, x2, x3 ],[ y1, y2, y3 ])

bx = fig.add_subplot( 2, 1, 2 )
yL = np.fromiter( ( gaussian( x,-2.1, 1.2, 8) + gaussian( x,0.7, 1.4, 6 ) for x in xL ), np.float )
marker=[10,15,20]
x1 = xL[ marker[0] ]
x2 = xL[ marker[1] ]
x3 = xL[ marker[2] ]
y1 = yL[ marker[0] ]
y2 = yL[ marker[1] ]
y3 = yL[ marker[2] ]
bx.scatter( [ x1, x2, x3 ],[ y1, y2, y3 ])
print get_x0( x1, x2, x3, y1, y2, y3 )
marker=[-20,-25,-30]
x1 = xL[ marker[0] ]
x2 = xL[ marker[1] ]
x3 = xL[ marker[2] ]
y1 = yL[ marker[0] ]
y2 = yL[ marker[1] ]
y3 = yL[ marker[2] ]
bx.scatter( [ x1, x2, x3 ],[ y1, y2, y3 ])
print get_x0( x1, x2, x3, y1, y2, y3 )
bx.plot( xL, yL )

plt.show() 

显示:

#Single
-2.0999999999999455
#Double
-2.0951188129317813
0.6998760921436634

非常接近-2.10.7

gaussians

如果出现噪音,可能需要一些平均值。