From c69f92eb423f12532022b92e0acbd94f5205834d Mon Sep 17 00:00:00 2001 From: yyl1c20 <yyl1c20@soton.ac.uk> Date: Wed, 7 Jun 2023 10:34:58 +0000 Subject: [PATCH] Upload New File --- partASVM.ipynb | 1059 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1059 insertions(+) create mode 100644 partASVM.ipynb diff --git a/partASVM.ipynb b/partASVM.ipynb new file mode 100644 index 0000000..5787f3f --- /dev/null +++ b/partASVM.ipynb @@ -0,0 +1,1059 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h1>1. Loading Datasets</h1>" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "[ TrainingDataBinary.csv info ]\n", + "<class 'pandas.core.frame.DataFrame'>\n", + "RangeIndex: 6000 entries, 0 to 5999\n", + "Columns: 129 entries, R1-PA1:VH to marker\n", + "dtypes: float64(112), int64(17)\n", + "memory usage: 5.9 MB\n", + "\n", + "[ TestingDataBinary.csv info ]\n", + "<class 'pandas.core.frame.DataFrame'>\n", + "RangeIndex: 100 entries, 0 to 99\n", + "Columns: 128 entries, R1-PA1:VH to snort_log4\n", + "dtypes: float64(112), int64(16)\n", + "memory usage: 100.1 KB\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "\n", + "mTrain = pd.read_csv(\"TrainingDataBinary.csv\")\n", + "mTest = pd.read_csv(\"TestingDataBinary.csv\")\n", + "\n", + "\n", + "print(\"\\n[ TrainingDataBinary.csv info ]\")\n", + "mTrain.info()\n", + "\n", + "print(\"\\n[ TestingDataBinary.csv info ]\")\n", + "mTest.info()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h1>1.1 Analysing the Data</h1>" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "R1-PA1:VH float64\n", + "R1-PM1:V float64\n", + "R1-PA2:VH float64\n", + "R1-PM2:V float64\n", + "R1-PA3:VH float64\n", + " ... \n", + "snort_log1 int64\n", + "snort_log2 int64\n", + "snort_log3 int64\n", + "snort_log4 int64\n", + "marker int64\n", + "Length: 129, dtype: object" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mTrain.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "marker\n", + "0 3000\n", + "1 3000\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mTrain['marker'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>R1-PA1:VH</th>\n", + " <th>R1-PM1:V</th>\n", + " <th>R1-PA2:VH</th>\n", + " <th>R1-PM2:V</th>\n", + " <th>R1-PA3:VH</th>\n", + " <th>R1-PM3:V</th>\n", + " <th>R1-PA4:IH</th>\n", + " <th>R1-PM4:I</th>\n", + " <th>R1-PA5:IH</th>\n", + " <th>R1-PM5:I</th>\n", + " <th>...</th>\n", + " <th>control_panel_log3</th>\n", + " <th>control_panel_log4</th>\n", + " <th>relay1_log</th>\n", + " <th>relay2_log</th>\n", + " <th>relay3_log</th>\n", + " <th>relay4_log</th>\n", + " <th>snort_log1</th>\n", + " <th>snort_log2</th>\n", + " <th>snort_log3</th>\n", + " <th>snort_log4</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>70.399324</td>\n", + " <td>127673.0908</td>\n", + " <td>-49.572308</td>\n", + " <td>127648.0176</td>\n", + " <td>-169.578319</td>\n", + " <td>127723.2374</td>\n", + " <td>65.689611</td>\n", + " <td>605.91099</td>\n", + " <td>-57.003571</td>\n", + " <td>626.78553</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>73.688102</td>\n", + " <td>130280.7109</td>\n", + " <td>-46.300719</td>\n", + " <td>130255.6377</td>\n", + " <td>-166.278082</td>\n", + " <td>130355.9307</td>\n", + " <td>71.831719</td>\n", + " <td>483.59351</td>\n", + " <td>-50.947407</td>\n", + " <td>500.98896</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>73.733939</td>\n", + " <td>130305.7842</td>\n", + " <td>-46.254883</td>\n", + " <td>130280.7109</td>\n", + " <td>-166.232245</td>\n", + " <td>130381.0040</td>\n", + " <td>71.808800</td>\n", + " <td>483.59351</td>\n", + " <td>-50.913030</td>\n", + " <td>500.98896</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>74.083443</td>\n", + " <td>130581.5902</td>\n", + " <td>-45.899649</td>\n", + " <td>130556.5169</td>\n", + " <td>-165.882741</td>\n", + " <td>130656.8100</td>\n", + " <td>72.152575</td>\n", + " <td>482.86107</td>\n", + " <td>-50.437475</td>\n", + " <td>499.15786</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>74.553268</td>\n", + " <td>131083.0556</td>\n", + " <td>-45.424094</td>\n", + " <td>131057.9823</td>\n", + " <td>-165.424375</td>\n", + " <td>131158.2754</td>\n", + " <td>72.118198</td>\n", + " <td>484.50906</td>\n", + " <td>-50.013486</td>\n", + " <td>497.69298</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5995</th>\n", + " <td>116.889120</td>\n", + " <td>131860.3269</td>\n", + " <td>-3.076783</td>\n", + " <td>131810.1804</td>\n", + " <td>-123.094253</td>\n", + " <td>131910.4735</td>\n", + " <td>114.780635</td>\n", + " <td>376.10794</td>\n", + " <td>-5.254023</td>\n", + " <td>374.82617</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5996</th>\n", + " <td>116.849013</td>\n", + " <td>131810.1804</td>\n", + " <td>-3.116890</td>\n", + " <td>131760.0339</td>\n", + " <td>-123.128630</td>\n", + " <td>131885.4002</td>\n", + " <td>114.769176</td>\n", + " <td>376.29105</td>\n", + " <td>-5.322778</td>\n", + " <td>374.82617</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5997</th>\n", + " <td>116.384917</td>\n", + " <td>131734.9606</td>\n", + " <td>-3.586716</td>\n", + " <td>131684.8140</td>\n", + " <td>-123.586996</td>\n", + " <td>131785.1071</td>\n", + " <td>114.299351</td>\n", + " <td>376.47416</td>\n", + " <td>-5.849899</td>\n", + " <td>374.82617</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5998</th>\n", + " <td>111.125164</td>\n", + " <td>130506.3704</td>\n", + " <td>-8.846468</td>\n", + " <td>130456.2238</td>\n", + " <td>-128.858208</td>\n", + " <td>130556.5169</td>\n", + " <td>106.667553</td>\n", + " <td>478.83265</td>\n", + " <td>-13.464508</td>\n", + " <td>477.73399</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5999</th>\n", + " <td>110.878793</td>\n", + " <td>130481.2971</td>\n", + " <td>-9.092840</td>\n", + " <td>130456.2238</td>\n", + " <td>-129.104580</td>\n", + " <td>130556.5169</td>\n", + " <td>106.392533</td>\n", + " <td>478.83265</td>\n", + " <td>-13.750987</td>\n", + " <td>477.91710</td>\n", + " <td>...</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>6000 rows × 128 columns</p>\n", + "</div>" + ], + "text/plain": [ + " R1-PA1:VH R1-PM1:V R1-PA2:VH R1-PM2:V R1-PA3:VH \n", + "0 70.399324 127673.0908 -49.572308 127648.0176 -169.578319 \\\n", + "1 73.688102 130280.7109 -46.300719 130255.6377 -166.278082 \n", + "2 73.733939 130305.7842 -46.254883 130280.7109 -166.232245 \n", + "3 74.083443 130581.5902 -45.899649 130556.5169 -165.882741 \n", + "4 74.553268 131083.0556 -45.424094 131057.9823 -165.424375 \n", + "... ... ... ... ... ... \n", + "5995 116.889120 131860.3269 -3.076783 131810.1804 -123.094253 \n", + "5996 116.849013 131810.1804 -3.116890 131760.0339 -123.128630 \n", + "5997 116.384917 131734.9606 -3.586716 131684.8140 -123.586996 \n", + "5998 111.125164 130506.3704 -8.846468 130456.2238 -128.858208 \n", + "5999 110.878793 130481.2971 -9.092840 130456.2238 -129.104580 \n", + "\n", + " R1-PM3:V R1-PA4:IH R1-PM4:I R1-PA5:IH R1-PM5:I ... \n", + "0 127723.2374 65.689611 605.91099 -57.003571 626.78553 ... \\\n", + "1 130355.9307 71.831719 483.59351 -50.947407 500.98896 ... \n", + "2 130381.0040 71.808800 483.59351 -50.913030 500.98896 ... \n", + "3 130656.8100 72.152575 482.86107 -50.437475 499.15786 ... \n", + "4 131158.2754 72.118198 484.50906 -50.013486 497.69298 ... \n", + "... ... ... ... ... ... ... \n", + "5995 131910.4735 114.780635 376.10794 -5.254023 374.82617 ... \n", + "5996 131885.4002 114.769176 376.29105 -5.322778 374.82617 ... \n", + "5997 131785.1071 114.299351 376.47416 -5.849899 374.82617 ... \n", + "5998 130556.5169 106.667553 478.83265 -13.464508 477.73399 ... \n", + "5999 130556.5169 106.392533 478.83265 -13.750987 477.91710 ... \n", + "\n", + " control_panel_log3 control_panel_log4 relay1_log relay2_log \n", + "0 0 0 0 0 \\\n", + "1 0 0 0 0 \n", + "2 0 0 0 0 \n", + "3 0 0 0 0 \n", + "4 0 0 0 0 \n", + "... ... ... ... ... \n", + "5995 0 0 0 0 \n", + "5996 0 0 0 0 \n", + "5997 0 0 0 0 \n", + "5998 0 0 0 0 \n", + "5999 0 0 0 0 \n", + "\n", + " relay3_log relay4_log snort_log1 snort_log2 snort_log3 snort_log4 \n", + "0 0 0 0 0 0 0 \n", + "1 0 0 0 0 0 0 \n", + "2 0 0 0 0 0 0 \n", + "3 0 0 0 0 0 0 \n", + "4 0 0 0 0 0 0 \n", + "... ... ... ... ... ... ... \n", + "5995 0 0 0 0 0 0 \n", + "5996 0 0 0 0 0 0 \n", + "5997 0 0 0 0 0 0 \n", + "5998 0 0 0 0 0 0 \n", + "5999 0 0 0 0 0 0 \n", + "\n", + "[6000 rows x 128 columns]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = mTrain.drop(columns = 'marker')\n", + "X" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "y = mTrain['marker']" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stratified Train-Test Split\n", + "The train-test split is stratified to ensure that the train and test samples from each class are almost the same percentage. This may be desirable for imbalanced number of samples as in this case. \n", + "\n", + "In such imbalanced datasets, the stratified K fold cross validation is used instead of the K-fold cross validation" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_train, X_test, y_train, y_test = train_test_split(X,y, random_state=1, test_size=0.2, stratify=y)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "marker\n", + "1 2400\n", + "0 2400\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_train.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "marker\n", + "1 600\n", + "0 600\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_test.value_counts()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h1>3. Choosing a Model: KNN , training, and evaluation</h1>" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.8766666666666667\n" + ] + } + ], + "source": [ + "#Import svm model\n", + "from sklearn.svm import SVC \n", + "from sklearn import svm\n", + "import sklearn.metrics as metrics\n", + "\n", + "#Create a svm Classifier\n", + "svm_clf = svm.SVC(C=10, kernel='linear', gamma = 0.1) # Linear Kernel\n", + "\n", + "#Train the model using the training sets\n", + "svm_clf.fit(X_train, y_train)\n", + "\n", + "#Predict the response for test dataset\n", + "y_pred = svm_clf.predict(X_test)\n", + "print(\"Accuracy:\", metrics.accuracy_score(y_test, y_pred))\n", + "\n", + "# y_pred = pd.DataFrame(y_pred, columns=['predicted marker'])\n", + "# print(svm_clf.score(y_test, y_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8766666666666667" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "svm_clf.score(X_test, y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Precision: 0.950199203187251\n", + "Recall: 0.795\n" + ] + } + ], + "source": [ + "print(\"Precision:\",metrics.precision_score(y_test, y_pred))\n", + "\n", + "# Model Recall: what percentage of positive tuples are labelled as such?\n", + "print(\"Recall:\",metrics.recall_score(y_test, y_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8679166666666667" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "svm_clf.score(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\60172\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\sklearn\\base.py:439: UserWarning: X does not have valid feature names, but SVC was fitted with feature names\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", + " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,\n", + " 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int64)" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_testpred = svm_clf.predict(mTest.values)\n", + "y_testpred" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[575, 25],\n", + " [123, 477]], dtype=int64)" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn.metrics import confusion_matrix\n", + "from sklearn.metrics import classification_report\n", + "from sklearn.metrics import ConfusionMatrixDisplay\n", + "confusion_matrix(y_test, y_pred)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.82 0.96 0.89 600\n", + " 1 0.95 0.80 0.87 600\n", + "\n", + " accuracy 0.88 1200\n", + " macro avg 0.89 0.88 0.88 1200\n", + "weighted avg 0.89 0.88 0.88 1200\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_test, y_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "predicted marker\n", + "0 53\n", + "1 47\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_testpred = pd.DataFrame(y_testpred, columns=['predicted marker'])\n", + "y_testpred.value_counts()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h1>4. Improving</h1>" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A grid search will be performed to find the optimal value of K. \n", + "\n", + "Afterwards, the stratified K fold cross validation will be used, followed by a confusion metric as an evaluation." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import cross_val_score\n", + "from sklearn.model_selection import GridSearchCV\n" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# param_grid = {'C': [0.001, 0.01, 0.1, 1, 10], 'gamma': [0.001, 0.01, 0.1, 1, 10],'kernel': ['linear']}\n", + "# grid = GridSearchCV(svm_clf,param_grid,refit=True,verbose=2)\n", + "# grid.fit(X_train,y_train)\n", + "# print(grid.best_estimator_)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "# print(grid.best_params_)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "# results = pd.DataFrame(grid.cv_results_)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://towardsdatascience.com/building-a-k-nearest-neighbors-k-nn-model-with-scikit-learn-51209555453a#:~:text=k%2DFold%20Cross%2DValidation,scored%20on%20the%20test%20set." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "# from sklearn.model_selection import StratifiedKFold\n", + "# score = cross_val_score(grid, X_train, y_train, cv=StratifiedKFold(n_splits=5, random_state=None, shuffle=False))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "# grid_predictions = grid.predict(X_test)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h1> 5. Metric Evaluation</h1>" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "# my_pred = grid.predict(X_test)\n", + "# my_pred" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "# score = grid.score(X_test, y_test)\n", + "# score" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Confusion Matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'my_pred' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[50], line 4\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39msklearn\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mmetrics\u001b[39;00m \u001b[39mimport\u001b[39;00m classification_report\n\u001b[0;32m 3\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39msklearn\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mmetrics\u001b[39;00m \u001b[39mimport\u001b[39;00m ConfusionMatrixDisplay\n\u001b[1;32m----> 4\u001b[0m confusion_matrix(y_test, my_pred)\n", + "\u001b[1;31mNameError\u001b[0m: name 'my_pred' is not defined" + ] + } + ], + "source": [ + "from sklearn.metrics import confusion_matrix\n", + "from sklearn.metrics import classification_report\n", + "from sklearn.metrics import ConfusionMatrixDisplay\n", + "confusion_matrix(y_test, my_pred)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.96 0.97 0.96 600\n", + " 1 0.81 0.82 0.81 300\n", + " 2 0.83 0.80 0.82 300\n", + "\n", + " accuracy 0.89 1200\n", + " macro avg 0.87 0.86 0.86 1200\n", + "weighted avg 0.89 0.89 0.89 1200\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_test, my_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfsAAAGwCAYAAACuFMx9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA9h0lEQVR4nO3de1yUdfr/8fcAcj4oGiAJHrJUPJaWsmVqmWT+TFd32/paUVltBpaaZm6eLW1trdYybcsVa3Ozw2ppbUWWp0RLzDI18oCBIlhrgKCcZu7fH65Ts2IxzsAwc7+ej8f9yPs4F1Fec12fz33fFsMwDAEAAJ/l5+kAAABA/SLZAwDg40j2AAD4OJI9AAA+jmQPAICPI9kDAODjSPYAAPi4AE8H4AqbzaaCggJFRETIYrF4OhwAgJMMw9CJEycUHx8vP7/6qz8rKipUVVXl8nUCAwMVHBzshogallcn+4KCAiUkJHg6DACAi/Lz89WqVat6uXZFRYXatg5X4TGry9eKi4tTbm6u1yV8r072ERERkqTvdrRRZDgjEr7ut5d09XQIANysRtXarPfsf5/Xh6qqKhUes+q77DaKjDj/XFF6wqbWPQ+pqqqKZN+QzrTuI8P9XPoFwjsEWJp4OgQA7vbfB7Y3xFBseIRF4RHn/zk2ee9wsVcnewAA6spq2GR14W0wVsPmvmAaGMkeAGAKNhmy6fyzvSvnehq9bwAAfByVPQDAFGyyyZVGvGtnexbJHgBgClbDkNU4/1a8K+d6Gm18AAB8HJU9AMAUzDxBj2QPADAFmwxZTZrsaeMDAODjqOwBAKZAGx8AAB/HbHwAAOCzqOwBAKZg++/iyvneimQPADAFq4uz8V0519NI9gAAU7AacvGtd+6LpaExZg8AgI+jsgcAmAJj9gAA+DibLLLK4tL53oo2PgAAPo7KHgBgCjbj9OLK+d6KZA8AMAWri218V871NNr4AAD4OCp7AIApmLmyJ9kDAEzBZlhkM1yYje/CuZ5GGx8AAB9HZQ8AMAXa+AAA+Dir/GR1oaFtdWMsDY1kDwAwBcPFMXuDMXsAANBYUdkDAEyBMXsAAHyc1fCT1XBhzN6LH5dLGx8AAB9HZQ8AMAWbLLK5UOPa5L2lPckeAGAKZh6zp40PAICPo7IHAJiC6xP0aOMDANConR6zd+FFOLTxAQBAY0VlDwAwBZuLz8ZnNj4AAI0cY/YAAPg4m/xMe589Y/YAAPg4KnsAgClYDYusLrym1pVzPY1kDwAwBauLE/SstPEBAEBjRbIHAJiCzfBzeXHGzJkzZbFYHJaOHTva91dUVCgtLU3NmzdXeHi4Ro4cqaKiIodr5OXlaciQIQoNDVVMTIwmTZqkmpoap3922vgAAFPwRBu/c+fO+uijj+zrAQE/pd3x48fr3Xff1RtvvKGoqCilp6drxIgR+vTTT09/ntWqIUOGKC4uTlu2bNHRo0d1++23q0mTJpo7d65TcZDsAQCoJwEBAYqLiztre0lJiZYuXaoVK1bommuukSQtW7ZMnTp10tatW9WnTx99+OGH2rNnjz766CPFxsaqR48emjNnjiZPnqyZM2cqMDCwznHQxgcAmIJNP83IP5/F9t/rlJaWOiyVlZXn/Mx9+/YpPj5e7dq106hRo5SXlydJys7OVnV1tQYOHGg/tmPHjkpMTFRWVpYkKSsrS127dlVsbKz9mJSUFJWWlmr37t1O/ewkewCAKZx5qI4riyQlJCQoKirKvsybN6/Wz+vdu7cyMjL0/vvva/HixcrNzVXfvn114sQJFRYWKjAwUE2bNnU4JzY2VoWFhZKkwsJCh0R/Zv+Zfc6gjQ8AgBPy8/MVGRlpXw8KCqr1uMGDB9v/3K1bN/Xu3VutW7fW66+/rpCQkHqP8+eo7AEApnDm2fiuLJIUGRnpsJwr2f+vpk2b6pJLLtH+/fsVFxenqqoqFRcXOxxTVFRkH+OPi4s7a3b+mfXa5gH8EpI9AMAUzrzP3pXFFWVlZTpw4IBatmypnj17qkmTJlq3bp19f05OjvLy8pScnCxJSk5O1q5du3Ts2DH7MZmZmYqMjFRSUpJTn00bHwBgCq6/9c65cydOnKihQ4eqdevWKigo0IwZM+Tv769bbrlFUVFRGj16tCZMmKDo6GhFRkZq7NixSk5OVp8+fSRJgwYNUlJSkm677TbNnz9fhYWFmjp1qtLS0urcTTiDZN9IvPKXOP3jKce2TKuLKrR00zeSpOPHAvTSnHjt2Bihk2V+SrioUjc/WKS+Q0rsx5f+6K/np16obZlRsvhJV91QrDFzjigkzCY0bl16l+n393+vi7ueVPO4Gs28q42y3o+y779ycLGG3P4fXdz1lCKjrRpz3SU6uLthx/xQf0LCrEp9uFC/GVyips1rdGB3iBZPu1Dffhnq6dDggsOHD+uWW27Rf/7zH11wwQW66qqrtHXrVl1wwQWSpKefflp+fn4aOXKkKisrlZKSoueff95+vr+/v9auXasxY8YoOTlZYWFhSk1N1ezZs52OpVEk+0WLFunJJ59UYWGhunfvrmeffVZXXHGFp8NqcK07nNITKw/Y1/39f3qAw5MPJKqs1F8zM3IVFV2jT1Y109w/ttGz//5W7buekiT9Ob21jhc10bzXDqim2qIFExL1zKQETXn+uwb/WeCc4FCbDu4O1gf/jNaMvx+qdf/uz8K0cU1Tjf/L4YYPEPVq/IJ8telQofljE3W8qImuGfmjnlh5QPf076j/FDbxdHg+w/WH6jh37muvvfaL+4ODg7Vo0SItWrTonMe0bt1a7733nlOfWxuPj9mvXLlSEyZM0IwZM7Rjxw51795dKSkpDmMUZuHvL0XH1NiXqOZW+74928M07K4f1PHSk2rZukr/N65IYVFW7fvqdHWXty9I2z+J1PgFeep42Ul16V2u+x87rA1vN9V/ChvFdzr8gu2fRGr5/Jba8rNq/ufWvRWtV5+O0xcbIxo4MtS3wGCbrrqhRC89Fq+vt4Wr4FCQ/rEgTgWHgvT/bv/B0+H5FJthcXnxVh5P9k899ZTuuece3XnnnUpKStKSJUsUGhqqv//9754OrcEdyQ3ULZd2VmqfTnoiLVHHDv/0jT6pV7k2vNNUpT/6y2aT1q9uqqoKi7r9pkyStHd7mMKjanRJ91P2cy7re0IWP+mbL8Ia/GcBUDf+/ob8A6SqSsdEUllhUecryj0UFXyNR0u+qqoqZWdna8qUKfZtfn5+GjhwoP0JQj9XWVnp8KSi0tLSBomzIXS8rFwTnzmlVhdV6vixJvrHgjg99NuL9cIn3yg03KZHX/hOc+9rrd937ir/AENBITbNWHpIF7atkiQd/z5ATZs7vhzBP0CKaFqj48eo7IHG6lS5v/ZsD9X/jStS3r5gFX8foP7Di9Wp50kVHHJuEhZ+mc3FNr7N8/XxefNo5D/88IOsVmutTwiq7elA8+bNc3hqUUJCQkOFWu8uv+aErh5aonZJFerV/4Qe+8dBlZX6a+M7TSVJy+fHqazUX0+s3K9n/52jkfce0+P3tVHu3mDPBg7AZfPHJspikf75xR6tPfSVho/+XutXN5XB3Fq3aui33jUmXlXyTZkyRRMmTLCvl5aW+lTC/7nwKKtatatUwaEgFRwK1DvLLtALn3yjNh0qJEkXda7Qrm3heiejhR7882FFX1Cj4v84/jqtNdKJ4gBFxzj/OkQADefod0GaNLK9gkKsCouw6fixJvrTkkM6+l3dX3QC/BKPfk1p0aKF/P39a31CUG1PBwoKCjrryUW+6lS5nwq+C1R0TLUqT53+Nfn5Ob5e0d/fsH/z79SrXGUlAfYJe5K0c3OEDJvU8VLG/QBvUHnKX8ePNVF4VI169juhrA9qn7CJ82OVxeXFW3k02QcGBqpnz54OTxCy2Wxat26d/QlCZvG3WfH6KitMhfmB2v15qGbd1Vb+flL/3/6ohPYVim9bqb8+nKBvvghVwaFAvbnkAu3YGKHfXH/6PvvEiyvVa0Cpnpl4+pjdn4Vp0dQL1W9YsZrHUdk3dsGhVrXrfErtOp+eYBmXUKV2nU/pggtPz8mIaFqjdp1PKfGS052dhIsq1K7zKTW7oNpjMcN9evYrVa/+pYpNqNRlV5/Q/DcPKH9/sD5cGe3p0HwKbXwPmjBhglJTU9WrVy9dccUVeuaZZ1ReXq4777zT06E1qB+ONtG8+9voxI/+impeo86Xl+uZtd+q6X9vv3vslQNaOjdeM1Lb6lS5n+LbVmniX/N0xbUn7NeY/Nx3WvRoKz1y00X2h+rc/9gRT/1IcMIl3U/pybd+esbCfbMKJEkfrmymBeMT1WdQqSY+k2/f/6clp1+T+cqCWP1jgXPPyEbjExZp051TjqpFy2qdKPbXp+9FadkTLWWt8d5KEo2LxTAM49cPq1/PPfec/aE6PXr00MKFC9W7d+9fPa+0tFRRUVH68dt2iozw3m9cqJuU+B6eDgGAm9UY1Vqvt1VSUlJvQ7NncsX0bQMVHH7+DymqKKvW7N4f1Wus9cXjlb0kpaenKz093dNhAAB8mKuteNr4AAA0cg39IpzGxHsjBwAAdUJlDwAwBcPFd9IbXnzrHckeAGAKtPEBAIDPorIHAJiCq6+p9eZX3JLsAQCmYHXxrXeunOtp3hs5AACoEyp7AIAp0MYHAMDH2eQnmwsNbVfO9TTvjRwAANQJlT0AwBSshkVWF1rxrpzraSR7AIApMGYPAICPM1x8653BE/QAAEBjRWUPADAFqyyyuvAyG1fO9TSSPQDAFGyGa+PuNsONwTQw2vgAAPg4KnsAgCnYXJyg58q5nkayBwCYgk0W2VwYd3flXE/z3q8pAACgTqjsAQCmwBP0AADwcWYes/feyAEAQJ1Q2QMATMEmF5+N78UT9Ej2AABTMFycjW+Q7AEAaNzM/NY7xuwBAPBxVPYAAFMw82x8kj0AwBRo4wMAAJ9FZQ8AMAUzPxufZA8AMAXa+AAAwGdR2QMATMHMlT3JHgBgCmZO9rTxAQDwcVT2AABTMHNlT7IHAJiCIddunzPcF0qDI9kDAEzBzJU9Y/YAAPg4KnsAgCmYubIn2QMATMHMyZ42PgAAPo5kDwAwhTOVvSvL+XriiSdksVg0btw4+7aKigqlpaWpefPmCg8P18iRI1VUVORwXl5enoYMGaLQ0FDFxMRo0qRJqqmpcfrzSfYAAFMwDIvLy/n4/PPP9cILL6hbt24O28ePH681a9bojTfe0IYNG1RQUKARI0bY91utVg0ZMkRVVVXasmWLli9froyMDE2fPt3pGEj2AADUk7KyMo0aNUovvviimjVrZt9eUlKipUuX6qmnntI111yjnj17atmyZdqyZYu2bt0qSfrwww+1Z88e/eMf/1CPHj00ePBgzZkzR4sWLVJVVZVTcZDsAQCmcOZ99q4sklRaWuqwVFZWnvMz09LSNGTIEA0cONBhe3Z2tqqrqx22d+zYUYmJicrKypIkZWVlqWvXroqNjbUfk5KSotLSUu3evdupn51kDwAwBXeN2SckJCgqKsq+zJs3r9bPe+2117Rjx45a9xcWFiowMFBNmzZ12B4bG6vCwkL7MT9P9Gf2n9nnDG69AwDACfn5+YqMjLSvBwUF1XrMgw8+qMzMTAUHBzdkeLWisgcAmIK7JuhFRkY6LLUl++zsbB07dkyXXXaZAgICFBAQoA0bNmjhwoUKCAhQbGysqqqqVFxc7HBeUVGR4uLiJElxcXFnzc4/s37mmLoi2QMATKEhb7279tprtWvXLu3cudO+9OrVS6NGjbL/uUmTJlq3bp39nJycHOXl5Sk5OVmSlJycrF27dunYsWP2YzIzMxUZGamkpCSnfnba+AAAU3Dl9rkz59dVRESEunTp4rAtLCxMzZs3t28fPXq0JkyYoOjoaEVGRmrs2LFKTk5Wnz59JEmDBg1SUlKSbrvtNs2fP1+FhYWaOnWq0tLSau0m/BKSPQAAHvD000/Lz89PI0eOVGVlpVJSUvT888/b9/v7+2vt2rUaM2aMkpOTFRYWptTUVM2ePdvpz7IYhuG1r+gtLS1VVFSUBgSMVICliafDQT3Ln3SFp0NAA2r9t288HQIaQI2tSuuOZ6ikpMRh0ps7nckVl705Qf5hzlXEP2ctr9SO3z1Vr7HWFyp7AIApGJJcKW+9tjIWE/QAAPB5VPYAAFOwySKLXHjFrQvnehrJHgBgCg05G7+xoY0PAICPo7IHAJiCzbDI4kJ17sr77D2NZA8AMAXDcHE2vhdPx6eNDwCAj6OyBwCYgpkn6JHsAQCmQLIHAMDHmXmCHmP2AAD4OCp7AIApmHk2PskeAGAKp5O9K2P2bgymgdHGBwDAx1HZAwBMgdn4AAD4OEOuvZPei7v4tPEBAPB1VPYAAFOgjQ8AgK8zcR+fZA8AMAcXK3t5cWXPmD0AAD6Oyh4AYAo8QQ8AAB9n5gl6tPEBAPBxVPYAAHMwLK5NsvPiyp5kDwAwBTOP2dPGBwDAx1HZAwDMgYfqAADg28w8G79Oyf6dd96p8wVvvPHG8w4GAAC4X52S/fDhw+t0MYvFIqvV6ko8AADUHy9uxbuiTsneZrPVdxwAANQrM7fxXZqNX1FR4a44AACoX4YbFi/ldLK3Wq2aM2eOLrzwQoWHh+vgwYOSpGnTpmnp0qVuDxAAALjG6WT/+OOPKyMjQ/Pnz1dgYKB9e5cuXfTSSy+5NTgAANzH4obFOzmd7F9++WX97W9/06hRo+Tv72/f3r17d33zzTduDQ4AALehjV93R44cUfv27c/abrPZVF1d7ZagAACA+zid7JOSkrRp06aztr/55pu69NJL3RIUAABuZ+LK3ukn6E2fPl2pqak6cuSIbDab/vWvfyknJ0cvv/yy1q5dWx8xAgDgOhO/9c7pyn7YsGFas2aNPvroI4WFhWn69Onau3ev1qxZo+uuu64+YgQAAC44r2fj9+3bV5mZme6OBQCAemPmV9ye94twtm/frr1790o6PY7fs2dPtwUFAIDb8da7ujt8+LBuueUWffrpp2ratKkkqbi4WL/5zW/02muvqVWrVu6OEQAAuMDpMfu7775b1dXV2rt3r44fP67jx49r7969stlsuvvuu+sjRgAAXHdmgp4ri5dyurLfsGGDtmzZog4dOti3dejQQc8++6z69u3r1uAAAHAXi3F6ceV8b+V0sk9ISKj14TlWq1Xx8fFuCQoAALcz8Zi90238J598UmPHjtX27dvt27Zv364HH3xQf/nLX9waHAAAcF2dKvtmzZrJYvlprKK8vFy9e/dWQMDp02tqahQQEKC77rpLw4cPr5dAAQBwiYkfqlOnZP/MM8/UcxgAANQzE7fx65TsU1NT6zsOAABQT877oTqSVFFRoaqqKodtkZGRLgUEAEC9MHFl7/QEvfLycqWnpysmJkZhYWFq1qyZwwIAQKNk4rfeOZ3sH374YX388cdavHixgoKC9NJLL2nWrFmKj4/Xyy+/XB8xAgAAFzid7NesWaPnn39eI0eOVEBAgPr27aupU6dq7ty5evXVV+sjRgAAXNfAT9BbvHixunXrpsjISEVGRio5OVn//ve/7fsrKiqUlpam5s2bKzw8XCNHjlRRUZHDNfLy8jRkyBCFhoYqJiZGkyZNUk1NjdM/utPJ/vjx42rXrp2k0+Pzx48flyRdddVV2rhxo9MBAADQEM48Qc+VxRmtWrXSE088oezsbG3fvl3XXHONhg0bpt27d0uSxo8frzVr1uiNN97Qhg0bVFBQoBEjRtjPt1qtGjJkiKqqqrRlyxYtX75cGRkZmj59utM/u9MT9Nq1a6fc3FwlJiaqY8eOev3113XFFVdozZo19hfjwHVdrjih391XpIu7nlTz2GrNuvsiZX3Y1OGYhPanNHrKEXXtfUL+AVLevmDN+eNF+r4g0DNBo07u7rlD1110UG2bFauixl87C+P01Kd9dKi4tjkvhpbc+K76ts7X2Hev18cH29r37B67+KyjJ74/UP/ed3E9Rg9X3HDTEQ35wxHFxldIkr47EKZ/Lmmj7ZubS5LiWp3S3RP3q/OlJWoSaFP2p9FaPO8SFf+H/6cbk9LSUof1oKAgBQUFnXXc0KFDHdYff/xxLV68WFu3blWrVq20dOlSrVixQtdcc40kadmyZerUqZO2bt2qPn366MMPP9SePXv00UcfKTY2Vj169NCcOXM0efJkzZw5U4GBdf/vwunK/s4779SXX34pSXrkkUe0aNEiBQcHa/z48Zo0aZJT19q4caOGDh2q+Ph4WSwWrV692tlwfFZwqE25e0K0aGpCrftbtq7UgrdylH8gWA//oYPGpCRpxcKWqqr03oc+mMXlFxbon1910S1vjNA9bw9VgJ9NLw5bq5CAsx9DfXuPr2T8Quvw0cwB6rc01b6s+9mXATQ+PxQFadkzF+mBP/TSgzf30pfbmmnawl1KvKhcQSFWPf63nTIMacrdPTTx9ssU0MTQjGe/ksWbH8remLhpgl5CQoKioqLsy7x58371o61Wq1577TWVl5crOTlZ2dnZqq6u1sCBA+3HdOzYUYmJicrKypIkZWVlqWvXroqNjbUfk5KSotLSUnt3oK6cruzHjx9v//PAgQP1zTffKDs7W+3bt1e3bt2culZ5ebm6d++uu+66y6F1AWn7+ihtXx91zv2pk47o80+itHTuT68UPvrd2d8s0fj88Z3/57D+aOY12nxPhpJivld2wU/vl+jY4gelXvql/rDyd9owenmt1yqtCtIPJ0PrNV64z2cbWjisv/xsOw35wxF17Fai5jGViomvUPrvL9ep8tN/NS94tJNe/3STuvf+UTu3RnsiZNQiPz/f4Tbz2qr6M3bt2qXk5GRVVFQoPDxcq1atUlJSknbu3KnAwMCzOuKxsbEqLCyUJBUWFjok+jP7z+xzhkv32UtS69at1bp16/M6d/DgwRo8eLCrIZiOxWLoimtK9OaSOD3+yj5d1PmkCvMDtXJRy7Na/Wj8IoJOP6uipOKnvzCCA6o1P+UjPba+7y8m86n9Nmn2Net1uDRSK3cladXejpLo7ngDPz9DVw06puAQq/Z+GaWWCackw6Lqqp8arlWVfjJsFnW+tIRk7wYWufjWu//+88yEu7ro0KGDdu7cqZKSEr355ptKTU3Vhg0bzj+I81SnZL9w4cI6X/CBBx4472B+TWVlpSorK+3r/ztuYhZNW9QoNNymm+4v1PIn47V03oXq1b9U0/52QJP/cIl2bYvwdIioI4sMTe77qXYUxGn/8eb27ZP7btEXR2P1Se652/LPbr1c2w5fqFPVAboy8bCm9d+k0CbVevUr5zpsaFhtLi7Tgn/sUGCgTadO+mvOuK7KPximkh+bqOKUn+4af0DLF7aTLNKd4w7IP8BQswuqfv3CaJQCAwPVvn17SVLPnj31+eef669//av+8Ic/qKqqSsXFxQ7VfVFRkeLi4iRJcXFx+uyzzxyud2a2/plj6qpOyf7pp5+u08UsFku9Jvt58+Zp1qxZ9XZ9b2HxO/3VNOvDKK1aerqlc3BPqJJ6lmnIrd+T7L3I1P4bdXHz47rtzeH2bQPa5qp3qyP63Wu//8Vzl3zey/7nb364QCFNqnXnZTtJ9o3c4dxQpf+ul8IirLrqumN66LG9evjOS5V/MExzH+qi9Gk5unHUYRk2izb8O0b79oTLsHk6ah/RCF6EY7PZVFlZqZ49e6pJkyZat26dRo4cKUnKyclRXl6ekpOTJUnJycl6/PHHdezYMcXExEiSMjMzFRkZqaSkJKc+t07JPjc316mL1pcpU6ZowoQJ9vXS0lIlJNQ+gc2XlR4PUE21lLcvxGF73v5gdb68zENRwVmP9tukfm2+U+q/hquoPNy+vXerI0qIKlHWvUsdjn9m8AfKLmipO1cNq/V6XxXFaswV2WriZ1W1zb9eY8f5q6nx09H800Mz+/dE6OIuJzTs1sN6bnYHfZEVrdE3JCuyaZWsVovKTzTRPz75VIWHQ37lqqiTBn5c7pQpUzR48GAlJibqxIkTWrFihdavX68PPvhAUVFRGj16tCZMmKDo6GhFRkZq7NixSk5OVp8+fSRJgwYNUlJSkm677TbNnz9fhYWFmjp1qtLS0n5xnkBtXB6zb0jnur3BbGqq/fTtl2FqdVGFw/YL21bq2GFu0Wn8DD3ab7OubZerO/51o46UOo79vZR9md7c3clh29ujXtefN/1G6w+1OedVO7b4QSUVQSR6L+NnMdQk0LF0Ly0+/f9x9yt+VNPoKm1d36K2U9HIHTt2TLfffruOHj2qqKgodevWTR988IGuu+46Sae75n5+fho5cqQqKyuVkpKi559/3n6+v7+/1q5dqzFjxig5OVlhYWFKTU3V7NmznY7Fq5K9mQSHWhXf5qf5CXEJlWqXdFInigP0fUGg3nwhVlMW5WrXtnB9uSVCvfqXqs/AYj38hw4ejBp1Ma3fJt3QYZ/Grh2sk9WBahF6UpJ0ojJQldYA/XAytNZJeUfLIuxfDPq3OaTmoSf1ZWGsqqwBSk7I1z29dijji+4N+rPAOXc8eEDbNzfXsaNBCg2zqv8NRep6ebGm3Xf693bd8KPKOxiqkuOB6tSjRH+cvE+rX0nQkUPcceEWDVzZL1269Bf3BwcHa9GiRVq0aNE5j2ndurXee+895z64Fh5N9mVlZdq/f799PTc3Vzt37lR0dLQSExM9GJnnXdLtpOa//q19/Y8zDkuSMt9orgUPtdGWD5rp2T9Z9Ye0Qo2Zla/DB04/UGf35+HnuiQaiZu7nb4/dvnItx22P5o5QKu/6Vina9TY/HRLt92a3HeLLDKUVxKl+Zt+ozd3OzeOh4YVFV2thx7fq+gLKlV+IkC5+8I17b7u+iLr9Ez7C9ucVOqDBxURVa1jR4K18sXWWvWy+YYq68v5PAXvf8/3VhbDMDwW/vr16zVgwICztqempiojI+NXzy8tLVVUVJQGBIxUgKVJPUSIxiR/0hWeDgENqPXfvvF0CGgANbYqrTueoZKSknp7RfqZXNHm8cflFxx83texVVTo0KOP1mus9cWjlX3//v3lwe8aAAAz4X32ztm0aZNuvfVWJScn68iRI5KkV155RZs3b3ZrcAAAuA3vs6+7t956SykpKQoJCdEXX3xhf8hNSUmJ5s6d6/YAAQCAa5xO9o899piWLFmiF198UU2a/DROfuWVV2rHjh1uDQ4AAHdp6FfcNiZOj9nn5OTo6quvPmt7VFSUiouL3RETAADu1wieoOcpTlf2cXFxDrfLnbF582a1a9fOLUEBAOB2jNnX3T333KMHH3xQ27Ztk8ViUUFBgV599VVNnDhRY8aMqY8YAQCAC5xu4z/yyCOy2Wy69tprdfLkSV199dUKCgrSxIkTNXbs2PqIEQAAl5n5oTpOJ3uLxaJHH31UkyZN0v79+1VWVqakpCSFh/PkNgBAI2bi++zP+6E6gYGBTr9iDwAANDynk/2AAQNksZx7RuLHH3/sUkAAANQLV2+fM1Nl36NHD4f16upq7dy5U19//bVSU1PdFRcAAO5FG7/unn766Vq3z5w5U2VlZS4HBAAA3Ou8no1fm1tvvVV///vf3XU5AADcy8T32bvtrXdZWVkKduHVgQAA1CduvXPCiBEjHNYNw9DRo0e1fft2TZs2zW2BAQAA93A62UdFRTms+/n5qUOHDpo9e7YGDRrktsAAAIB7OJXsrVar7rzzTnXt2lXNmjWrr5gAAHA/E8/Gd2qCnr+/vwYNGsTb7QAAXsfMr7h1ejZ+ly5ddPDgwfqIBQAA1AOnk/1jjz2miRMnau3atTp69KhKS0sdFgAAGi0T3nYnOTFmP3v2bD300EO64YYbJEk33nijw2NzDcOQxWKR1Wp1f5QAALjKxGP2dU72s2bN0n333adPPvmkPuMBAABuVudkbxinv9L069ev3oIBAKC+8FCdOvqlt90BANCo0cavm0suueRXE/7x48ddCggAALiXU8l+1qxZZz1BDwAAb0Abv45uvvlmxcTE1FcsAADUHxO38et8nz3j9QAAeCenZ+MDAOCVTFzZ1znZ22y2+owDAIB6xZg9AAC+zsSVvdPPxgcAAN6Fyh4AYA4mruxJ9gAAUzDzmD1tfAAAfByVPQDAHGjjAwDg22jjAwAAn0VlDwAwB9r4AAD4OBMne9r4AAD4OCp7AIApWP67uHK+tyLZAwDMwcRtfJI9AMAUuPUOAAD4LCp7AIA50MYHAMAEvDhhu4I2PgAAPo7KHgBgCmaeoEeyBwCYg4nH7GnjAwBQD+bNm6fLL79cERERiomJ0fDhw5WTk+NwTEVFhdLS0tS8eXOFh4dr5MiRKioqcjgmLy9PQ4YMUWhoqGJiYjRp0iTV1NQ4FQvJHgBgCmfa+K4sztiwYYPS0tK0detWZWZmqrq6WoMGDVJ5ebn9mPHjx2vNmjV64403tGHDBhUUFGjEiBH2/VarVUOGDFFVVZW2bNmi5cuXKyMjQ9OnT3cqFtr4AABzaOA2/vvvv++wnpGRoZiYGGVnZ+vqq69WSUmJli5dqhUrVuiaa66RJC1btkydOnXS1q1b1adPH3344Yfas2ePPvroI8XGxqpHjx6aM2eOJk+erJkzZyowMLBOsVDZAwDghNLSUoelsrKyTueVlJRIkqKjoyVJ2dnZqq6u1sCBA+3HdOzYUYmJicrKypIkZWVlqWvXroqNjbUfk5KSotLSUu3evbvOMftEZW/U1MiwePMrClAXbZYd8HQIaECH7u3o6RDQAKyVFdKChvksd83GT0hIcNg+Y8YMzZw58xfPtdlsGjdunK688kp16dJFklRYWKjAwEA1bdrU4djY2FgVFhbaj/l5oj+z/8y+uvKJZA8AwK9yUxs/Pz9fkZGR9s1BQUG/empaWpq+/vprbd682YUAzh9tfACAORhuWCRFRkY6LL+W7NPT07V27Vp98sknatWqlX17XFycqqqqVFxc7HB8UVGR4uLi7Mf87+z8M+tnjqkLkj0AAPXAMAylp6dr1apV+vjjj9W2bVuH/T179lSTJk20bt06+7acnBzl5eUpOTlZkpScnKxdu3bp2LFj9mMyMzMVGRmppKSkOsdCGx8AYAoN/QS9tLQ0rVixQm+//bYiIiLsY+xRUVEKCQlRVFSURo8erQkTJig6OlqRkZEaO3askpOT1adPH0nSoEGDlJSUpNtuu03z589XYWGhpk6dqrS0tDoNH5xBsgcAmEMD33q3ePFiSVL//v0dti9btkx33HGHJOnpp5+Wn5+fRo4cqcrKSqWkpOj555+3H+vv76+1a9dqzJgxSk5OVlhYmFJTUzV79mynYiHZAwBQDwzj178dBAcHa9GiRVq0aNE5j2ndurXee+89l2Ih2QMATMFiGLLUIQH/0vneimQPADAHXoQDAAB8FZU9AMAUeJ89AAC+jjY+AADwVVT2AABToI0PAICvM3Ebn2QPADAFM1f2jNkDAODjqOwBAOZAGx8AAN/nza14V9DGBwDAx1HZAwDMwTBOL66c76VI9gAAU2A2PgAA8FlU9gAAc2A2PgAAvs1iO724cr63oo0PAICPo7IHAJgDbXwAAHybmWfjk+wBAOZg4vvsGbMHAMDHUdkDAEyBNj4AAL7OxBP0aOMDAODjqOwBAKZAGx8AAF/HbHwAAOCrqOwBAKZAGx8AAF/HbHwAAOCrqOwBAKZAGx8AAF9nM04vrpzvpUj2AABzYMweAAD4Kip7AIApWOTimL3bIml4JHsAgDnwBD0AAOCrqOwBAKbArXcAAPg6ZuMDAABfRWUPADAFi2HI4sIkO1fO9TSSPQDAHGz/XVw530vRxgcAwMdR2QMATIE2PgAAvs7Es/FJ9gAAc+AJegAAwFdR2QMATIEn6KHR6dK7TL+//3td3PWkmsfVaOZdbZT1fpR9/5WDizXk9v/o4q6nFBlt1ZjrLtHB3SEejBju8vs7cnXHA/u0ekWiXvxLR0lSs+aVumvct7q0938UElajw4fCtHJpO235ONbD0eKX3N1zh6676KDaNitWRY2/dhbG6alP++hQcbNajja05MZ31bd1vsa+e70+PtjWvmfK1Zt1acujurj5cR083kwjX7up4X4IX0IbH41NcKhNB3cH67k/tTrn/t2fhWnp3JYNHBnq08VJJbp+ZL4OfhvusH3C7K91YetyzR5/qdJu+o22fByrR/78pdp1KPVQpKiLyy8s0D+/6qJb3hihe94eqgA/m14ctlYhAdVnHXt7j69kGOd+ieqqPZ30733t6zNc+DCPJvt58+bp8ssvV0REhGJiYjR8+HDl5OR4MqRGY/snkVo+v6W2/Kya/7l1b0Xr1afj9MXGiAaODPUlOKRGkx7fpWfndFZZaROHfZ26F2vNykR9uztKhUdCtXJpO5WfaKL2nUj2jdkf3/l/Wv1NRx04Hq2cH1ro0cxrFB9ZpqSY7x2O69jiB6Ve+qWmrRtQ63XmbbxK/9zVRYdLIhsibJ9lsbm+eCuPJvsNGzYoLS1NW7duVWZmpqqrqzVo0CCVl5d7MizAI8Y8slefb26hnZ81P2vf3i+b6upBhQqPrJbFYujqQUcVGGTVruxoD0SK8xURVCVJKqkIsm8LDqjW/JSP9Nj6vvrhZKinQjOHM218VxYv5dFk//777+uOO+5Q586d1b17d2VkZCgvL0/Z2dm1Hl9ZWanS0lKHBfAFVw86qvYdTyjj2Ytr3f/E5G7yDzC0cv0nWr31I6U/ulePPdRDR/NJDt7CIkOT+36qHQVx2n/8py90k/tu0RdHY/VJbttfOBveaOPGjRo6dKji4+NlsVi0evVqh/2GYWj69Olq2bKlQkJCNHDgQO3bt8/hmOPHj2vUqFGKjIxU06ZNNXr0aJWVlTkdS6Masy8pKZEkRUfXXq3MmzdPUVFR9iUhIaEhwwPqRYvYCt07KUdPTu2q6ir/Wo+57f79Cg+v1p/u66lxt/bRqldb65E/f6XW7U80cLQ4X1P7b9TFzY9r4vvX2bcNaJur3q2O6M+brvJgZCZiuGFxQnl5ubp3765FixbVun/+/PlauHChlixZom3btiksLEwpKSmqqKiwHzNq1Cjt3r1bmZmZWrt2rTZu3Kh7773XuUDUiGbj22w2jRs3TldeeaW6dOlS6zFTpkzRhAkT7OulpaUkfHi99p1K1ax5lRa+utW+zT/AUJfLftTQm/J174grNfTmfI353W+Ud/D0xL3cfRHqcumP+n835WvR3CRPhY46erTfJvVr851S/zVcReU/Tb7s3eqIEqJKlHXvUofjnxn8gbILWurOVcMaOlSf1tCPyx08eLAGDx5c6z7DMPTMM89o6tSpGjbs9O/55ZdfVmxsrFavXq2bb75Ze/fu1fvvv6/PP/9cvXr1kiQ9++yzuuGGG/SXv/xF8fHxdY6l0ST7tLQ0ff3119q8efM5jwkKClJQUNA59wPe6MvPonX/75Mdto2buVuHD4XpzYw2Cgq2Sjp7uNBqs8jPz3vHEM3B0KP9Nuvadrm641836kip4wS7l7Iv05u7Ozlse3vU6/rzpt9o/aE2DRgnnPG/Q8jnk5tyc3NVWFiogQMH2rdFRUWpd+/eysrK0s0336ysrCw1bdrUnuglaeDAgfLz89O2bdv029/+ts6f1yiSfXp6ur090apV7beamU1wqFXxbavs63EJVWrX+ZROFPvr+yOBimhaowsurFbz2NO38CRcdLrt8+OxAP34fZNar4nG6dTJAH13wPGuiopT/iotaaLvDkTIP8CmI3mhSn90j5Y+3UGlJU2U3P+YLu39H8168FIPRY26mNZvk27osE9j1w7WyepAtQg9KUk6URmoSmuAfjgZWuukvKNlEQ5fDBKjShTapFotQk8qKKBGHVv8IEk6cLyZqm21D/2gFm66z/5/O8ozZszQzJkznbpUYWGhJCk21vFZGbGxsfZ9hYWFiomJcdgfEBCg6Oho+zF15dFkbxiGxo4dq1WrVmn9+vVq25YJKmdc0v2UnnzrgH39vlkFkqQPVzbTgvGJ6jOoVBOfybfv/9OSPEnSKwti9Y8FcQ0bLOqVtcZPM8deqjse2Kfpz3yhkNAaFeSH6qkZXbT90ws8HR5+wc3ddkuSlo9822H7o5kDtPqbjnW+zqxr1uuKVgX29bdueUOSdF3GKBWc4Ha8OjPk2jvp//s9IT8/X5GRP/1794aOs0eTfVpamlasWKG3335bERER9m8qUVFRCgkx99PgvsoKV0p893Puz3w9Wpmvc9uVr5py7+UO6wX5YZo7qYdngsF56/zsGLecw9i9e7hrzD4yMtIh2Z+PuLjTRVlRUZFatvzp4WhFRUXq0aOH/Zhjx445nFdTU6Pjx4/bz68rj87GX7x4sUpKStS/f3+1bNnSvqxcudKTYQEAUK/atm2ruLg4rVu3zr6ttLRU27ZtU3Ly6Tk8ycnJKi4udrgd/eOPP5bNZlPv3r2d+jyPt/EBAGgQhlwcs3fu8LKyMu3fv9++npubq507dyo6OlqJiYkaN26cHnvsMV188cVq27atpk2bpvj4eA0fPlyS1KlTJ11//fW65557tGTJElVXVys9PV0333yzUzPxpUYyQQ8AgHrXwC/C2b59uwYM+OkRyGduHU9NTVVGRoYefvhhlZeX695771VxcbGuuuoqvf/++woODraf8+qrryo9PV3XXnut/Pz8NHLkSC1cuNDp0En2AADUg/79+/9iB9tisWj27NmaPXv2OY+Jjo7WihUrXI6FZA8AMAebpHO/WLBu53spkj0AwBQa+gl6jUmjejY+AABwPyp7AIA5NPAEvcaEZA8AMAcTJ3va+AAA+DgqewCAOZi4sifZAwDMgVvvAADwbdx6BwAAfBaVPQDAHBizBwDAx9kMyeJCwrZ5b7KnjQ8AgI+jsgcAmANtfAAAfJ2LyV7em+xp4wMA4OOo7AEA5kAbHwAAH2cz5FIrntn4AACgsaKyBwCYg2E7vbhyvpci2QMAzIExewAAfBxj9gAAwFdR2QMAzIE2PgAAPs6Qi8nebZE0ONr4AAD4OCp7AIA50MYHAMDH2WySXLhX3ua999nTxgcAwMdR2QMAzIE2PgAAPs7EyZ42PgAAPo7KHgBgDiZ+XC7JHgBgCoZhk+HCm+tcOdfTSPYAAHMwDNeqc8bsAQBAY0VlDwAwB8PFMXsvruxJ9gAAc7DZJIsL4+5ePGZPGx8AAB9HZQ8AMAfa+AAA+DbDZpPhQhvfm2+9o40PAICPo7IHAJgDbXwAAHyczZAs5kz2tPEBAPBxVPYAAHMwDEmu3GfvvZU9yR4AYAqGzZDhQhvfINkDANDIGTa5Vtlz6x0AAGikqOwBAKZAGx8AAF9n4ja+Vyf7M9+yalTt0nMS4CVsVZ6OAA3IWlnh6RDQAM78nhuianY1V9So2n3BNDCvTvYnTpyQJG3Wex6OBA2iyNMBoEEt8HQAaEgnTpxQVFRUvVw7MDBQcXFx2lzoeq6Ii4tTYGCgG6JqWBbDiwchbDabCgoKFBERIYvF4ulwGkxpaakSEhKUn5+vyMhIT4eDesTv2jzM+rs2DEMnTpxQfHy8/Pzqb854RUWFqqpc7w4GBgYqODjYDRE1LK+u7P38/NSqVStPh+ExkZGRpvpLwcz4XZuHGX/X9VXR/1xwcLBXJml34dY7AAB8HMkeAAAfR7L3QkFBQZoxY4aCgoI8HQrqGb9r8+B3jfrk1RP0AADAr6OyBwDAx5HsAQDwcSR7AAB8HMkeAAAfR7L3MosWLVKbNm0UHBys3r1767PPPvN0SKgHGzdu1NChQxUfHy+LxaLVq1d7OiTUk3nz5unyyy9XRESEYmJiNHz4cOXk5Hg6LPgYkr0XWblypSZMmKAZM2Zox44d6t69u1JSUnTs2DFPhwY3Ky8vV/fu3bVo0SJPh4J6tmHDBqWlpWnr1q3KzMxUdXW1Bg0apPLyck+HBh/CrXdepHfv3rr88sv13HPPSTr9boCEhASNHTtWjzzyiIejQ32xWCxatWqVhg8f7ulQ0AC+//57xcTEaMOGDbr66qs9HQ58BJW9l6iqqlJ2drYGDhxo3+bn56eBAwcqKyvLg5EBcKeSkhJJUnR0tIcjgS8h2XuJH374QVarVbGxsQ7bY2NjVVhY6KGoALiTzWbTuHHjdOWVV6pLly6eDgc+xKvfegcAviQtLU1ff/21Nm/e7OlQ4GNI9l6iRYsW8vf3V1FRkcP2oqIixcXFeSgqAO6Snp6utWvXauPGjaZ+dTfqB218LxEYGKiePXtq3bp19m02m03r1q1TcnKyByMD4ArDMJSenq5Vq1bp448/Vtu2bT0dEnwQlb0XmTBhglJTU9WrVy9dccUVeuaZZ1ReXq4777zT06HBzcrKyrR//377em5urnbu3Kno6GglJiZ6MDK4W1pamlasWKG3335bERER9jk4UVFRCgkJ8XB08BXceudlnnvuOT355JMqLCxUjx49tHDhQvXu3dvTYcHN1q9frwEDBpy1PTU1VRkZGQ0fEOqNxWKpdfuyZct0xx13NGww8FkkewAAfBxj9gAA+DiSPQAAPo5kDwCAjyPZAwDg40j2AAD4OJI9AAA+jmQPAICPI9kDAODjSPaAi+644w4NHz7cvt6/f3+NGzeuweNYv369LBaLiouLz3mMxWLR6tWr63zNmTNnqkePHi7FdejQIVksFu3cudOl6wA4fyR7+KQ77rhDFotFFotFgYGBat++vWbPnq2ampp6/+x//etfmjNnTp2OrUuCBgBX8SIc+Kzrr79ey5YtU2Vlpd577z2lpaWpSZMmmjJlylnHVlVVKTAw0C2fGx0d7ZbrAIC7UNnDZwUFBSkuLk6tW7fWmDFjNHDgQL3zzjuSfmq9P/7444qPj1eHDh0kSfn5+brpppvUtGlTRUdHa9iwYTp06JD9mlarVRMmTFDTpk3VvHlzPfzww/rf10v8bxu/srJSkydPVkJCgoKCgtS+fXstXbpUhw4dsr/splmzZrJYLPYXn9hsNs2bN09t27ZVSEiIunfvrjfffNPhc9577z1dcsklCgkJ0YABAxzirKvJkyfrkksuUWhoqNq1a6dp06apurr6rONeeOEFJSQkKDQ0VDfddJNKSkoc9r/00kvq1KmTgoOD1bFjRz3//PNOxwKg/pDsYRohISGqqqqyr69bt045OTnKzMzU2rVrVV1drZSUFEVERGjTpk369NNPFR4eruuvv95+3oIFC5SRkaG///3v2rx5s44fP65Vq1b94ufefvvt+uc//6mFCxdq7969euGFFxQeHq6EhAS99dZbkqScnBwdPXpUf/3rXyVJ8+bN08svv6wlS5Zo9+7dGj9+vG699VZt2LBB0ukvJSNGjNDQoUO1c+dO3X333XrkkUec/ncSERGhjIwM7dmzR3/961/14osv6umnn3Y4Zv/+/Xr99de1Zs0avf/++/riiy90//332/e/+uqrmj59uh5//HHt3btXc+fO1bRp07R8+XKn4wFQTwzAB6WmphrDhg0zDMMwbDabkZmZaQQFBRkTJ06074+NjTUqKyvt57zyyitGhw4dDJvNZt9WWVlphISEGB988IFhGIbRsmVLY/78+fb91dXVRqtWreyfZRiG0a9fP+PBBx80DMMwcnJyDElGZmZmrXF+8sknhiTjxx9/tG+rqKgwQkNDjS1btjgcO3r0aOOWW24xDMMwpkyZYiQlJTnsnzx58lnX+l+SjFWrVp1z/5NPPmn07NnTvj5jxgzD39/fOHz4sH3bv//9b8PPz884evSoYRiGcdFFFxkrVqxwuM6cOXOM5ORkwzAMIzc315BkfPHFF+f8XAD1izF7+Ky1a9cqPDxc1dXVstls+r//+z/NnDnTvr9r164O4/Rffvml9u/fr4iICIfrVFRU6MCBAyopKdHRo0fVu3dv+76AgAD16tXrrFb+GTt37pS/v7/69etX57j379+vkydP6rrrrnPYXlVVpUsvvVSStHfvXoc4JCk5ObnOn3HGypUrtXDhQh04cEBlZWWqqalRZGSkwzGJiYm68MILHT7HZrMpJydHEREROnDggEaPHq177rnHfkxNTY2ioqKcjgdA/SDZw2cNGDBAixcvVmBgoOLj4xUQ4Pife1hYmMN6WVmZevbsqVdfffWsa11wwQXnFUNISIjT55SVlUmS3n33XYckK52eh+AuWVlZGjVqlGbNmqWUlBRFRUXptdde04IFC5yO9cUXXzzry4e/v7/bYgXgGpI9fFZYWJjat29f5+Mvu+wyrVy5UjExMWdVt2e0bNlS27Zt09VXXy3pdAWbnZ2tyy67rNbju3btKpvNpg0bNmjgwIFn7T/TWbBarfZtSUlJCgoKUl5e3jk7Ap06dbJPNjxj69atv/5D/syWLVvUunVrPfroo/Zt33333VnH5eXlqaCgQPHx8fbP8fPzU4cOHRQbG6v4+HgdPHhQo0aNcurzATQcJugB/zVq1Ci1aNFCw4YN06ZNm5Sbm6v169frgQce0OHDhyVJDz74oJ544gmtXr1a33zzje6///5fvEe+TZs2Sk1N1V133aXVq1fbr/n6669Lklq3bi2LxaK1a9fq+++/V1lZmSIiIjRx4kSNHz9ey5cv14EDB7Rjxw49++yz9klv9913n/bt26dJkyYpJydHK1asUEZGhlM/78UXX6y8vDy99tprOnDggBYuXFjrZMPg4GClpqbqyy+/1KZNm/TAAw/opptuUlxcnCRp1qxZmjdvnhYuXKhvv/1Wu3bt0rJly/TUU085FQ+A+kOyB/4rNDRUGzduVGJiokaMGKFOnTpp9OjRqqiosFf6Dz30kG677TalpqYqOTlZERER+u1vf/uL1128eLF+97vf6f7771fHjh11zz33qLy8XJJ04YUXatasWXrkkUcUGxur9PR0SdKcOXM0bdo0zZs3T506ddL111+vd999V23btpV0ehz9rbfe0urVq9W9e3ctWbJEc+fOdernvfHGGzV+/Hilp6erR48e2rJli6ZNm3bWce3bt9eIESN0ww03aNCgQerWrZvDrXV33323XnrpJS1btkxdu3ZVv379lJGRYY8VgOdZjHPNLAIAAD6Byh4AAB9HsgcAwMeR7AEA8HEkewAAfBzJHgAAH0eyBwDAx5HsAQDwcSR7AAB8HMkeAAAfR7IHAMDHkewBAPBx/x8TvM6P8AnGmAAAAABJRU5ErkJggg==", + "text/plain": [ + "<Figure size 640x480 with 2 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cm =confusion_matrix(y_test, my_pred)\n", + "disp = ConfusionMatrixDisplay(confusion_matrix=cm,)\n", + "disp.plot()\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h1> 6. Testing Data</h1>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\60172\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\sklearn\\base.py:439: UserWarning: X does not have valid feature names, but KNeighborsClassifier was fitted with feature names\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "text/plain": [ + "predicted marker\n", + "0 38\n", + "2 37\n", + "1 25\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 328, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_testpred = grid.predict(mTest.values)\n", + "y_testpred = pd.DataFrame(y_testpred, columns=['predicted marker'])\n", + "y_testpred.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_testpred.to_csv('testresult.csv')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.11.3" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} -- GitLab