{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "465ef7c3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-01-10T06:48:15.893603Z",
     "start_time": "2023-01-10T06:48:14.076493Z"
    }
   },
   "outputs": [],
   "source": [
    "#import the packages\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "from warnings import simplefilter\n",
    "simplefilter(action='ignore', category=FutureWarning)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ef8db77c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-01-10T06:48:15.910189Z",
     "start_time": "2023-01-10T06:48:15.894567Z"
    }
   },
   "outputs": [],
   "source": [
    "#Data Pre-process \n",
    "#limit the data range and normalize the data\n",
    "def Dataprocess(Data):\n",
    "    P_Data = np.clip(Data,0,255)\n",
    "    M_Data = P_Data/255\n",
    "    return M_Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d35b249e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-01-10T06:50:38.762856Z",
     "start_time": "2023-01-10T06:48:21.394739Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "best_score= 0.8082\n",
      "best_criterion entropy\n",
      "best_max_depth 15\n",
      "best_min_samples_leaf 2\n",
      "best_min_samples_split 2\n"
     ]
    }
   ],
   "source": [
    "#This cell is to train and tune decision tree model to get the best performance\n",
    "#import the original data\n",
    "#import train data\n",
    "M_Train = pd.read_csv('fashion-mnist_train.csv')\n",
    "M_Train_array = np.array(M_Train)\n",
    "TrainMat = M_Train_array[:,1:785]\n",
    "TrainMat = Dataprocess(TrainMat)\n",
    "TrainLabel = M_Train_array[:,0]\n",
    "#import test data\n",
    "M_Test = pd.read_csv('fashion-mnist_test.csv')\n",
    "M_Test_array = np.array(M_Test)\n",
    "TestMat = M_Test_array[:,1:785]\n",
    "TestMat = Dataprocess(TestMat)\n",
    "TestLabel = M_Test_array[:,0]\n",
    "\n",
    "best_score = 0\n",
    "#A nested for-loop is defined to traverse four important parameters to get the best decision tree model\n",
    "#criterion\n",
    "for c in ['gini','entropy']:\n",
    "    #max_depth\n",
    "    for j in range(5,20):\n",
    "        #min_samples_leaf\n",
    "        for m in (2,10):\n",
    "            #min_samples_split\n",
    "            for n in (2,10):\n",
    "                #create decision tree model\n",
    "                classifier = DecisionTreeClassifier(criterion=c,max_depth=j,min_samples_leaf=m,min_samples_split=n,max_features='auto',random_state=0)\n",
    "                #train the model\n",
    "                classifier.fit(TrainMat, TrainLabel)\n",
    "                #Test accuracy\n",
    "                score = classifier.score(TestMat,TestLabel)\n",
    "                #If the accuracy rate this time is greater than the previous maximum accuracy rate, the parameter values of this time will be stored\n",
    "                if score >best_score:\n",
    "                    best_criterion = c\n",
    "                    best_score = score\n",
    "                    best_max_depth = j\n",
    "                    best_min_samples_leaf =m\n",
    "                    best_min_samples_split =n\n",
    "#print the best parameter values\n",
    "print('best_score=',best_score)\n",
    "print('best_criterion',best_criterion)\n",
    "print('best_max_depth',best_max_depth)\n",
    "print('best_min_samples_leaf',best_min_samples_leaf)\n",
    "print('best_min_samples_split',best_min_samples_split)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fe3a7aa2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-01-10T06:52:06.501049Z",
     "start_time": "2023-01-10T06:52:04.703580Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Confusion Matrix: \n",
      "[[782   5  27  57  10   1 108   0  10   0]\n",
      " [ 14 942   7  24   3   2   5   0   3   0]\n",
      " [ 20   3 720  17 135   0  91   0  14   0]\n",
      " [ 47  33  13 832  53   0  19   0   3   0]\n",
      " [  5   4 116  33 751   5  82   0   4   0]\n",
      " [  1   1   0   2   1 864   1  89   9  32]\n",
      " [180   7 105  52 121   0 518   0  17   0]\n",
      " [  0   0   1   0   0  64   0 866   5  64]\n",
      " [ 12   5  19   6  10  10  27   1 907   3]\n",
      " [  0   0   0   1   0  22   1  69   7 900]]\n",
      "\n",
      "\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.74      0.78      0.76      1000\n",
      "           1       0.94      0.94      0.94      1000\n",
      "           2       0.71      0.72      0.72      1000\n",
      "           3       0.81      0.83      0.82      1000\n",
      "           4       0.69      0.75      0.72      1000\n",
      "           5       0.89      0.86      0.88      1000\n",
      "           6       0.61      0.52      0.56      1000\n",
      "           7       0.84      0.87      0.86      1000\n",
      "           8       0.93      0.91      0.92      1000\n",
      "           9       0.90      0.90      0.90      1000\n",
      "\n",
      "    accuracy                           0.81     10000\n",
      "   macro avg       0.81      0.81      0.81     10000\n",
      "weighted avg       0.81      0.81      0.81     10000\n",
      "\n",
      "mean accuracy= 0.8082\n"
     ]
    }
   ],
   "source": [
    "#This cell is to evaluate the best Decision tree model\n",
    "\n",
    "#use the best parameter values to create the Decision tree model\n",
    "DT = DecisionTreeClassifier(criterion='entropy',max_depth=15,max_features='auto',min_samples_leaf=2,min_samples_split=2,random_state=0)\n",
    "#train\n",
    "DT.fit(TrainMat,TrainLabel)\n",
    "#Calculate the confusion matrix\n",
    "pred=DT.predict(TestMat)\n",
    "cm = confusion_matrix(y_true=TestLabel, y_pred=pred)\n",
    "\n",
    "# Print confusion matrix\n",
    "print(\"Confusion Matrix: \")\n",
    "print(cm)\n",
    "print('\\n')\n",
    "# Print precision ,recall and accuracy\n",
    "print(classification_report(TestLabel,pred))\n",
    "print('mean accuracy=', DT.score(TestMat,TestLabel))\n",
    "        "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
