Source code for autogluon.eda.visualization.model
from typing import Any, Dict, Optional
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from autogluon.core.constants import REGRESSION
from ..state import AnalysisState
from .base import AbstractVisualization
from .jupyter import JupyterMixin
__all__ = ["ConfusionMatrix", "FeatureImportance", "RegressionEvaluation", "ModelLeaderboard"]
[docs]class ConfusionMatrix(AbstractVisualization, JupyterMixin):
"""
Render confusion matrix for binary/multiclass classificator.
This visualization depends on :py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator` analysis.
Parameters
----------
headers: bool, default = False
if `True` then render headers
namespace: str, default = None
namespace to use; can be nested like `ns_a.ns_b.ns_c`
fig_args: Optional[Dict[str, Any]] = None,
kwargs to pass into chart figure
Examples
--------
>>> import autogluon.eda.analysis as eda
>>> import autogluon.eda.visualization as viz
>>> import autogluon.eda.auto as auto
>>>
>>> df_train = ...
>>> df_test = ...
>>> predictor = ...
>>>
>>> auto.analyze(model=predictor, val_data=df_test, anlz_facets=[
>>> eda.model.AutoGluonModelEvaluator(),
>>> ], viz_facets=[
>>> viz.model.ConfusionMatrix(fig_args=dict(figsize=(3,3)), annot_kws={"size": 12}),
>>> ])
See Also
--------
:py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator`
"""
def __init__(
self,
fig_args: Optional[Dict[str, Any]] = None,
headers: bool = False,
namespace: Optional[str] = None,
**kwargs,
) -> None:
super().__init__(namespace, **kwargs)
self.headers = headers
if fig_args is None:
fig_args = {}
self.fig_args = fig_args
def can_handle(self, state: AnalysisState) -> bool:
return "model_evaluation" in state and "confusion_matrix" in state.model_evaluation
def _render(self, state: AnalysisState) -> None:
self.render_header_if_needed(state, "Confusion Matrix")
labels = state.model_evaluation.labels
cm = pd.DataFrame(state.model_evaluation.confusion_matrix, columns=labels, index=labels)
cm.index.name = "Actual"
cm.columns.name = "Predicted"
normalized = state.model_evaluation.confusion_matrix_normalized
fmt = ",.2%" if normalized else "d"
cells_num = len(cm)
fig_args = self.fig_args.copy()
if "figsize" not in fig_args:
fig_args["figsize"] = (cells_num, cells_num)
fig, ax = plt.subplots(**fig_args)
sns.heatmap(
cm,
ax=ax,
cmap="Blues",
annot=True,
linewidths=0.5,
linecolor="lightgrey",
fmt=fmt,
cbar=False,
**self._kwargs,
)
plt.show(fig)
[docs]class RegressionEvaluation(AbstractVisualization, JupyterMixin):
"""
Render predictions vs ground truth chart for regressor.
This visualization depends on :py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator` analysis.
Parameters
----------
headers: bool, default = False
if `True` then render headers
namespace: str, default = None
namespace to use; can be nested like `ns_a.ns_b.ns_c`
fig_args: Optional[Dict[str, Any]] = None,
kwargs to pass into chart figure
Examples
--------
>>> import autogluon.eda.analysis as eda
>>> import autogluon.eda.visualization as viz
>>> import autogluon.eda.auto as auto
>>>
>>> df_train = ...
>>> df_test = ...
>>> predictor = ...
>>>
>>> auto.analyze(model=predictor, val_data=df_test, anlz_facets=[
>>> eda.model.AutoGluonModelEvaluator(),
>>> ], viz_facets=[
>>> viz.model.RegressionEvaluation(fig_args=dict(figsize=(6,6)), marker='o', scatter_kws={'s':5}),
>>> ])
See Also
--------
:py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator`
"""
def __init__(
self,
fig_args: Optional[Dict[str, Any]] = None,
headers: bool = False,
namespace: Optional[str] = None,
**kwargs,
) -> None:
super().__init__(namespace, **kwargs)
self.headers = headers
if fig_args is None:
fig_args = {}
self.fig_args = fig_args
def can_handle(self, state: AnalysisState) -> bool:
return "model_evaluation" in state and state.model_evaluation.problem_type == REGRESSION
def _render(self, state: AnalysisState) -> None:
self.render_header_if_needed(state, "Prediction vs Target")
data = pd.DataFrame({"y_true": state.model_evaluation.y_true, "y_pred": state.model_evaluation.y_pred})
fig, ax = plt.subplots(**self.fig_args)
sns.regplot(ax=ax, data=data, x="y_true", y="y_pred", **self._kwargs)
plt.show(fig)
[docs]class FeatureImportance(AbstractVisualization, JupyterMixin):
"""
Render feature importance for the model.
This visualization depends on :py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator` analysis.
Parameters
----------
show_barplots: bool, default = False
render features barplots if True
headers: bool, default = False
if `True` then render headers
namespace: str, default = None
namespace to use; can be nested like `ns_a.ns_b.ns_c`
fig_args: Optional[Dict[str, Any]] = None,
kwargs to pass into chart figure
Examples
--------
>>> import autogluon.eda.analysis as eda
>>> import autogluon.eda.visualization as viz
>>> import autogluon.eda.auto as auto
>>>
>>> df_train = ...
>>> df_test = ...
>>> predictor = ...
>>>
>>> auto.analyze(model=predictor, val_data=df_test, anlz_facets=[
>>> eda.model.AutoGluonModelEvaluator(),
>>> ], viz_facets=[
>>> viz.model.FeatureImportance(show_barplots=True)
>>> ])
See Also
--------
:py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator`
"""
def __init__(
self,
show_barplots: bool = False,
fig_args: Optional[Dict[str, Any]] = None,
headers: bool = False,
namespace: Optional[str] = None,
**kwargs,
) -> None:
super().__init__(namespace, **kwargs)
self.headers = headers
if fig_args is None:
fig_args = {}
self.fig_args = fig_args
self.show_barplots = show_barplots
def can_handle(self, state: AnalysisState) -> bool:
return "model_evaluation" in state and "importance" in state.model_evaluation
def _render(self, state: AnalysisState) -> None:
self.render_header_if_needed(state, "Feature Importance")
importance = state.model_evaluation.importance
with pd.option_context("display.max_rows", 100 if len(importance) <= 100 else 20):
self.display_obj(importance)
if self.show_barplots:
fig_args = self.fig_args.copy()
if "figsize" not in fig_args:
fig_args["figsize"] = (12, len(importance) / 4)
fig, ax = plt.subplots(**fig_args)
sns.barplot(ax=ax, data=importance.reset_index(), y="index", x="importance", **self._kwargs)
plt.show(fig)
[docs]class ModelLeaderboard(AbstractVisualization, JupyterMixin):
"""
Render model leaderboard for trained model ensemble.
Parameters
----------
headers: bool, default = False
if `True` then render headers
namespace: str, default = None
namespace to use; can be nested like `ns_a.ns_b.ns_c`
Examples
--------
>>> import autogluon.eda.analysis as eda
>>> import autogluon.eda.visualization as viz
>>> import autogluon.eda.auto as auto
>>>
>>> df_train = ...
>>> df_test = ...
>>> predictor = ...
>>>
>>> auto.analyze(model=predictor, val_data=df_test, anlz_facets=[
>>> eda.model.AutoGluonModelEvaluator(),
>>> ], viz_facets=[
>>> viz.model.ModelLeaderboard(),
>>> ])
See Also
--------
:py:class:`~autogluon.eda.analysis.model.AutoGluonModelEvaluator`
"""
def __init__(self, namespace: Optional[str] = None, headers: bool = False, **kwargs) -> None:
super().__init__(namespace, **kwargs)
self.headers = headers
def can_handle(self, state: AnalysisState) -> bool:
return "model_evaluation" in state and "leaderboard" in state.model_evaluation
def _render(self, state: AnalysisState) -> None:
self.render_header_if_needed(state, "Model Leaderboard")
df = state.model_evaluation.leaderboard
with pd.option_context("display.max_rows", 100 if len(df) <= 100 else 20):
self.display_obj(df)