【发布时间】:2015-03-10 11:57:58
【问题描述】:
我已经为行星绕太阳运行时的 (x,y,z) 坐标生成了一堆数据。现在我想通过这些数据拟合一个椭圆。
我想做什么:
我根据五个参数创建了一个虚拟椭圆:定义尺寸和形状的半长轴和偏心率以及旋转椭圆的三个欧拉角。由于我的数据并不总是以原点为中心,因此我还需要翻译需要额外三个变量(dx、dy、dz)的椭圆。 一旦我用这八个变量初始化这个函数,我就会得到这个椭圆上的 N 个点。 (N = 我正在绘制椭圆的数据点数) 我计算这些虚拟点与实际数据的偏差,然后我使用 some 最小化方法最小化这个偏差,以找到这八个变量的最佳拟合值。
我的问题在于最后一部分:最小化偏差并找到变量的值。
为了最小化偏差,我使用 scipy.optimize.minimize 来尝试逼近最佳拟合变量,但它做得不够好:
Here is an image 我最适合的一个看起来像什么,这是一个非常准确的初始猜测。 (蓝色 = 数据,红色 = 拟合)
Here is the entire code.(不需要数据,它会生成自己的假数据)
简而言之,我使用这个 scipy 函数:
initial_guess = [0.3,0.2,0.1,0.7,3,0.0,-0.1,0.0]
bnds = ((0.2, 0.5), (0.1, 0.3), (0, 2*np.pi), (0, 2*np.pi), (0, 2*np.pi), (-0.5,0.5), (-0.5,0.5), (-0.3,0.3)) #reasonable bounds for the variables
result = optimize.minimize(deviation, initial_guess, args=(data,), method='L-BFGS-B', bounds=bnds, tol=1e-8) #perform minimalisation
semi_major,eccentricity,inclination,periapsis,longitude,dx,dy,dz = result["x"]
为了最小化这个误差(或偏差)函数:
def deviation(variables, data):
"""
This function calculates the cumulative seperation between the ellipse fit points and data points and returns it
"""
num_pts = len(data[:,0])
semi_major,eccentricity,inclination,periapsis,longitude,dx,dy,dz = variables
dummy_ellipse = generate_ellipse(num_pts,semi_major,eccentricity,inclination,periapsis,longitude,dz,dy,dz)
deviations = np.zeros(len(data[:,0]))
pair_deviations = np.zeros(len(data[:,0]))
# Calculate separation between each pair of points
for j in range(len(data[:,0])):
for i in range(len(data[:,0])):
pair_deviations[i] = np.sqrt((data[j,0]-dummy_ellipse[i,0])**2 + (data[j,1]-dummy_ellipse[i,1])**2 + (data[j,2]-dummy_ellipse[i,2])**2)
deviations[j] = min(pair_deviations) # only pick the closest point to the data point j.
total_deviation = sum(deviations)
return total_deviation
(我的代码可能有点混乱且效率低下,我是新手)
我可能在我的编码中犯了一些逻辑错误,但我认为它归结为 scipy.minimize.optimize 函数。我不太了解它的工作原理以及对它的期望。在处理这么多变量时,还建议我尝试马尔可夫链蒙特卡罗。我确实看过emcee,但现在有点过头了。
【问题讨论】:
-
免责声明:我尚未通读您的所有代码。 真的有多糟糕?仅仅因为它看起来有点不对劲并不一定表明它非常不合适。当我运行您的代码时,所有拟合参数最多正确为 +-0.05(倾角),其余参数甚至更“精确”,约为 +-0.02。创建一种管道,您一次只适合几个参数有助于提高精度吗? (即假设所有角度都为零并且仅适合
e和a,然后根据原始数据取该椭圆并拟合角度,可能使用不同的方法等) -
只是一个观察:由于您的数据可能位于一个平面上,因此最好在拟合之前在该平面上定义椭圆,而不是尝试拟合欧拉角。
-
帖子中的链接已损坏,因此问题/答案中的代码不足以重新创建示例...
标签: python scipy ellipse astronomy minimization