<jupyter_start><jupyter_text>Task 3  Imports<jupyter_code>import numpy as np
import pandas as pd
from joblib import dump, load
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.rcParams.update({'font.size': 16, 'axes.labelweight': 'bold', 'figure.figsize': (8,6)})
## add any other additional packages that you need. You are free to use any packages for vizualization.<jupyter_output><empty_output><jupyter_text>Part 1: Recall as a final goal of this project. We want to build and deploy ensemble machine learning models in the cloud, where features are outputs of different climate models and the target is the actual rainfall observation. In this milestone, you'll actually build these ensemble machine learning models in the cloud.  **Your tasks:**1. Read the data CSV from your s3 bucket. 2. Drop rows with nans. 3. Split the data into train (80%) and test (20%) portions with `random_state=123`. 4. Carry out EDA of your choice on the train split. 5. Train ensemble machine learning model using `RandomForestRegressor` and evaluate with metric of your choice (e.g., `RMSE`) by considering `Observed` as the target column. 6. Discuss your results. Are you getting better results with ensemble models compared to the individual climate models? > Recall that individual columns in the data are predictions of different climate models.<jupyter_code>## Depending on the permissions that you provided to your bucket you might need to provide your aws credentials
## to read from the bucket, if so provide with your credentials and pass as storage_options=aws_credentials
# aws_credentials = {"key": "","secret": "","token":""}
aws_credentials ={"key": "ASIASOALUKF4II54PPRP",
                  "secret": "<KEY>",
                  "token": "<KEY>}

df = pd.read_csv("s3://mds-s3-19/output/ml_data_SYD.csv", 
                 index_col=0, parse_dates=True, storage_options=aws_credentials)
## Use your ML skills to get from step 1 to step 6
# Drop rows with nans

df = df.dropna()
# Data Splitting

train_df, test_df = train_test_split(df, test_size=0.2, random_state=123)
X_train, y_train = train_df.drop(columns=['Observed']), train_df['Observed']
X_test, y_test = test_df.drop(columns=['Observed']), test_df['Observed']
# EDA

fig, axes = plt.subplots(nrows=5, ncols=5, figsize=(20, 20))
row_order = 0
column_order = 0

for model in train_df.columns:
    if model == 'Observed':
        pass
    else:
        fig = train_df[model].plot.line(ax=axes[row_order, column_order], alpha=0.3)
        fig = train_df['Observed'].plot.line(ax=axes[row_order, column_order], alpha=0.3)
        fig.set_title(f"{model} vs Observed", fontsize=12)
        fig.set_ylabel("Precipitation [mm/day]", fontsize=10)
        fig.set_xlabel("Time", fontsize=10)
        fig.legend(fontsize=10)

        if column_order == 4:
            column_order = 0
            row_order += 1
        else:
            column_order += 1

for ax in axes.flat:
    ax.label_outer()
# Training

model_rf = RandomForestRegressor(n_jobs=-1)
model_rf.fit(X_train, y_train)
randomforest_pred = model_rf.predict(X_test)

test_df["RandomForestReg"] = randomforest_pred  # For easiness of for-loop
# Evaluation

models_rmse = dict()   # prepare dict for RMSE results

for model in test_df.columns:
    if model == 'Observed':
        pass
    else:
        models_rmse[model] = np.sqrt(mean_squared_error(y_test, test_df[model]))
pd.DataFrame(models_rmse, index=["RMSE"]).T.sort_values(by="RMSE")<jupyter_output><empty_output><jupyter_text>**Discussion:** With the ensemble model (`RandomForestRegressor` trained on features that are outputs from different climate models) and only with default hyperparameters, we are getting the lowest RMSE compared to the individual models.   Part 2:  Preparation for deploying model next week ***NOTE: Complete task 4 from the milestone3 before coming here*** We’ve found the best hyperparameter settings with MLlib (from the task 4 from milestone3), here we then use the same hyperparameters to train a scikit-learn model.<jupyter_code>model = RandomForestRegressor(n_estimators=100, max_depth=5)
model.fit(X_train, y_train)
print(f"Train RMSE: {mean_squared_error(y_train, model.predict(X_train), squared=False):.2f}")
print(f" Test RMSE: {mean_squared_error(y_test, model.predict(X_test), squared=False):.2f}")
# ready to deploy
dump(model, "model.joblib")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10226522982186056, 'fraction_numerical': 0.01561469100505828, 'mean_word_length': 4.720754716981132, 'pattern_counts': {'":': 6, '<': 15, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '643429', 'license': 'MIT', 'n_tokens_mistral': 1483, 'n_tokens_neox': 1393, 'n_words': 466, 'path': 'notebooks/Milestone3-Task3.ipynb', 'repo_name': 'UBC-MDS/DSCI_525_Group19', 'size': '4962'}