3D-график для подогнанной регрессионной поверхности с помощью matplotlib - PullRequest
0 голосов
/ 27 января 2020

Я пытаюсь создать трехмерный график для построения подгонки поверхности регрессии. Я видел следующие примеры.

График линейной модели в 3d с Matplotlib

Объединение точечного графика с поверхностным графиком

Подходящие поверхности для трехмерных данных

Тем не менее, первая сильно устарела и больше не работает, а вторая связана, но у меня возникли некоторые проблемы с генерацией значений для 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')

Я получил следующий график, но я не уверен, что он прав.

enter image description here

Если возможно, я также хотел бы добавить проекции для построенной поверхности.

1 Ответ

1 голос
/ 27 января 2020

В ответе, который вы связали, критическим шагом является применение модели ко всей сетке сетки путем предоставления «экзогенных» данных. В этом случае вы можете легко это сделать, создав новый фрейм данных, содержащий развернутую сетку, и передав его как 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()

Что даст вам

enter image description here

Я включил отдельные точки соответствия в график рассеяния в дополнение к точкам данных, чтобы указать, что этот подход правильно генерирует соответствующую поверхность. Я также отфильтровал данные в две группы: те, которые должны быть нанесены перед поверхности, и те, которые должны быть нанесены позади поверхности. Это сделано для того, чтобы совместить слои matplotlib с художниками в 3D-рендеринге. Геометрия просмотра была изменена по умолчанию в попытке максимизировать четкость 3D-свойств.


Редактировать

Добавление проекции поверхности регрессии на одну из плоскостей осей довольно тривиально - вы просто наносите на график данные с одним измерением, установленным на предел оси, то есть

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

, который затем дает вам

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...