From fcdb506eb4736e1d03a85d3762288f37d3defe80 Mon Sep 17 00:00:00 2001 From: christosPro123 <protopapaschristos@gmail.com> Date: Sat, 3 Jun 2023 11:52:53 +0100 Subject: [PATCH] Finished report, code comments, QoL formatting changes --- COMP3217.docx | Bin 13832 -> 15225 bytes part1.ipynb | 2 +- part2.ipynb | 24 ++++++++++++++---------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/COMP3217.docx b/COMP3217.docx index e4bd96f44bf0065b1cc577a2cd42134a8fa508e1..96233f4717916487a884a0500943b51456c29c54 100644 GIT binary patch delta 9331 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 T3IhW}kLlzGrb=v!EI^_Ft{J-n delta 7988 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 diff --git a/part1.ipynb b/part1.ipynb index 4d6c92e..5e41726 100644 --- a/part1.ipynb +++ b/part1.ipynb @@ -507,7 +507,7 @@ "test_data['predicted_marker'] = y_pred_new\n", "\n", "# Save the updated DataFrame to a new CSV file\n", - "test_data.to_csv('TestingDataBinary_with_predictions.csv', index=False)" + "test_data.to_csv('TestingResultsBinary.csv', index=False)" ] } ], diff --git a/part2.ipynb b/part2.ipynb index eb26b8e..2382678 100644 --- a/part2.ipynb +++ b/part2.ipynb @@ -153,6 +153,7 @@ } ], "source": [ + "#Plot histogram of classification distribution\n", "plt.hist(train_df['129'])" ] }, @@ -162,6 +163,7 @@ "metadata": {}, "outputs": [], "source": [ + "#Split features from target classification to fit Random Forest Classifier\n", "X = train_df.drop('129', axis=1)\n", "y = train_df['129']" ] @@ -196,6 +198,7 @@ "metadata": {}, "outputs": [], "source": [ + "#Extract the importance of each feature from the model into a seperate dataframe\n", "importances = rfc.feature_importances_\n", "feature_importances = pd.DataFrame({'Feature':X.columns, 'Importance': importances})" ] @@ -206,7 +209,8 @@ "metadata": {}, "outputs": [], "source": [ - "feature_importances = feature_importances.sort_values('Importance', ascending=False)\n" + "#Sort the features dataframe in descending order (highest importance feature at top)\n", + "feature_importances = feature_importances.sort_values('Importance', ascending=False)" ] }, { @@ -237,23 +241,17 @@ "metadata": {}, "outputs": [], "source": [ + "#Extract the top N features from dataframe into a list (n was changed several times to test - 40 is ideal to avoid overfitting)\n", "n_features= feature_importances.head(40)['Feature'].tolist()" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Feature Columns: 91, 82, 101, 53, and 115" - ] - }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [], "source": [ + "#Re-split the data based on those 40 features\n", "X = train_df[n_features]\n", "y = train_df['129']" ] @@ -264,6 +262,7 @@ "metadata": {}, "outputs": [], "source": [ + "#Split into training and testing data\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)" ] }, @@ -287,6 +286,7 @@ } ], "source": [ + "#Train classifier again based on new split of data\n", "rfc = RandomForestClassifier()\n", "rfc.fit(X_train,y_train)" ] @@ -297,6 +297,7 @@ "metadata": {}, "outputs": [], "source": [ + "#Make first predictions\n", "y_pred = rfc.predict(X_test)" ] }, @@ -306,6 +307,7 @@ "metadata": {}, "outputs": [], "source": [ + "#Print accuracy\n", "accuracy = accuracy_score(y_test,y_pred)" ] }, @@ -335,7 +337,6 @@ "# Generate the classification report\n", "classification_rep = classification_report(y_test, y_pred)\n", "\n", - "# Print the classification report\n", "print(classification_rep)" ] }, @@ -429,6 +430,7 @@ } ], "source": [ + "#Split data to classify based on those same n-features\n", "multi_test = test_df[n_features]\n", "predicted_category = rfc.predict(multi_test)\n", "print(\"Predicted Category: \", predicted_category)" @@ -452,6 +454,7 @@ } ], "source": [ + "#Calculate distribution of predicted classification\n", "category_counts = pd.Series(predicted_category).value_counts(normalize=True) * 100\n", "print('Category Percentages:')\n", "print(category_counts)" @@ -463,6 +466,7 @@ "metadata": {}, "outputs": [], "source": [ + "#Append predictions to dataframe as new column and save as new CSV\n", "test_df[\"Prediction Markers\"] = predicted_category\n", "test_df.to_csv(\"TestingResultsMulti.csv\",index=False)" ] -- GitLab