<jupyter_start><jupyter_text>Notebook_12: Multi Out RegressionThe idea of this notebook is to experiment with multi-output regression to see if I can predict both the location and the depth of the crack and with what accuracy<jupyter_code>from pathlib import Path
import numpy as np
import pandas as pd

from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline

from sklearn.linear_model import LinearRegression, RidgeCV, Ridge
from sklearn.multioutput import MultiOutputRegressor


from src.models.model_metrics import score_model
import altair as alt
from altair_saver import save
import altair_data_server
alt.data_transformers.enable('data_server')
project_root = Path().resolve().parent
data_path = project_root / 'Data' / 'Final' / 'al_data_final.csv'
from src.config import FIGURES
data = pd.read_csv(data_path)
data<jupyter_output><empty_output><jupyter_text>Data PrepFor the sake of a quick experiment, let's stick to the polynomialising that we've done throughout and seemed to show the best results predicting the 1 target<jupyter_code># Split into target and features
X = data.drop(['tc_act', 'x'], axis = 1)
y = data[['tc_act', 'x']]
X
y
# Train test split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, shuffle = True, stratify = data['x'])
X_train
X_test
y_train
y_test
prep_pipeline = Pipeline([
    ("scaler", StandardScaler())
])
X_train_prepared = prep_pipeline.fit_transform(X_train)
X_test_prepared = prep_pipeline.transform(X_test)<jupyter_output><empty_output><jupyter_text>Modelling<jupyter_code>multi_linreg = MultiOutputRegressor(LinearRegression()).fit(X_train_prepared, y_train)
multi_ridge = MultiOutputRegressor(RidgeCV()).fit(X_train_prepared, y_train)
multi_linreg.score(X_train_prepared, y_train)
multi_ridge.score(X_train_prepared, y_train)
y_pred = multi_ridge.predict(X_test_prepared)
y_test
y_pred
rmse_x = np.sqrt(mean_squared_error(y_test.values[:, 1], y_pred[:, 1]))
rmse_tc = np.sqrt(mean_squared_error(y_test.values[:, 0], y_pred[:, 0]))
rmse_x
rmse_tc
multi_df = pd.DataFrame(columns = ['x_act', 'tc_act', 'x_pred', 'tc_pred'])<jupyter_output><empty_output><jupyter_text>Now Let's do it on the whole data<jupyter_code>data
# Shuffle the data
data_shuffled = data.sample(frac = 1)


# Split into target and features
X = data_shuffled.drop(['tc_act', 'x'], axis = 1)
y = data_shuffled[['tc_act', 'x']]
multi_ridge = RidgeCV()

multi_ridge.fit(X, y)
multi_ridge.alpha_
y_pred = multi_ridge.predict(X)
y_pred
x_pred = y_pred[:, 1]
tc_pred = y_pred[:, 0]
multi_df = pd.DataFrame(columns = ['tc_act', 'x_act', 'tc_pred', 'x_pred'])
multi_df['tc_act'] = data_shuffled['tc_act']
multi_df['x_act'] = data_shuffled['x']
multi_df['tc_pred'] = tc_pred
multi_df['x_pred'] = x_pred
multi_df['temp'] = data_shuffled['temp']
multi_df
fig1 = alt.Chart(multi_df).mark_circle(opacity = 0.5).encode(
    x = alt.X('tc_act:Q', title = 'Actual Crack Depth (mm)'),
    y = alt.Y('tc_pred:Q', title = 'Predicted Crack Depth (mm)'),
    color = alt.Color('temp:O', title = 'Temperature (C)', scale = alt.Scale(scheme = 'reds'))
).properties(
    width = 800,
    height = 400,
    title = 'Multi-output Regression Prediction Accuracy (Aluminium) (Crack Depth)'
)

save(fig1, fp = str(FIGURES/'multi_output_crack_depth.png'), fmt = 'png', method = 'selenium', scale_factor = 6.0)
fig1
fig2 = alt.Chart(multi_df).mark_circle(opacity = 0.5).encode(
    x = alt.X('x_act:Q', title = 'Actual Crack Position (mm)'),
    y = alt.Y('x_pred:Q', title = 'Predicted Crack Position (mm)'),
    color = alt.Color('temp:O', title = 'Temperature (C)', scale = alt.Scale(scheme = 'reds'))
).properties(
    width = 800,
    height = 400,
    title = 'Multi-output Regression Prediction Accuracy (Aluminium) (Crack Position)'
)

save(fig2, fp = str(FIGURES/'multi_output_crack_position.png'), fmt = 'png', method = 'selenium', scale_factor = 6.0)
fig2
rmse_dict = {'Single Prediction': 0.179, 'Multi-Output Prediction': 0.209}
rmse_df = pd.DataFrame({'output': ['Single Prediction', 'Multi-Output Prediction'], 'RMSE': [0.179, 0.209]})
rmse_df
fig3 = alt.Chart(rmse_df).mark_bar(size = 100).encode(
    x = alt.X('output:N', title = 'Model Prediction Mode', axis = None),
    y = alt.Y('RMSE:Q', title = 'Root Mean Squared Error (mm)'),
    color = alt.Color('output:N', title = 'Prediction Mode')
).properties(
    width = 500,
    height = 400,
    title = 'Single vs Multi-Output Predictive Accuracy (Aluminium) (Crack Depth)'
)

save(fig3, fp = str(FIGURES/'multi_output_accuracy.png'), fmt = 'png', method = 'selenium', scale_factor = 6.0)
fig3
# Recreate ML vs original model image in altair (final_rmse_comparison.png)

comp_df = pd.DataFrame({'model': ['Referenced Polynomial Model', 'Multiple Ridge Regression Model'], 'rmse': [0.799, 0.179]})

fig4 = alt.Chart(comp_df).mark_bar(size = 100).encode(
    x = alt.X('model:N', title = 'Model', sort = '-y', axis = None),
    y = alt.Y('rmse:Q', title = 'Root Mean Squared Error (mm)', scale = alt.Scale(domain = (0.0, 1.0))),
    color = alt.Color('model:N', title = 'Model')
).properties(
    width = 500,
    height = 400,
    title = 'RMSE Comparison (Aluminium) (Crack Depth)'
)

save(fig4, fp = str(FIGURES/'final_rmse_comparison.png'), fmt = 'png', method = 'selenium', scale_factor = 6.0)
fig4
comp_df_b = pd.DataFrame({'model': ['Traditional Curve Fitting', 'Multiple Ridge Regression Model'], 'rmse': [0.799, 0.179]})

fig4b = alt.Chart(comp_df_b).mark_bar(size = 100).encode(
    x = alt.X('model:N', title = 'Model', sort = '-y', axis = None),
    y = alt.Y('rmse:Q', title = 'Root Mean Squared Error (mm)', scale = alt.Scale(domain = (0.0, 1.0))),
    color = alt.Color('model:N', title = 'Model')
).properties(
    width = 500,
    height = 400,
    title = 'RMSE Comparison (Aluminium) (Crack Depth)'
)
fig4b
save(fig4b, fp = str(FIGURES/'ml_vs_curve_fitting.png'), fmt = 'png', method = 'selenium', scale_factor = 6.0)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14860426929392448, 'fraction_numerical': 0.02019704433497537, 'mean_word_length': 5.445502645502645, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, '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': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '16959', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2314, 'n_tokens_neox': 2190, 'n_words': 547, 'path': 'Notebooks/Notebook_12 Multiout Regression.ipynb', 'repo_name': 'FollowTheProcess/msc_project', 'size': '6090'}