2012-10-30 15:24:59 +08:00
|
|
|
"""
|
|
|
|
|
========================
|
|
|
|
|
Partial Dependence Plots
|
|
|
|
|
========================
|
|
|
|
|
|
2015-11-05 08:21:50 +08:00
|
|
|
Partial dependence plots show the dependence between the target function [2]_
|
2012-10-30 15:24:59 +08:00
|
|
|
and a set of 'target' features, marginalizing over the
|
|
|
|
|
values of all other features (the complement features). Due to the limits
|
|
|
|
|
of human perception the size of the target feature set must be small (usually,
|
2012-11-11 01:52:15 +08:00
|
|
|
one or two) thus the target features are usually chosen among the most
|
2012-12-25 20:16:05 +08:00
|
|
|
important features
|
|
|
|
|
(see :attr:`~sklearn.ensemble.GradientBoostingRegressor.feature_importances_`).
|
2012-10-30 15:24:59 +08:00
|
|
|
|
|
|
|
|
This example shows how to obtain partial dependence plots from a
|
2012-11-21 05:34:59 +08:00
|
|
|
:class:`~sklearn.ensemble.GradientBoostingRegressor` trained on the California
|
2015-11-05 08:21:50 +08:00
|
|
|
housing dataset. The example is taken from [1]_.
|
2012-10-30 15:24:59 +08:00
|
|
|
|
2012-11-26 06:20:40 +08:00
|
|
|
The plot shows four one-way and one two-way partial dependence plots.
|
|
|
|
|
The target variables for the one-way PDP are:
|
|
|
|
|
median income (`MedInc`), avg. occupants per household (`AvgOccup`),
|
2012-10-30 15:24:59 +08:00
|
|
|
median house age (`HouseAge`), and avg. rooms per household (`AveRooms`).
|
2012-11-26 06:20:40 +08:00
|
|
|
|
2012-11-11 04:10:55 +08:00
|
|
|
We can clearly see that the median house price shows a linear relationship
|
|
|
|
|
with the median income (top left) and that the house price drops when the
|
2012-11-26 06:20:40 +08:00
|
|
|
avg. occupants per household increases (top middle).
|
|
|
|
|
The top right plot shows that the house age in a district does not have
|
|
|
|
|
a strong influence on the (median) house price; so does the average rooms
|
|
|
|
|
per household.
|
|
|
|
|
The tick marks on the x-axis represent the deciles of the feature values
|
2013-06-27 21:09:16 +08:00
|
|
|
in the training data.
|
2012-10-30 15:24:59 +08:00
|
|
|
|
|
|
|
|
Partial dependence plots with two target features enable us to visualize
|
2012-11-26 06:20:40 +08:00
|
|
|
interactions among them. The two-way partial dependence plot shows the
|
2012-10-30 15:24:59 +08:00
|
|
|
dependence of median house price on joint values of house age and avg.
|
|
|
|
|
occupants per household. We can clearly see an interaction between the
|
|
|
|
|
two features:
|
2013-06-27 21:09:16 +08:00
|
|
|
For an avg. occupancy greater than two, the house price is nearly independent
|
2012-10-30 15:24:59 +08:00
|
|
|
of the house age, whereas for values less than two there is a strong dependence
|
|
|
|
|
on age.
|
|
|
|
|
|
2015-11-05 08:21:50 +08:00
|
|
|
.. [1] T. Hastie, R. Tibshirani and J. Friedman,
|
2012-12-25 20:16:05 +08:00
|
|
|
"Elements of Statistical Learning Ed. 2", Springer, 2009.
|
2012-10-30 15:24:59 +08:00
|
|
|
|
2015-11-05 08:21:50 +08:00
|
|
|
.. [2] For classification you can think of it as the regression score before
|
2012-11-27 15:36:46 +08:00
|
|
|
the link function.
|
2012-10-30 15:24:59 +08:00
|
|
|
"""
|
2016-01-04 21:18:48 +08:00
|
|
|
from __future__ import print_function
|
2013-02-01 22:04:03 +08:00
|
|
|
print(__doc__)
|
2012-10-30 15:24:59 +08:00
|
|
|
|
2012-10-15 01:59:10 +08:00
|
|
|
import numpy as np
|
2014-02-27 17:22:21 +08:00
|
|
|
import matplotlib.pyplot as plt
|
2012-10-15 01:59:10 +08:00
|
|
|
|
2012-10-23 21:13:02 +08:00
|
|
|
from mpl_toolkits.mplot3d import Axes3D
|
2012-10-15 01:59:10 +08:00
|
|
|
|
2015-09-11 02:26:39 +08:00
|
|
|
from sklearn.model_selection import train_test_split
|
2012-10-15 01:59:10 +08:00
|
|
|
from sklearn.ensemble import GradientBoostingRegressor
|
2012-11-27 15:36:46 +08:00
|
|
|
from sklearn.ensemble.partial_dependence import plot_partial_dependence
|
2012-11-26 06:20:40 +08:00
|
|
|
from sklearn.ensemble.partial_dependence import partial_dependence
|
2012-11-11 03:16:10 +08:00
|
|
|
from sklearn.datasets.california_housing import fetch_california_housing
|
2012-10-15 01:59:10 +08:00
|
|
|
|
2015-12-15 00:49:14 +08:00
|
|
|
|
|
|
|
|
def main():
|
2015-12-16 22:18:34 +08:00
|
|
|
cal_housing = fetch_california_housing()
|
2015-12-15 00:49:14 +08:00
|
|
|
|
|
|
|
|
# split 80/20 train-test
|
|
|
|
|
X_train, X_test, y_train, y_test = train_test_split(cal_housing.data,
|
|
|
|
|
cal_housing.target,
|
|
|
|
|
test_size=0.2,
|
|
|
|
|
random_state=1)
|
|
|
|
|
names = cal_housing.feature_names
|
|
|
|
|
|
2016-02-22 00:07:56 +08:00
|
|
|
print("Training GBRT...")
|
2015-12-15 00:49:14 +08:00
|
|
|
clf = GradientBoostingRegressor(n_estimators=100, max_depth=4,
|
|
|
|
|
learning_rate=0.1, loss='huber',
|
|
|
|
|
random_state=1)
|
|
|
|
|
clf.fit(X_train, y_train)
|
2016-01-04 21:18:48 +08:00
|
|
|
print(" done.")
|
2015-12-15 00:49:14 +08:00
|
|
|
|
|
|
|
|
print('Convenience plot with ``partial_dependence_plots``')
|
|
|
|
|
|
|
|
|
|
features = [0, 5, 1, 2, (5, 1)]
|
2015-12-16 22:18:34 +08:00
|
|
|
fig, axs = plot_partial_dependence(clf, X_train, features,
|
|
|
|
|
feature_names=names,
|
2015-12-15 00:49:14 +08:00
|
|
|
n_jobs=3, grid_resolution=50)
|
|
|
|
|
fig.suptitle('Partial dependence of house value on nonlocation features\n'
|
|
|
|
|
'for the California housing dataset')
|
|
|
|
|
plt.subplots_adjust(top=0.9) # tight_layout causes overlap with suptitle
|
|
|
|
|
|
|
|
|
|
print('Custom 3d plot via ``partial_dependence``')
|
|
|
|
|
fig = plt.figure()
|
|
|
|
|
|
|
|
|
|
target_feature = (1, 5)
|
2015-11-17 04:18:40 +08:00
|
|
|
pdp, axes = partial_dependence(clf, target_feature,
|
|
|
|
|
X=X_train, grid_resolution=50)
|
|
|
|
|
XX, YY = np.meshgrid(axes[0], axes[1])
|
|
|
|
|
Z = pdp[0].reshape(list(map(np.size, axes))).T
|
2015-12-15 00:49:14 +08:00
|
|
|
ax = Axes3D(fig)
|
2017-06-28 20:56:27 +08:00
|
|
|
surf = ax.plot_surface(XX, YY, Z, rstride=1, cstride=1,
|
|
|
|
|
cmap=plt.cm.BuPu, edgecolor='k')
|
2015-12-15 00:49:14 +08:00
|
|
|
ax.set_xlabel(names[target_feature[0]])
|
|
|
|
|
ax.set_ylabel(names[target_feature[1]])
|
|
|
|
|
ax.set_zlabel('Partial dependence')
|
|
|
|
|
# pretty init view
|
|
|
|
|
ax.view_init(elev=22, azim=122)
|
|
|
|
|
plt.colorbar(surf)
|
2017-06-28 20:56:27 +08:00
|
|
|
plt.suptitle('Partial dependence of house value on median\n'
|
|
|
|
|
'age and average occupancy')
|
2015-12-15 00:49:14 +08:00
|
|
|
plt.subplots_adjust(top=0.9)
|
|
|
|
|
|
|
|
|
|
plt.show()
|
|
|
|
|
|
|
|
|
|
|
2015-12-16 22:18:34 +08:00
|
|
|
# Needed on Windows because plot_partial_dependence uses multiprocessing
|
|
|
|
|
if __name__ == '__main__':
|
2015-12-15 00:49:14 +08:00
|
|
|
main()
|