Commit 135e2f32 authored by Chamodi Yapa's avatar Chamodi Yapa

ML Model

parent 3d883784
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ML Model Development - Random Forest"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Import Necessary Modules"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.ensemble import RandomForestRegressor\n",
"from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error, explained_variance_score\n",
"import matplotlib.pyplot as plt\n",
"import joblib"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"# Load the final dataset\n",
"df = pd.read_csv(\"../DataPreprocessing/final_game_dataset.csv\")\n",
"\n",
"# Load the scalers\n",
"scaler_X = joblib.load(\"./fun1/scaler_X.pkl\")\n",
"scaler_y = joblib.load(\"./fun1/scaler_y.pkl\")"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"# Separate X and y\n",
"X = df.drop(columns=[\"improvement_score\"])\n",
"y = df[\"improvement_score\"].ravel()\n",
"\n",
"# Scale the dataset\n",
"X_scaled = scaler_X.transform(X)\n",
"y_scaled = scaler_y.transform(y.reshape(-1, 1))"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"# Split the dataset into a training and testing set\n",
"X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled, test_size=0.2, random_state=42)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>#sk-container-id-4 {color: black;}#sk-container-id-4 pre{padding: 0;}#sk-container-id-4 div.sk-toggleable {background-color: white;}#sk-container-id-4 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-4 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-4 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-4 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-4 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-4 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-4 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-4 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-4 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-4 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-4 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-4 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-4 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-4 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-4 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-4 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-4 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-4 div.sk-item {position: relative;z-index: 1;}#sk-container-id-4 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-4 div.sk-item::before, #sk-container-id-4 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-4 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-4 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-4 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-4 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-4 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-4 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-4 div.sk-label-container {text-align: center;}#sk-container-id-4 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-4 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-4\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>RandomForestRegressor(random_state=42)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" checked><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">RandomForestRegressor</label><div class=\"sk-toggleable__content\"><pre>RandomForestRegressor(random_state=42)</pre></div></div></div></div></div>"
],
"text/plain": [
"RandomForestRegressor(random_state=42)"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Create and train a Random Forest Regressor model\n",
"rf_model = RandomForestRegressor(n_estimators=100, random_state=42)\n",
"rf_model.fit(X_train, y_train.ravel())"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Make predictions on the test set\n",
"y_pred = rf_model.predict(X_test)\n",
"\n",
"# Inverse transform to get back the original scale\n",
"y_pred_original_scale = scaler_y.inverse_transform(y_pred.reshape(-1, 1))\n",
"y_test_original_scale = scaler_y.inverse_transform(y_test.reshape(-1, 1))\n",
"\n",
"# Plot the predicted vs. actual improvement scores\n",
"plt.scatter(y_test_original_scale, y_pred_original_scale)\n",
"plt.xlabel(\"Actual Improvement Score\")\n",
"plt.ylabel(\"Predicted Improvement Score\")\n",
"plt.title(\"Actual vs. Predicted Improvement Score\")\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Calculate Evaluation Metrics"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training R2 Score: 1.00\n",
"Testing R2 Score: 1.00\n",
"Mean Squared Error: 0.00\n",
"Mean Absolute Error (MAE): 0.00\n",
"Root Mean Squared Error (RMSE): 0.01\n",
"Explained Variance Score: 1.00\n"
]
}
],
"source": [
"# Calculate evaluation metrics\n",
"mse = mean_squared_error(y_test_original_scale, y_pred_original_scale)\n",
"r2 = r2_score(y_test_original_scale, y_pred_original_scale)\n",
"\n",
"# Training accuracy\n",
"y_train_pred = rf_model.predict(X_train)\n",
"train_r2 = r2_score(y_train, y_train_pred)\n",
"\n",
"# Testing accuracy\n",
"test_r2 = r2_score(y_test, y_pred)\n",
"\n",
"print(f\"Training R2 Score: {train_r2:.2f}\")\n",
"print(f\"Testing R2 Score: {test_r2:.2f}\")\n",
"\n",
"\n",
"# Calculate additional evaluation metrics\n",
"mae = mean_absolute_error(y_test_original_scale, y_pred_original_scale)\n",
"rmse = mean_squared_error(y_test_original_scale, y_pred_original_scale, squared=False)\n",
"explained_variance = explained_variance_score(y_test_original_scale, y_pred_original_scale)\n",
"\n",
"# Print evaluation metrics\n",
"print(f\"Mean Squared Error: {mse:.2f}\")\n",
"print(f\"Mean Absolute Error (MAE): {mae:.2f}\")\n",
"print(f\"Root Mean Squared Error (RMSE): {rmse:.2f}\")\n",
"print(f\"Explained Variance Score: {explained_variance:.2f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Cross-Validation"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cross-Validation MSE Scores: [9.57677453e-05 9.10708808e-05 1.02907478e-04 1.10507850e-04\n",
" 1.18874434e-04]\n",
"Average MSE: 0.00010382567759524451\n"
]
}
],
"source": [
"from sklearn.model_selection import cross_val_score\n",
"\n",
"# Perform k-fold cross-validation\n",
"cross_val_scores = cross_val_score(rf_model, X_scaled, y_scaled.ravel(), cv=5, scoring='neg_mean_squared_error')\n",
"cross_val_mse = -cross_val_scores # Convert negative MSE to positive\n",
"\n",
"# Print the cross-validation MSE scores\n",
"print(\"Cross-Validation MSE Scores:\", cross_val_mse)\n",
"print(\"Average MSE:\", cross_val_mse.mean())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Saving the Model"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model saved as 'rf_model.pkl'.\n"
]
}
],
"source": [
"import joblib\n",
"\n",
"# Save the trained model to a file\n",
"joblib.dump(rf_model, \"./fun1/rf_model.pkl\")\n",
"\n",
"print(\"Model saved as 'rf_model.pkl'.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### The metrics and cross-validation MSE scores as percentages "
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training R2 Score: 100.00%\n",
"Testing R2 Score: 99.99%\n",
"Mean Squared Error: 0.02%\n",
"Mean Absolute Error (MAE): 0.40%\n",
"Root Mean Squared Error (RMSE): 1.24%\n",
"Cross-Validation MSE Scores: [0.00957677 0.00910709 0.01029075 0.01105079 0.01188744]\n",
"Average MSE: 0.01%\n"
]
}
],
"source": [
"# Convert R2 scores to percentages\n",
"train_r2_percent = train_r2 * 100\n",
"test_r2_percent = test_r2 * 100\n",
"\n",
"# Convert MSE, MAE, and RMSE to percentages\n",
"mse_percent = mse * 100\n",
"mae_percent = mae * 100\n",
"rmse_percent = rmse * 100\n",
"\n",
"# Convert cross-validation MSE scores to percentages\n",
"cross_val_mse_percent = cross_val_mse * 100\n",
"average_mse_percent = cross_val_mse.mean() * 100\n",
"\n",
"# Print the metrics\n",
"print(f\"Training R2 Score: {train_r2_percent:.2f}%\")\n",
"print(f\"Testing R2 Score: {test_r2_percent:.2f}%\")\n",
"print(f\"Mean Squared Error: {mse_percent:.2f}%\")\n",
"print(f\"Mean Absolute Error (MAE): {mae_percent:.2f}%\")\n",
"print(f\"Root Mean Squared Error (RMSE): {rmse_percent:.2f}%\")\n",
"print(\"Cross-Validation MSE Scores:\", cross_val_mse_percent)\n",
"print(f\"Average MSE: {average_mse_percent:.2f}%\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "learn-joy",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment