Extras

Transformers Adicionales

Transformer Velocidades

Vamos a crear un transformer para calcular la velocidad promedio en cada zona (borough) de Nueva York y asignarle esa velocidad a cada viaje.

Para calcular la velocidad necesitamos el tiempo que se demora el viaje. Como esta es nuestra variable dependiente, debemos tener en cuenta que solo podemos usar los datos de train porque, en principio, no hemos observado los datos de validation. Al calcular las velocidades para cada zona con los datos que llegan a .fit() evitamos el data leakage porque garantizamos que no estamos usando los tiempos de viaje de validaci贸n.

class TransformerVelocidad(BaseEstimator, TransformerMixin):
    def fit(self, X, y):
        X_init = X[["pickup_latitude", "pickup_longitude"]].to_numpy()
        X_final = X[["dropoff_latitude", "dropoff_longitude"]].to_numpy()

        # Distancia de Haversine
        distancia = self.distancia_haversine(X_init=X_init, X_final=X_final)
        
        velocidad_df = pd.DataFrame()
        tiempo_en_horas = y.to_numpy() / 3600
        velocidad_df["velocidad"] = distancia / tiempo_en_horas
        velocidad_df["pickup_borough"] = X["pickup_borough"]
        velocidad_borough = velocidad_df.groupby("pickup_borough")["velocidad"].mean()
        self.velocidad_borough = velocidad_borough.to_dict()
        return self

    def transform(self, X, y=None):
        velocidad_df = pd.DataFrame()
        velocidad_df["velocidad"] = X["pickup_borough"].map(self.velocidad_borough)
        return velocidad_df
    
    def distancia_haversine(self, X_init, X_final):
        # Convertir de decimal a radianes
        X_init = np.radians(X_init)
        X_final = np.radians(X_final)

        # Formula de Haversine
        dlat = X_final[:, 0] - X_init[:, 0] 
        dlon = X_final[:, 1] - X_init[:, 1]
        a = (np.sin(dlat / 2) ** 2) + np.cos(X_init[:, 0]) * np.cos(X_final[:, 0]) * (np.sin(dlon / 2) ** 2)
        c = 2 * np.arcsin(np.sqrt(a))
        r = 6371 # Radio de la tierra en kil贸metros
        return c * r
transformer_velocidades = TransformerVelocidad()
velocidades_df = transformer_velocidades.fit_transform(train_df, y_train)
velocidades_df.head()

Entrenando con XGBoost y LightGBM

def log_metrics_mlflow(y_pred_val, y_val):
    val_mae = mean_absolute_error(y_pred=y_pred_val, y_true=y_val)
    val_rmse = mean_squared_error(y_pred=y_pred_val, y_true=y_val, squared=False)
    val_mape = mean_absolute_percentage_error(y_pred=y_pred_val, y_true=y_val)
    val_r2 = r2_score(y_pred=y_pred_val, y_true=y_val)

    mlflow.log_metric("val_mae", val_mae)
    mlflow.log_metric("val_rmse", val_rmse)
    mlflow.log_metric("val_mape", val_mape)
    mlflow.log_metric("val_r2", val_r2)

LightGBM

from lightgbm import LGBMRegressor

mlflow.lightgbm.autolog()
with mlflow.start_run(run_name="lgbm") as run:
    lgbm_model = LGBMRegressor()
    lgbm_model.fit(X_train, y_train)
    y_pred_val = lgbm_model.predict(X_val)
    log_metrics_mlflow(y_pred_val, y_val)
    mlflow.log_artifact("preprocesser.pkl")
    
    with open("lgbm_model.pkl", "wb") as f:
        dill.dump(lgbm_model, f)
    mlflow.log_artifact("lgbm_model.pkl")

XGBoost

from xgboost import XGBRegressor

mlflow.xgboost.autolog()
with mlflow.start_run(run_name="xgboost") as run:
    xgb_model = XGBRegressor()
    xgb_model.fit(X_train, y_train)
    y_pred_val = xgb_model.predict(X_val)
    log_metrics_mlflow(y_pred_val, y_val)
    mlflow.log_artifact("preprocesser.pkl")
    
    with open("xgb_model.pkl", "wb") as f:
        dill.dump(xgb_model, f)
    mlflow.log_artifact("xgb_model.pkl")

Last updated

Was this helpful?