numpy 拟合回归曲面的3D图

gcmastyq  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(81)

我正在尝试制作一个3D图形来绘制拟合回归曲面。我看过以下例子。
Plot linear model in 3d with Matplotlib
Combining scatter plot with surface plot
Best fit surfaces for 3 dimensional data
然而,第一个非常过时,不再工作,第二个是相关的,但我有一些麻烦来生成Z的值。我能找到的所有例子要么是过时的,要么是低级的模拟数据例子。问题可能比Z多。请看下面的代码。

import numpy as np
import seaborn as sns
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d

df = sns.load_dataset('mpg')
df.dropna(inplace=True)

model = smf.ols(formula='mpg ~ horsepower + acceleration', data=df)
results = model.fit()

x, y = model.exog_names[1:]

x_range = np.arange(df[x].min(), df[x].max())
y_range = np.arange(df[y].min(), df[y].max())

X, Y = np.meshgrid(x_range, y_range)
# Z = results.fittedvalues.values.reshape()

fig = plt.figure(figsize=plt.figaspect(1)*3)
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha = 0.2)

更新:

我把Z改成了下面的是对的

Z = results.params[0] + X*results.params[1] + Y*results.params[2]

并追加

ax.scatter(df[x], df[y], df[model.endog_names], s=50)
ax.view_init(20, 120)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

我得到了下面的情节,但我不确定它是否正确。

如果可能,我还想为绘制的曲面添加投影。

wixjitnu

wixjitnu1#

在你的答案中,关键的一步是通过提供“外生”数据将模型应用于整个网格。在这种情况下,你可以通过创建一个新的包含展开的网格网格的框架并将其作为exog传递给statsmodels.regression.linear_model.OLS.predict来轻松完成。用你的例子来演示一下:

import numpy as np
import seaborn as sns
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d

df = sns.load_dataset('mpg')
df.dropna(inplace=True)

model = smf.ols(formula='mpg ~ horsepower + acceleration', data=df)
results = model.fit()

x, y = model.exog_names[1:]

x_range = np.arange(df[x].min(), df[x].max())
y_range = np.arange(df[y].min(), df[y].max())

X, Y = np.meshgrid(x_range, y_range)

exog = pd.DataFrame({x: X.ravel(), y: Y.ravel()})
Z = results.predict(exog = exog).values.reshape(X.shape)

fig = plt.figure(figsize=plt.figaspect(1)*2)
ax = plt.axes(projection='3d')
ax.scatter(df[x].values, df[y].values, results.fittedvalues.values, 
           marker='.', label="Fits")
cond = df[model.endog_names].values > results.fittedvalues.values
ax.scatter(df[x][cond].values, df[y][cond].values, df[model.endog_names]
           [cond].values, label="Raw")
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha = 0.4)
ax.scatter(df[x][cond == False].values, df[y][cond == False].values,
           df[model.endog_names][cond == False].values)
ax.legend()
plt.show()

它会给你给予

除了数据点之外,我还在散点图中包括了各个拟合点,以表明这种方法正确地生成了相应的表面。我还将数据分为两组:那些应该在表面的前面绘制的,那些应该在表面的后面绘制的。这是为了适应matplotlib在3D渲染中对艺术家的分层。查看几何体已从默认值更改,以最大限度地提高3D属性的清晰度。

编辑

将回归曲面的投影添加到其中一个轴平面上是相当简单的-您只需将一维设置为轴极限,即

ax.plot_surface(X, Y, np.full_like(X, ax.get_zlim()[0]), alpha = 0.2)

这样你就可以

相关问题