python - 正确实现 scipy.optimize 以求解平面方程的所有参数
问题描述
一个三维平面方程定义为:
a * x + b * y + c * z + d = 0
其中 x、y 和 z 是数据点的坐标,a、b、c 和 d 定义平面参数。我有一堆 x,y,z 数据点,我知道它们大致形成了一个平面。现在我想将这些数据点拟合到一个平面上并找到 a、b、c、d 参数。到目前为止我有这个功能:
import scipy.optimize as op
def _plane(ws,x,y,z):
cost = np.sum(ws[0]*x + ws[1]*y + ws[2]*z + ws[3])
print cost, np.sum(ws)
return cost
out = op.minimize(_plane,ws,args=(x,y,z),method='SLSQP',options={'maxiter':1000, 'disp':1})
ws = plane([np.mean(x),np.mean(y),np.mean(z),0.001],x,y,z)
输出:
130.78467 -0.3011288588643074
130.78467 -0.3011288588643074
130.78467 -0.3011288439631462
130.78467 -0.3011288439631462
130.78468 -0.3011288439631462
130.78467 -0.3011288439631462
-119765.375 -1024.3011288588643
-119765.375 -1024.3011288588643
-119765.375 -1024.3011288439632
-119765.375 -1024.3011288439632
-119765.375 -1024.3011288439632
-119765.375 -1024.3011288439632
Optimization terminated successfully. (Exit mode 0)
Current function value: -119765.375
Iterations: 2
Function evaluations: 12
Gradient evaluations: 2
out: fun: -119765.375
jac: array([0., 0., 0., 0.])
message: 'Optimization terminated successfully.'
nfev: 12
nit: 2
njev: 2
status: 0
success: True
x: array([-4.07030255e-01, -8.12448636e-02, -1.02381385e+03, 1.00000000e-03])
正如你所看到cost
的,它总是在减少,d
无论我最初给出什么,它的值都不会改变。这个实现正确吗?
更新:
使用cost = abs(np.sum(ws[0]*x + ws[1]*y + ws[2]*z + ws[3]))
可解决优化问题,设置method='cg'
可提供最佳结果。
解决方案
对于将平面调整为一组点的具体问题,可以使用更简单的方法:
>>> import numpy as np
>>> points = np.array([(3,0,0), (0,4,0), (3,0,1),
... (0,4,1), (6,-4,0), (6,-4,1)])
计算质心并从每个点中减去它。
>>> centroid = np.average(points, axis=0)
>>> centered = points - centroid
计算中心点数组的单值分解。第三个奇异值对应的向量垂直于平面,范数为1,所以可以直接用它作为平面的a,b,c系数。
>>> _, _, vh = np.linalg.svd(centered)
>>> a, b, c = normal = vh[2]
质心必须位于平面上,因此可以从法线向量和质心计算出最后一个系数 (d)。
>>> d = -normal @ centroid
>>> plane_coefficients = a, b, c, d
>>> print(plane_coefficients)
(0.8, 0.6, 0.0, -2.4000000000000004)
推荐阅读
- java - 将 SQL 数据添加到默认的 JPARepostiroty 方法
- python - 使用 PrismJS 在 Django 中突出显示语法
- javascript - Discord.js 机器人试图在语音通道上播放 mp3 文件 - 没有错误,也没有声音
- javascript - Express Electron 不能需要本地 Js 文件
- json - 我们如何在 Flutter 中从 JSON 对象中获取特定数据?
- html - 如何防止仅绝对定位的元素发送链接?
- tomcat - 使用 SSL 登录 GeoServer 的问题
- python - 聚合熊猫数据框但折叠重复的单元格值
- c# - .NET5 连接的 Wsdl 服务未按预期填充响应
- javascript - 如何在 angular-flot 条上添加 onclick 功能