{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from sklearn.feature_extraction import  DictVectorizer\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "from sklearn.naive_bayes import MultinomialNB\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.neighbors import  KNeighborsClassifier\n",
    "import sklearn.metrics as met\n",
    "import pandas as pd\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#podaci o instancama\n",
    "corpus = []\n",
    "#klase instanci\n",
    "classes = []\n",
    "\n",
    "#putanja do direktorijuma koji sadrzi skup \n",
    "#u skupu su podaci podeljeni po direktorijumima cije ime odredjuje klasu clanaka\n",
    "#u svakoj datoteci su podaci o recima iz clanaka u obliku koren_reci broj_pojavljivanja\n",
    "dir_path='C:/Users/student/Desktop/ipIndustija4/ipVezbe82021/vezbe7/ebart/VektoriEbart-5/Skup/'\n",
    "#ucitavanje skupa\n",
    "#detalje o skupu pogledati u tekstu za vezbe 6\n",
    "for class_name in os.listdir(dir_path):  #izlistavanje direktorijuma koji predstavljaju klase\n",
    "    dir_path_clas = dir_path + class_name #putanja klasa-direktorijuma\n",
    "    for file_name in os.listdir(dir_path_clas):  #izlistavanje datoteka u  klasa-direktorijumu\n",
    "        f=open(dir_path_clas + '/' + file_name, 'r') #otvaranje datoteke\n",
    "        file_words = {}  #priprema recnika za cuvanje podataka iz jednog clanka, elementi ce biti oblika rec:broj_pojavljivanja\n",
    "        for line in f:  #prolazak kroz redove datoteke\n",
    "            word_count=line.split() #pravljenje liste na osnovu reda. U listi je prvi element rec, a drugi broj pojavljivanja reci \n",
    "            file_words[word_count[0]]=int(word_count[1]) #dodavanje podataka o reci u recnik\n",
    "        classes.append(class_name) # dodavanje podataka o dokumentu\n",
    "        corpus.append(file_words) # dodavanje klase dokumenta\n",
    "        f.close()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "#pravljenje term-matrice na osnovu liste recnika\n",
    "#jedan recnik sadrzi informacije o jednoj instanci, tj. jednom clanku u\n",
    "# kojem je kljuc term, a vrednost kljuca broj pojavljivanja terma u clanku\n",
    "dv = DictVectorizer()\n",
    "x=dv.fit_transform(corpus)\n",
    "#print('Termi koji se pojavljuju u korpusu')\n",
    "#print(dv.get_feature_names())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "df=pd.DataFrame(x.toarray(), columns=dv.get_feature_names())\n",
    "#print(df.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "#podela na trening i test skup\n",
    "x_train, x_test, y_train, y_test = train_test_split(df, classes, test_size=0.3, stratify=classes)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def class_info(clf, x_train, y_train, x_test, y_test, cv=False):\n",
    "\n",
    "    start=time.time()\n",
    "    clf.fit(x_train, y_train)\n",
    "\n",
    "    end=time.time()\n",
    "    print('Vreme pravljenja modela', end-start)\n",
    "\n",
    "    #izvestaj za unakrsnu validaciju, ukoliko je primenjena\n",
    "    if cv:\n",
    "        print('Najbolji parametri', clf.best_params_)\n",
    "\n",
    "        means = clf.cv_results_['mean_test_score']\n",
    "        stds = clf.cv_results_['std_test_score']\n",
    "        for mean, std, params in zip(means, stds, clf.cv_results_['params']):\n",
    "            print(\"%0.3f (+/-%0.03f) za %s\" % (mean, std * 2, params))\n",
    "\n",
    "    print('Trening skup')\n",
    "    y_pred = clf.predict(x_train)\n",
    "\n",
    "    cnf_matrix = met.confusion_matrix(y_train, y_pred)\n",
    "    print(\"Matrica konfuzije\")\n",
    "    print(pd.DataFrame(cnf_matrix, index=clf.classes_, columns=clf.classes_))\n",
    "   \n",
    "\n",
    "    accuracy = met.accuracy_score(y_train, y_pred)\n",
    "    print(\"Preciznost\", accuracy)\n",
    "  \n",
    "\n",
    "    class_report = met.classification_report(y_train, y_pred)\n",
    "    print(\"Izvestaj klasifikacije\")\n",
    "    print(class_report)\n",
    "   \n",
    "\n",
    "    print('Test skup')\n",
    "    y_pred = clf.predict(x_test)\n",
    "\n",
    "    cnf_matrix = met.confusion_matrix(y_test, y_pred)\n",
    "    print(\"Matrica konfuzije\")\n",
    "    print(pd.DataFrame(cnf_matrix, index=clf.classes_, columns=clf.classes_))\n",
    " \n",
    "\n",
    "    accuracy = met.accuracy_score(y_test, y_pred)\n",
    "    print(\"Preciznost\", accuracy)\n",
    "  \n",
    "\n",
    "    class_report = met.classification_report(y_test, y_pred, target_names=clf.classes_)\n",
    "    print(\"Izvestaj klasifikacije\")\n",
    "    print(class_report)\n",
    " \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MultinomialNB\n",
      "Vreme pravljenja modela 0.5828678607940674\n",
      "Trening skup\n",
      "Matrica konfuzije\n",
      "                 Ekonomija  HronikaKriminal  KulturaZabava  Politika  Sport\n",
      "Ekonomija              216                2              3        12      0\n",
      "HronikaKriminal          9              362              2        61      0\n",
      "KulturaZabava            0                2            433         4      0\n",
      "Politika                 5               14              2       628      5\n",
      "Sport                    0                4              0         2    678\n",
      "Preciznost 0.9480360065466449\n",
      "Izvestaj klasifikacije\n",
      "                 precision    recall  f1-score   support\n",
      "\n",
      "      Ekonomija       0.94      0.93      0.93       233\n",
      "HronikaKriminal       0.94      0.83      0.89       434\n",
      "  KulturaZabava       0.98      0.99      0.99       439\n",
      "       Politika       0.89      0.96      0.92       654\n",
      "          Sport       0.99      0.99      0.99       684\n",
      "\n",
      "       accuracy                           0.95      2444\n",
      "      macro avg       0.95      0.94      0.94      2444\n",
      "   weighted avg       0.95      0.95      0.95      2444\n",
      "\n",
      "Test skup\n",
      "Matrica konfuzije\n",
      "                 Ekonomija  HronikaKriminal  KulturaZabava  Politika  Sport\n",
      "Ekonomija               85                2              0        13      0\n",
      "HronikaKriminal          5              129              4        47      1\n",
      "KulturaZabava            1                3            178         4      2\n",
      "Politika                 4               15              3       258      1\n",
      "Sport                    1                4              3         6    279\n",
      "Preciznost 0.8864503816793893\n",
      "Izvestaj klasifikacije\n",
      "                 precision    recall  f1-score   support\n",
      "\n",
      "      Ekonomija       0.89      0.85      0.87       100\n",
      "HronikaKriminal       0.84      0.69      0.76       186\n",
      "  KulturaZabava       0.95      0.95      0.95       188\n",
      "       Politika       0.79      0.92      0.85       281\n",
      "          Sport       0.99      0.95      0.97       293\n",
      "\n",
      "       accuracy                           0.89      1048\n",
      "      macro avg       0.89      0.87      0.88      1048\n",
      "   weighted avg       0.89      0.89      0.89      1048\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#klasifikacija primenom razlicitih algoritama\n",
    "print(\"MultinomialNB\")\n",
    "clf_mnb = MultinomialNB()\n",
    "class_info(clf_mnb, x_train, y_train, x_test, y_test)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "#definisanje mogucih vrednosti parametara za drveta odlucivanja\n",
    "# koji ce se koristiti u unakrsnoj validaciji\n",
    "parameters = [{'criterion': ['gini', 'entropy'],\n",
    "               'max_depth':[15, 25, 5],\n",
    "               }]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DecisionTreeClassifier\n",
      "Vreme pravljenja modela 516.6887810230255\n",
      "Najbolji parametri {'criterion': 'gini', 'max_depth': 25}\n",
      "0.643 (+/-0.049) za {'criterion': 'gini', 'max_depth': 15}\n",
      "0.685 (+/-0.042) za {'criterion': 'gini', 'max_depth': 25}\n",
      "0.501 (+/-0.055) za {'criterion': 'gini', 'max_depth': 5}\n",
      "0.645 (+/-0.039) za {'criterion': 'entropy', 'max_depth': 15}\n",
      "0.664 (+/-0.054) za {'criterion': 'entropy', 'max_depth': 25}\n",
      "0.532 (+/-0.043) za {'criterion': 'entropy', 'max_depth': 5}\n",
      "Trening skup\n",
      "Matrica konfuzije\n",
      "                 Ekonomija  HronikaKriminal  KulturaZabava  Politika  Sport\n",
      "Ekonomija              170                0              0        25     38\n",
      "HronikaKriminal          0              340              0        28     66\n",
      "KulturaZabava            0                0            352        10     77\n",
      "Politika                 0                0              0       585     69\n",
      "Sport                    0                0              0         9    675\n",
      "Preciznost 0.8682487725040916\n",
      "Izvestaj klasifikacije\n",
      "                 precision    recall  f1-score   support\n",
      "\n",
      "      Ekonomija       1.00      0.73      0.84       233\n",
      "HronikaKriminal       1.00      0.78      0.88       434\n",
      "  KulturaZabava       1.00      0.80      0.89       439\n",
      "       Politika       0.89      0.89      0.89       654\n",
      "          Sport       0.73      0.99      0.84       684\n",
      "\n",
      "       accuracy                           0.87      2444\n",
      "      macro avg       0.92      0.84      0.87      2444\n",
      "   weighted avg       0.90      0.87      0.87      2444\n",
      "\n",
      "Test skup\n",
      "Matrica konfuzije\n",
      "                 Ekonomija  HronikaKriminal  KulturaZabava  Politika  Sport\n",
      "Ekonomija               51                8              0        20     21\n",
      "HronikaKriminal          4              101              1        47     33\n",
      "KulturaZabava            5               15            119         4     45\n",
      "Politika                12               37             10       196     26\n",
      "Sport                    0                6              1        10    276\n",
      "Preciznost 0.708969465648855\n",
      "Izvestaj klasifikacije\n",
      "                 precision    recall  f1-score   support\n",
      "\n",
      "      Ekonomija       0.71      0.51      0.59       100\n",
      "HronikaKriminal       0.60      0.54      0.57       186\n",
      "  KulturaZabava       0.91      0.63      0.75       188\n",
      "       Politika       0.71      0.70      0.70       281\n",
      "          Sport       0.69      0.94      0.80       293\n",
      "\n",
      "       accuracy                           0.71      1048\n",
      "      macro avg       0.72      0.67      0.68      1048\n",
      "   weighted avg       0.72      0.71      0.70      1048\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(\"DecisionTreeClassifier\")\n",
    "\n",
    "#napomena: izvrsavanje traje dugo\n",
    "clf_dt = GridSearchCV(DecisionTreeClassifier(), parameters, cv=5)\n",
    "class_info(clf_dt, x_train, y_train, x_test, y_test, cv=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "KNeighborsClassifier\n",
      "Vreme pravljenja modela 82.55995988845825\n",
      "Najbolji parametri {'n_neighbors': 10, 'p': 2, 'weights': 'distance'}\n",
      "0.525 (+/-0.046) za {'n_neighbors': 5, 'p': 2, 'weights': 'uniform'}\n",
      "0.544 (+/-0.025) za {'n_neighbors': 5, 'p': 2, 'weights': 'distance'}\n",
      "0.549 (+/-0.043) za {'n_neighbors': 10, 'p': 2, 'weights': 'uniform'}\n",
      "0.554 (+/-0.053) za {'n_neighbors': 10, 'p': 2, 'weights': 'distance'}\n",
      "0.525 (+/-0.046) za {'n_neighbors': 20, 'p': 2, 'weights': 'uniform'}\n",
      "0.533 (+/-0.046) za {'n_neighbors': 20, 'p': 2, 'weights': 'distance'}\n",
      "Trening skup\n",
      "Matrica konfuzije\n",
      "                 Ekonomija  HronikaKriminal  KulturaZabava  Politika  Sport\n",
      "Ekonomija              233                0              0         0      0\n",
      "HronikaKriminal          0              434              0         0      0\n",
      "KulturaZabava            0                0            439         0      0\n",
      "Politika                 0                0              0       654      0\n",
      "Sport                    0                0              0         0    684\n",
      "Preciznost 1.0\n",
      "Izvestaj klasifikacije\n",
      "                 precision    recall  f1-score   support\n",
      "\n",
      "      Ekonomija       1.00      1.00      1.00       233\n",
      "HronikaKriminal       1.00      1.00      1.00       434\n",
      "  KulturaZabava       1.00      1.00      1.00       439\n",
      "       Politika       1.00      1.00      1.00       654\n",
      "          Sport       1.00      1.00      1.00       684\n",
      "\n",
      "       accuracy                           1.00      2444\n",
      "      macro avg       1.00      1.00      1.00      2444\n",
      "   weighted avg       1.00      1.00      1.00      2444\n",
      "\n",
      "Test skup\n",
      "Matrica konfuzije\n",
      "                 Ekonomija  HronikaKriminal  KulturaZabava  Politika  Sport\n",
      "Ekonomija               10                3             13        56     18\n",
      "HronikaKriminal          1               10             11        74     90\n",
      "KulturaZabava            0                0             77        27     84\n",
      "Politika                 2                2             13       221     43\n",
      "Sport                    0                0              3        13    277\n",
      "Preciznost 0.5677480916030534\n",
      "Izvestaj klasifikacije\n",
      "                 precision    recall  f1-score   support\n",
      "\n",
      "      Ekonomija       0.77      0.10      0.18       100\n",
      "HronikaKriminal       0.67      0.05      0.10       186\n",
      "  KulturaZabava       0.66      0.41      0.50       188\n",
      "       Politika       0.57      0.79      0.66       281\n",
      "          Sport       0.54      0.95      0.69       293\n",
      "\n",
      "       accuracy                           0.57      1048\n",
      "      macro avg       0.64      0.46      0.43      1048\n",
      "   weighted avg       0.61      0.57      0.49      1048\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(\"KNeighborsClassifier\")\n",
    "\n",
    "#definisanje mogucih vrednosti parametara za K najblizih suseda\n",
    "# koji ce se koristiti u unakrsnoj validaciji\n",
    "parameters = [{'n_neighbors': [5, 10, 20],\n",
    "               'p':[2],\n",
    "               'weights': ['uniform', 'distance'],\n",
    "               }]\n",
    "\n",
    "# napomena: izvrsavanje traje dugo\n",
    "clf_dt = GridSearchCV(KNeighborsClassifier(), parameters, cv=5 )\n",
    "class_info(clf_dt, x_train, y_train, x_test, y_test, cv=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.8.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
