File size: 4,792 Bytes
85b83ea | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import argparse
import os
import pandas as pd
import time
import mlflow
from mlflow.models.signature import infer_signature
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, FunctionTransformer, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
if __name__ == "__main__":
# Set your variables for your environment
EXPERIMENT_NAME = "appointment_cancellation_detector"
# Set tracking URI to your Heroku application
mlflow.set_tracking_uri("https://lekhal15-mlflow_demo_1.hf.space/")
# Set experiment's info
mlflow.set_experiment(EXPERIMENT_NAME)
# Get our experiment info
experiment = mlflow.get_experiment_by_name(EXPERIMENT_NAME)
### MLFLOW Experiment setup
# experiment_name="appointment_cancellation_detector"
# mlflow.set_experiment(experiment_name)
# experiment = mlflow.get_experiment_by_name(experiment_name)
# client = mlflow.tracking.MlflowClient()
# mlflow.set_tracking_uri(os.environ["APP_URI"])
# run = client.create_run(experiment.experiment_id)
print("training model...")
# Time execution
start_time = time.time()
# Call mlflow autolog
mlflow.sklearn.autolog(log_models=False) # We won't log models right away
# Parse arguments given in shell script
parser = argparse.ArgumentParser()
parser.add_argument("--n_estimators", default=1)
parser.add_argument("--min_samples_split", default=2)
args = parser.parse_args()
# Import dataset
df = pd.read_csv(
"https://full-stack-assets.s3.eu-west-3.amazonaws.com/Deployment/doctolib_simplified_dataset_01.csv"
)
# X, y split
X = df.iloc[:, 3:-1]
y = df.iloc[:, -1].apply(lambda x: 0 if x == "No" else 1)
# Train / test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
print(df.columns)
# Preprocessing
def date_processing(df):
df = df.copy()
## Transform datetime into a number
df["ScheduledDay"] = pd.to_datetime(
df["ScheduledDay"], yearfirst=True, infer_datetime_format=True
)
df["AppointmentDay"] = pd.to_datetime(
df["AppointmentDay"], yearfirst=True, infer_datetime_format=True
)
## Get the difference between scheduled day and appointment
df["time_difference_between_scheduled_and_appointment"] = (
df["AppointmentDay"] - df["ScheduledDay"]
).dt.days
## Remove redundant info
df = df.drop(["ScheduledDay", "AppointmentDay"], axis=1)
return df
date_preprocessor = FunctionTransformer(date_processing)
# Preprocessing
X_train_after_date_processing = date_processing(X_train)
categorical_features = X_train_after_date_processing.select_dtypes(
"object"
).columns # Select all the columns containing strings
categorical_transformer = OneHotEncoder(
drop="first", handle_unknown="error", sparse=False
)
numerical_feature_mask = ~X_train_after_date_processing.columns.isin(
X_train_after_date_processing.select_dtypes("object").columns
) # Select all the columns containing anything else than strings
numerical_features = X_train_after_date_processing.columns[numerical_feature_mask]
numerical_transformer = StandardScaler()
feature_preprocessor = ColumnTransformer(
transformers=[
("categorical_transformer", categorical_transformer, categorical_features),
("numerical_transformer", numerical_transformer, numerical_features),
]
)
# Pipeline
n_estimators = int(args.n_estimators)
min_samples_split = int(args.min_samples_split)
model = Pipeline(
steps=[
("Dates_preprocessing", date_preprocessor),
("features_preprocessing", feature_preprocessor),
(
"Regressor",
RandomForestClassifier(
n_estimators=n_estimators, min_samples_split=min_samples_split
),
),
]
)
# Log experiment to MLFlow
with mlflow.start_run(experiment_id=experiment.experiment_id) as run:
model.fit(X_train, y_train)
predictions = model.predict(X_train)
# Log model seperately to have more flexibility on setup
mlflow.sklearn.log_model(
sk_model=model,
artifact_path="appointment_cancellation_detector",
registered_model_name="appointment_cancellation_detector_RF",
signature=infer_signature(X_train, predictions),
)
print("...Done!")
print(f"---Total training time: {time.time()-start_time}")
|