import warnings
warnings.simplefilter("ignore")
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor(max_depth=2)
from sklearn.model_selection import train_test_split
X = pd.read_csv('../vol/intermediate_results/X_opening.csv')
y = X['worldwide_gross']
X = X.drop('worldwide_gross',axis=1)
X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=1)
model.fit(X_train,y_train)
import graphviz
from sklearn.tree import export_graphviz
treedot = export_graphviz(model,out_file=None, feature_names=X.columns)
treedot
graphviz.Source(treedot)
Virtudes de los arboles de decision:
Sin embargo en la practica existen modelos que obtienen mejor rendimiento. Como mejorar el modelo de arboles de decisión?
Concepto General
Random Forest y Gradient Boosted Trees, forman parte de una familia de algoritmos que se denominan ensembles.
$$ Ensemble = Submodelos \rightarrow Entrenamiento \rightarrow Predicciones_{Intermedias} \rightarrow Voto \rightarrow Prediccion_{final}$$Cómo funciona el algoritmo Random Forest?
Vamos a generar cientos de modelos de arboles de decisión que serán entrenados sobre conjuntos de datos bootstrapeados del conjunto de datos original y donde para cada etapa de separación el conjunto de features elegibles sera un subconjunto aleatorio del conjunto original de features.
Cada uno de los arboles entrenados luego podrá votar por su predicción y promediaremos estos votos.
Ensembles del pobre ("Poor man's ensembles")
from sklearn.ensemble import VotingClassifier
sirve por ejemplo para hacer un ensemble manual de clasificaciónEn general los ensembles del pobre funcionan ya que cada uno de los modelos que votarán en conjunto son bastante fuertes.
Porqué RF es poderoso?
Así el algoritmo de Random Forest compromete un poco de poder de predicción de cada uno de los decision trees que arma, pero la forma aleatoria de generarlos hace que esten fuertemente descorrelacionados.
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_validate
forest = RandomForestRegressor(200)
results = cross_validate(forest,X,y,cv=5,scoring='r2')
test_scores = results['test_score']
train_scores = results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
Mejor resultado que Lasso! Ya no tenemos Bias y tenemos un mejor score r2. Sin embargo tenemos una diferencia importante entre score de entrenamiento y de test (overfit).
from sklearn.ensemble import GradientBoostingRegressor
ensemble = GradientBoostingRegressor()
results = cross_validate(ensemble,X,y,cv=5,scoring='r2')
test_scores = results['test_score']
train_scores = results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
Cómo optimizamos los parametros de este último modelo?
Grid Search
Por ahora dijimos que:
Sin embargo una vez que hemos finalizado nuestra etapa de prototipaje y ya queremos establecer un modelo definitivo deberiamos seguir el flujo siguiente.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=1)
from sklearn.model_selection import GridSearchCV
param_test1 = {'n_estimators':range(20,501,20)}
estimator = GradientBoostingRegressor(learning_rate=0.1,
min_samples_split=500,
min_samples_leaf=50,
max_depth=8,
max_features='sqrt',
subsample=0.8,
random_state=10)
gsearch1 = GridSearchCV(estimator,
param_grid = param_test1,
scoring='r2',
cv=5)
gsearch1.fit(X_train,y_train)
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_
gsearch1.best_estimator_
cross_validate(gsearch1.best_estimator_,X_train,y_train)
final_results = cross_validate(gsearch1.best_estimator_,X_train,y_train)
test_scores = final_results['test_score']
train_scores = final_results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
Recursos
Próximos pasos