Issue
To find the best hyperparameters for a Support Vector Regression i did a grid search with a DataFrame as result like:
svr__kernel svr__C svr__epsilon mae
rbf 0.01 0.1 19.80
linear 0.01 0.1 19.00
poly2 0.01 0.1 19.72
rbf 0.01 0.2 19.76
.. .. .. ..
To visualize the results i created a contour plot for one kernel.
fig, ax = plt.subplots(figsize=(15,7))
plot_df = df[df.svr__kernel == "poly2"].copy()
C = plot_df["svr__C"]
epsilon = plot_df["svr__epsilon"]
score = plot_df["mae"]
# Plotting all evaluations:
ax.plot(C, epsilon, "ko", ms=1)
# Create a contour plot
cntr = ax.tricontourf(C, epsilon, score, levels=12, cmap="RdBu_r")
# Adjusting the colorbar
fig.colorbar(cntr, ax=ax, label="MAE")
# Adjusting the axis limits
ax.set(
xlim=(min(C), max(C)),
ylim=(min(epsilon), max(epsilon)),
xlabel="C",
ylabel="Epsilon",
)
ax.set_title("SVR performance landscape")
Now i would like to have a FacetGrid with contour plots from every kernel and the same colorbar for the mae value. Unfortunately i have serious problems understanding the proceeding of FacetGrids.
Solution
Answer
If you have a dataframe like this:
kernels = ['rbf', 'linear', 'poly2']
c_size = 10
eps_size = 10
df = pd.DataFrame({'svr__kernel': np.repeat(kernels, c_size*eps_size),
'svr__C': len(kernels)*eps_size*list(np.linspace(0, 5, c_size)),
'svr__epsilon': len(kernels)*list(np.repeat(np.linspace(0.1, 1, eps_size), c_size))})
df['mae'] = 15 + 10*np.random.random(len(df))
svr__kernel svr__C svr__epsilon mae
0 rbf 0.000000 0.1 18.745401
1 rbf 0.555556 0.1 24.507143
2 rbf 1.111111 0.1 22.319939
3 rbf 1.666667 0.1 20.986585
4 rbf 2.222222 0.1 16.560186
.. ... ... ... ...
295 poly2 2.777778 1.0 20.222433
296 poly2 3.333333 1.0 22.699936
297 poly2 3.888889 1.0 17.158210
298 poly2 4.444444 1.0 21.228905
299 poly2 5.000000 1.0 15.853475
You can set up the seaborn.FacetGrid
with:
overall_min = df['mae'].min()
overall_max = df['mae'].max()
cmap = RdBu_r
levels = 12
g = sns.FacetGrid(df, col = 'svr__kernel')
g.map(plt.tricontourf, 'svr__C', 'svr__epsilon', 'mae', levels = levels, cmap = cmap, vmin = overall_min, vmax = overall_max)
Then you can move to the left the last plot in order to make some space for the colorbar, add an axis and draw the colormap on it:
g.fig.subplots_adjust(right = 0.88)
cbar_ax = g.fig.add_axes([0.9, 0.1, 0.03, 0.8])
norm = BoundaryNorm(np.linspace(overall_min, overall_max, levels), cmap.N)
plt.colorbar(ScalarMappable(norm = norm, cmap = cmap), cax = cbar_ax)
Complete Code
In this example I added 3
to 'mae'
column with add_3_to_poly2
function only for 'poly2'
kernel, with the aim of doing a check on colorbar values with respect to contourf levels.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from matplotlib.cm import ScalarMappable, RdBu_r
from matplotlib.colors import BoundaryNorm
def add_3_to_poly2(df):
if df['svr__kernel'] == 'poly2':
return df['mae'] + 3
else:
return df['mae']
kernels = ['rbf', 'linear', 'poly2']
c_size = 10
eps_size = 10
df = pd.DataFrame({'svr__kernel': np.repeat(kernels, c_size*eps_size),
'svr__C': len(kernels)*eps_size*list(np.linspace(0, 5, c_size)),
'svr__epsilon': len(kernels)*list(np.repeat(np.linspace(0.1, 1, eps_size), c_size))})
df['mae'] = 15 + 10*np.random.random(len(df))
df['mae'] = df.apply(add_3_to_poly2, axis = 1)
overall_min = df['mae'].min()
overall_max = df['mae'].max()
cmap = RdBu_r
levels = 12
g = sns.FacetGrid(df, col = 'svr__kernel')
g.map(plt.tricontourf, 'svr__C', 'svr__epsilon', 'mae', levels = levels, cmap = cmap, vmin = overall_min, vmax = overall_max)
g.fig.subplots_adjust(right = 0.88)
cbar_ax = g.fig.add_axes([0.9, 0.1, 0.03, 0.8])
norm = BoundaryNorm(np.linspace(overall_min, overall_max, levels), cmap.N)
plt.colorbar(ScalarMappable(norm = norm, cmap = cmap), cax = cbar_ax)
plt.show()
Plot
Notes
As you can see, 'poly2'
contourf values are actually greater than other ones and colorbar correctly keeps track of all values, from overall minimum to overall maximum.
Answered By - Zephyr
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.