[英]Fitting 3D data points to polynomial surface and getting the surface equation back
我是 Python 3D 擬合和相關優化技術的新手。 我試圖了解類似的主題並根據最小二乘法找到答案,但我的成功相當有限。
問題:我有一些(大約 400 個)3D 點存儲在 np 數組中。
data = np.array([[x1, y1, z1], [x2, y2, z2], [x3, y3, z3], [x4, y4, z4], ... ])
我想將多項式曲面(2 階或 3 階)擬合到這些點,然后獲取曲面方程的參數,因此我可以計算任何給定 (x, y) 值對的 z。 例如:
z = (A * x ** 2) + (B * y ** 2) + (C * x * y) + (D * x) + (E * y) + F
我需要得到一個 output,其中包含 A、B、C、D、E 和 F 參數。 有沒有一種很好的“Pythonic”方式來做到這一點?
curve_fit
接受自變量的多維數組,但您的 function 必須接受相同的:
import numpy as np
from scipy.optimize import curve_fit
data = np.array(
[[0, 0, 1],
[1, 1, 2],
[2, 1, 3],
[3, 0, 5],
[4, 0, 2],
[5, 1, 3],
[6, 0, 7]]
)
def func(X, A, B, C, D, E, F):
# unpacking the multi-dim. array column-wise, that's why the transpose
x, y, z = X.T
return (A * x ** 2) + (B * y ** 2) + (C * x * y) + (D * x) + (E * y) + F
popt, _ = curve_fit(func, data, data[:,2])
from string import ascii_uppercase
for i, j in zip(popt, ascii_uppercase):
print(f"{j} = {i:.3f}")
# A = 0.060
# B = 2004.446
# C = -0.700
# D = 0.521
# E = -2003.046
# F = 1.148
請注意,通常您應該為參數提供初始猜測以實現良好的擬合結果。
如果您允許 sklearn 依賴,您可以將sklearn.preprocessing.PolynomialFeatures與sklearn.linear_model.LinearRegression一起使用:
import numpy as np
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
np.random.seed(0)
# Generate fake data
n,m = 400, 3
data = np.random.randn(n,m)
# Generate polynomial features of desired degree
d = 3
poly = PolynomialFeatures(degree=d, include_bias=False)
X = poly.fit_transform(data[:, :-1]) # X.shape = (400, 9)
y = data[:,-1] # y.shape = (400,)
# Define and fit linear regression
clf = LinearRegression()
clf.fit(X, y)
# Check results
print(clf.coef_)
[-0.01437971 0.09894586 0.01936384 0.17245758 0.05518938
0.0239589 -0.09930492 -0.04593238 -0.01588326]
print(clf.intercept_)
-0.12456419670821159
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.