J'ai des points de données d'entrée (x, y, z), tous positifs, et je dois les adapter à une surface. Plus précisément, je dois créer une grille à partir des points de données x et y et évaluer les points de données sur cette grille pour obtenir une surface de valeurs z à tracer.
Comment puis-je effectuer une troisième régression polynomiale ou plus pour ajuster une surface à mes points de données?
Le degré de la régression polynomiale doit de préférence être une valeur d'entrée.
3 Réponses :
Ce serait formidable si vous pouviez nous montrer votre tentative. Je suis sûr qu'il existe de nombreuses façons de le faire, mais voici deux premiers conseils:
Votre polynôme 2D (de degré arbitraire) peut être défini en utilisant polyval2d
de la bibliothèque numpy.
Vous pouvez ensuite adapter cette fonction (par exemple, en utilisant la méthode des moindres carrés) avec la bibliothèque scipy: scipy.optimize
.
Voici un ajusteur de surface 3D non linéaire avec nuage de points 3D, tracé de surface 3D et tracé de contour. Il doit s'agir de tous les graphiques.
import numpy, scipy, scipy.optimize import matplotlib from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm # to colormap 3D surfaces from blue to red import matplotlib.pyplot as plt graphWidth = 800 # units are pixels graphHeight = 600 # units are pixels # 3D contour plot lines numberOfContourLines = 16 def SurfacePlot(func, data, fittedParameters): f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100) matplotlib.pyplot.grid(True) axes = Axes3D(f) x_data = data[0] y_data = data[1] z_data = data[2] xModel = numpy.linspace(min(x_data), max(x_data), 20) yModel = numpy.linspace(min(y_data), max(y_data), 20) X, Y = numpy.meshgrid(xModel, yModel) Z = func(numpy.array([X, Y]), *fittedParameters) axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True) axes.scatter(x_data, y_data, z_data) # show data along with plotted surface axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot axes.set_xlabel('X Data') # X axis data label axes.set_ylabel('Y Data') # Y axis data label axes.set_zlabel('Z Data') # Z axis data label plt.show() plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems def ContourPlot(func, data, fittedParameters): f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100) axes = f.add_subplot(111) x_data = data[0] y_data = data[1] z_data = data[2] xModel = numpy.linspace(min(x_data), max(x_data), 20) yModel = numpy.linspace(min(y_data), max(y_data), 20) X, Y = numpy.meshgrid(xModel, yModel) Z = func(numpy.array([X, Y]), *fittedParameters) axes.plot(x_data, y_data, 'o') axes.set_title('Contour Plot') # add a title for contour plot axes.set_xlabel('X Data') # X axis data label axes.set_ylabel('Y Data') # Y axis data label CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k') matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours plt.show() plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems def ScatterPlot(data): f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100) matplotlib.pyplot.grid(True) axes = Axes3D(f) x_data = data[0] y_data = data[1] z_data = data[2] axes.scatter(x_data, y_data, z_data) axes.set_title('Scatter Plot (click-drag with mouse)') axes.set_xlabel('X Data') axes.set_ylabel('Y Data') axes.set_zlabel('Z Data') plt.show() plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems def func(data, a, alpha, beta): t = data[0] p_p = data[1] return a * (t**alpha) * (p_p**beta) if __name__ == "__main__": xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0]) zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9]) data = [xData, yData, zData] initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example # here a non-linear surface fit is made with scipy's curve_fit() fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters) ScatterPlot(data) SurfacePlot(func, data, fittedParameters) ContourPlot(func, data, fittedParameters) print('fitted prameters', fittedParameters) modelPredictions = func(data, *fittedParameters) absError = modelPredictions - zData SE = numpy.square(absError) # squared errors MSE = numpy.mean(SE) # mean squared errors RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData)) print('RMSE:', RMSE) print('R-squared:', Rsquared)
Cordialement François