简体   繁体   English

使用 Python 拟合 3D 多项式曲面

[英]Fit 3D Polynomial Surface with Python

I have a python code that calculates z values dependent on x and y values.我有一个 python 代码,它计算依赖于 x 和 y 值的 z 值。 Overall, I have 7 x-values and 7 y-values as well as 49 z-values that are arranged in a grid (x and y correspond each to one axis, z is the height).总的来说,我有 7 个 x 值和 7 个 y 值以及 49 个 z 值,它们排列在一个网格中(x 和 y 分别对应一个轴,z 是高度)。

Now, I would like to fit a polynomial surface of degree 2 in the form of z = f(x,y) .现在,我想以z = f(x,y)的形式拟合 2 次多项式曲面。

I found a Matlab command that does this calculation.我找到了一个执行此计算的 Matlab 命令。 ( https://www.mathworks.com/help/curvefit/fit.html ) ( https://www.mathworks.com/help/curvefit/fit.html )

load franke
sf = fit([x, y],z,'poly23')
plot(sf,[x,y],z)

I want to calculate the parameters of my 2 degree function in Python.我想用 Python 计算我的 2 度函数的参数。 I tried to use the scipy curve_fit function with the following fit function:我尝试使用具有以下拟合函数的 scipy curve_fit函数:

def func(a, b, c, d ,e ,f ,g ,h ,i ,j, x, y):
    return a + b * x**0 * y**0 + c * x**0 * y**1 + d * x**0 * y**2 
             + e * x**1 * y**0 + f * x**1 * y**1 + g * x**1 * y**2
             + h * x**2 * y**0 + i * x**2 * y**1 + j * x**2 * y**2
    
guess = (1,1,1,1,1,1,1,1,1,1)
params, pcov = optimize.curve_fit(func, x, y, guess)

But at this point I am getting confused and I am not sure, if this is the right approach to get the parameters for my fit function.但此时我感到困惑,我不确定这是否是获取适合函数参数的正确方法。 Is there possibly another solution for this problem?这个问题可能有另一种解决方案吗? Thank's a lot!非常感谢!

Now, two years later, I am able to solve the problem.现在,两年后,我能够解决这个问题。 It is a classical linear regression problem with polynomial features, where the input variables are arranged in a mesh.这是一个具有多项式特征的经典线性回归问题,其中输入变量排列在网格中。 In the code below, I calculated the polynomial features I need, respectively that ones, that will explain my target variable.在下面的代码中,我分别计算了我需要的多项式特征,这些特征将解释我的目标变量。

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

np.random.seed(0)
# set dimension of the data
dim = 12
# create random data, which will be the target values
Z = (np.ones((dim,dim)) * np.arange(1,dim+1,1))**3 + np.random.rand(dim,dim) * 200 

# create a 2D-mesh
x = np.arange(1,dim+1).reshape(dim,1)
y = np.arange(1,dim+1).reshape(1,dim)
X,Y = np.meshgrid(x,y)

# calculate polynomial features based on the input mesh
features = {}
features['x^0*y^0'] = np.matmul(x**0,y**0).flatten()
features['x*y'] = np.matmul(x,y).flatten()
features['x*y^2'] = np.matmul(x,y**2).flatten()
features['x^2*y^0'] = np.matmul(x**2, y**0).flatten()
features['x^2*y'] = np.matmul(x**2, y).flatten()
features['x^3*y^2'] = np.matmul(x**3, y**2).flatten()
features['x^3*y'] = np.matmul(x**3, y).flatten()
features['x^0*y^3'] = np.matmul(x**0, y**3).flatten()
dataset = pd.DataFrame(features)

# fit a linear regression model
reg = LinearRegression().fit(dataset.values, Z.flatten())
# get coefficients and calculate the predictions 
z_pred = reg.intercept_ + np.matmul(dataset.values, reg.coef_.reshape(-1,1)).reshape(dim,dim)

# visualize the results
fig = plt.figure(figsize = (5,5))
ax = Axes3D(fig)
# plot the fitted curve
ax.plot_wireframe(X, Y, z_pred, label = 'prediction')
# plot the target values
ax.scatter(X, Y, Z, c = 'r', label = 'datapoints')
ax.view_init(25, 80)
plt.legend()

输入变量和预测表面的 3D 图

I wrote a Python tkinter GUI application that does exactly this, it draws the surface plot with matplotlib and can save fitting results and graphs to PDF.我编写了一个 Python tkinter GUI 应用程序,它正是这样做的,它使用 matplotlib 绘制曲面图,并且可以将拟合结果和图形保存为 PDF。 The code is on github at:代码在 github 上:

https://github.com/zunzun/tkInterFit/ https://github.com/zunzun/tkInterFit/

Try the 3D Polynomial "Full Quadratic" as it is the same equation shown in your question.尝试 3D 多项式“全二次”,因为它与您的问题中显示的方程相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM