# -*- coding: utf-8 -*-
"""IR5_MI_KNN.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1ivytswQ_9jZCLL2EiFzEwuMi34Vu_0Tu
"""

## Cell 0 ##

cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]
import pickle

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# UNCOMMENT these three pickle files for executing the code for (80:20) split. Give path to the pickled files.  #

#pickle_in = open("PATH OF classes_list(80:20).pickle FILE","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF Global(80:20).pickle FILE","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("PATH OF classes_test_list(80:20).pickle FILE","rb")
#classes_test_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF MI(80:20).pickle FILE","rb")
#MI =pickle.load(pickle_in)


#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++






#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# UNCOMMENT these three pickle files for executing the code for 70:30 split. Give path to the pickled files. #

#pickle_in = open("PATH OF classes_list(70:30).pickle FILE","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF Global(70:30).pickle FILE","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("PATH OF classes_test_list(70:30).pickle FILE","rb")
#classes_test_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF MI(70:30).pickle FILE","rb")
#MI =pickle.load(pickle_in)


#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++





#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# UNCOMMENT these three pickle files for executing the code for (50:50) split. Give path to the pickled files. #

#pickle_in = open("PATH OF classes_list(50:50).pickle FILE","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF Global(50:50).pickle FILE","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("PATH OF classes_test_list(50:50).pickle FILE","rb")
#classes_test_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF MI(50:50).pickle FILE","rb")
#MI =pickle.load(pickle_in)

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#Execution sequence of this python  code using pickled results

# Cell 1 --> Cell 2 --> Cell 3 -->Cell 4-->cell 10-->cell 11-->cell 12--->Cell 13--> Cell 14 --> Cell 15-->Cell 16--->Cell 17--->cell 18
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

### Cell 1 ###
##importing  nltk##

import nltk
nltk.download('punkt')

#Cell 2 #
##installing num2words ##
pip install num2words

#Cell 3 #
#Importing all esentials#

from nltk.stem import PorterStemmer 
from nltk.tokenize import RegexpTokenizer
from nltk.tokenize import word_tokenize 
import numpy as np
import glob
from collections import Counter 
from sklearn.utils import shuffle  
import os
from num2words import num2words
from nltk.corpus import stopwords 
import pickle
import math
import operator
from sklearn.manifold import TSNE
import seaborn as sns
import matplotlib.pyplot as plt 
import random 
from sklearn.model_selection import train_test_split
import pandas as pd  

ps = PorterStemmer() 
tokenizer = RegexpTokenizer(r'\w+')

## CELL 4  ##
## Download stopwords ##

import nltk
nltk.download('stopwords')

## Cell 5 ##
##Splitting into Test & Train RANDOMLY using Test Train Split and shuffle ###



Data=pd.DataFrame(columns = ["file_name", "class"])
cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]


for group in cat_list:
  for filename in glob.glob("drive/My Drive/IR4/"+group+"/*"):
    
    length=len(filename)
    j=0
    for k in range(length-1,-1,-1):
      if filename[k]=='/':
        j=k
        break
  
    Data=Data.append({"file_name":filename[j+1:len(filename)],"class":group},ignore_index=True)

##Shuffling and split ##
Data = shuffle(Data)

x=Data["file_name"]
y=Data["class"]
xTrain, xTest, yTrain, yTest = train_test_split(x, y, test_size = 0.2, random_state = 12)

## Cell 6 ##
## Pre-processing Train Docs ###

stop_words = set(stopwords.words('english')) 
cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]
GLOBAL=[]
classes_list={}
for group in cat_list:
  global_doc=[]
  for filename in glob.glob("drive/My Drive/IR4/"+group+"/*"):
    
    length=len(filename)
    j=0
    for k in range(length-1,-1,-1):
      if filename[k]=='/':
        j=k
        break
    print(filename[j+1:len(filename)])
    if filename[j+1:len(filename)] in list(xTrain):
      if not os.path.isdir(filename):
        text = open(filename,"r+",errors='ignore') 
        var=(text.read())
        var=var.replace(',','')
        words_tokens=tokenizer.tokenize(var)
        words = [w for w in words_tokens if not w in stop_words] 
      
        Words=[]
        for w in words:
          if w.isdigit():
            Words.append(ps.stem(num2words(w)))
            GLOBAL.append(ps.stem(num2words(w)))
          else:
            Words.append(ps.stem(w))
            GLOBAL.append(ps.stem(w))
      global_doc.append(Words)
  classes_list.update({group:global_doc})


#pickle_out = open("drive/My Drive/classes_list(80:20).pickle","wb")
#pickle.dump(classes_list, pickle_out)
#pickle_out.close()


#pickle_out = open("drive/My Drive/Global(80:20).pickle","wb")
#pickle.dump(classes_list, pickle_out)
#pickle_out.close()

## Cell 7 ##
### Calculating MI for each Tuple(term,class) ####

MI=[]

Global_unique=np.unique(GLOBAL) #all terms of all the classes

for term in Global_unique:
  for clas in cat_list:
    N11=0
    N10=0
    N01=0
    N00=0

    for key in classes_list.keys():
      docs=classes_list.get(key)
      for doc in docs:
        if term in doc and key ==clas:
          N11=N11+1
        if term in doc and key !=clas:
          N10=N10+1
        if term not in doc and key ==clas:
          N01=N01+1
        if term not in doc and key !=clas:
          N00=N00+1
    N00=N00+0.0001
    N01=N01+0.0001
    N10=N10+0.0001
    N11=N11+0.0001      
    N=N00+N11+N01+N10
    

    val=(N11/N)*math.log(((N*N11)/((N11+N10)*(N01+N11)))+0.0001,2) + (N01/N)*math.log(((N*N01)/((N01+N00)*(N01+N11)))+0.0001,2) + (N10/N)*math.log(((N*N10)/((N11+N10)*(N00+N10)))+0.0001,2) + (N00/N)*math.log(((N*N00)/((N01+N00)*(N00+N10)))+0.0001,2)
    print(term,val)
    MI.append(tuple([term,clas,val]))

#### selecting the value of number of features (K) ###
### Feature Selection using TF-IDF ###

## Cell 8 ##

#cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]
#pickle_in = open("drive/My Drive/classes_list(70:30).pickle","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("drive/My Drive/Global(70:30).pickle","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("drive/My Drive/xTest(70:30).pickle","rb")
#xTest =pickle.load(pickle_in)


#pickle_in = open("drive/My Drive/classes_test_list(70:30).pickle","rb")
#classes_test_list =pickle.load(pickle_in)

## Cell 9 ##


#MI=[]
#file = open("drive/My Drive/MI_1(80:20).pickle", 'rb')      
#MI1 = pickle.load(file) 
#file = open("drive/My Drive/MI_2(80:20).pickle", 'rb')      
#MI2 = pickle.load(file) 
#file = open("drive/My Drive/MI_3(80:20).pickle", 'rb')      
#MI3 = pickle.load(file) 
#file = open("drive/My Drive/MI_4(80:20).pickle", 'rb')      
#MI4 = pickle.load(file) 
#file = open("drive/My Drive/MI_5(80:20).pickle", 'rb')      
#MI5 = pickle.load(file) 
#file = open("drive/My Drive/MI_6(80:20).pickle", 'rb')      
#MI6 = pickle.load(file)

#for item in range(0,len(MI1)):
#  MI.append(MI1[item])
#  MI.append(MI2[item])
#  MI.append(MI3[item])
#  MI.append(MI4[item])
#  MI.append(MI5[item])
#  MI.append(MI6[item])

#print(len(MI))

#pickle_out = open("drive/My Drive/MI(80:20).pickle","wb")
#pickle.dump(MI, pickle_out)
#pickle_out.close()

## Cell 10 ##
### Further proceesing of MI.Please note that I have selected 1/5 of total features for my calculations ##
Global_unique=np.unique(GLOBAL)
MI1=[]
MI2=[]
MI3=[]
MI4=[]
MI5=[]

for item in MI:
  if item[1]==cat_list[0]:
    MI1.append(item)
  if item[1]==cat_list[1]:
    MI2.append(item)
  if item[1]==cat_list[2]:
    MI3.append(item)
  if item[1]==cat_list[3]:
    MI4.append(item)
  if item[1]==cat_list[4]:
    MI5.append(item)

MI1.sort(key=lambda elem : elem[2],reverse=True)
MI2.sort(key=lambda elem : elem[2],reverse=True)
MI3.sort(key=lambda elem : elem[2],reverse=True)
MI4.sort(key=lambda elem : elem[2],reverse=True)
MI5.sort(key=lambda elem : elem[2],reverse=True)

length=int(len(MI1)/5)

Mutual_info=[]
Mutual_info.append(MI1[0:length])
Mutual_info.append(MI2[0:length])
Mutual_info.append(MI3[0:length])
Mutual_info.append(MI4[0:length])
Mutual_info.append(MI5[0:length])
################################

## Cell 11 ##
##  Making tuple (class,feature vector) for each training doc ##
train_vecs=[]
selected_features=[]

## making union of all selected features from each class ###
for cls in Mutual_info:
  for item in cls:
    selected_features.append(item[0])

selected_features=set(selected_features)
selected_features=list(selected_features)



for key in classes_list.keys():

  docs=classes_list.get(key)
  for doc in docs:
    #print(doc)
    vec=[]
    for feature in selected_features:
      vec.append(doc.count(feature))
    train_vecs.append(tuple([key,vec]))

## Cell 12 ##
##  Making tuple (class,feature vector) for each Testing doc ##

test_vecs=[]

for key in classes_test_list.keys():

  docs=classes_test_list.get(key)
  for doc in docs:
    print(doc)
    vec=[]
    for feature in selected_features:
      vec.append(doc.count(feature))
    test_vecs.append(tuple([key,vec]))

## Cell 13 ##
#### Matrix multiplication of Test and Train Docs for computing Cosing similarity###
TestV=[]
TrainV=[]
for test in test_vecs:
  TestV.append(test[1])

for train in train_vecs:
  TrainV.append(train[1])

TestV=np.array(TestV)
TrainV=np.array(TrainV)
dot=np.dot(TestV,TrainV.T)

## Cell 14 ##
## Computing Similarity Matrix from above matrix multiplication ##
similarity_matrix=[]
for i in range(0,len(test_vecs)):
  mag_test=np.linalg.norm(TestV[i])
  print(i)
  list1=dot[i]
  list1=list1/mag_test
  #print(len(list))
  temp=[]
  for j in range(0,len(train_vecs)):
    
    mag_train=np.linalg.norm(TrainV[j])
    temp.append(tuple([j,list1[j]/mag_train]))

  similarity_matrix.append(temp)

## Cell 15 ##
#similarity_matrix=dot
#pickle_out = open("drive/My Drive/similarity_matrix_MI_KNN(80:20).pickle","wb")
#pickle.dump(similarity_matrix, pickle_out)
#pickle_out.close()

## Cell 16 ##
## ## KNN logic##
import statistics 
  
i=0
ct=0
actual=[]
predicted=[]
for test in similarity_matrix:
  #print(test
  #print(item)
  
  item=sorted(test, key=lambda tup: tup[1],reverse=True)

  ## In order to select the k value of KNN change the second value of the below line of code. Say for K=5 below line will be--> item=item[0:5] 
  ## For K=3 below line will be--> item=item[0:3]  ###

  item=item[0:5]
  vecs=[]
  for it in item:
    x=it[0]
    vecs.append(train_vecs[x][0])

  res=Counter(vecs)
  
  class1=res.most_common(1)[0][0]
  predicted.append(class1)
  actual.append(test_vecs[i][0])
  if class1==test_vecs[i][0]:
    ct=ct+1
  i=i+1
acrcy=((ct*100)/len(similarity_matrix))
print("accuracy= ",acrcy)

## Cell 17 ##
## Printing Confusion Matrix ##

from sklearn.metrics import confusion_matrix 

CM=confusion_matrix(actual, predicted)
print(CM)


##pickle_out = open("drive/My Drive/confusion_matrix_TFIDF_KNN(k=5)(80:20).pickle","wb")
#ickle.dump(CM, pickle_out)
#pickle_out.close()


#pickle_out = open("drive/My Drive/accuracy_TFIDF_KNN(k=5)(80:20).pickle","wb")
#pickle.dump(acrcy, pickle_out)
#pickle_out.close()

## Cell 18 ##
## give value of accuracy in list y [] to plot graph for "Number of neighbours vs accuracy in MI & KNN"  ###

import matplotlib.pyplot as plt 


x=[1,3,5]
y=[]  ### Values dal yaha pe ###
tick_label = ['K=1', 'K=3', 'K=5'] 

plt.bar(x,y, tick_label = tick_label, 
		width = 0.8, color = ['red', 'green','blue']) 


plt.xlabel('number of neighbours') 

plt.ylabel('accuracy') 

plt.title('Number of neighbours vs accuracy in MI & KNN') 
plt.ylim(91,95) 
#plt.xlim(1,8) 

plt.show()


69390b67bdc0ee014d876a87a75811f5c5229165
# -*- coding: utf-8 -*-
"""IR5_MI_KNN.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1ivytswQ_9jZCLL2EiFzEwuMi34Vu_0Tu
"""

## Cell 0 ##

cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]
import pickle

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# UNCOMMENT these three pickle files for executing the code for (80:20) split. Give path to the pickled files.  #

#pickle_in = open("PATH OF classes_list(80:20).pickle FILE","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF Global(80:20).pickle FILE","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("PATH OF classes_test_list(80:20).pickle FILE","rb")
#classes_test_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF MI(80:20).pickle FILE","rb")
#MI =pickle.load(pickle_in)


#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++






#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# UNCOMMENT these three pickle files for executing the code for 70:30 split. Give path to the pickled files. #

#pickle_in = open("PATH OF classes_list(70:30).pickle FILE","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF Global(70:30).pickle FILE","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("PATH OF classes_test_list(70:30).pickle FILE","rb")
#classes_test_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF MI(70:30).pickle FILE","rb")
#MI =pickle.load(pickle_in)


#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++





#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# UNCOMMENT these three pickle files for executing the code for (50:50) split. Give path to the pickled files. #

#pickle_in = open("PATH OF classes_list(50:50).pickle FILE","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF Global(50:50).pickle FILE","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("PATH OF classes_test_list(50:50).pickle FILE","rb")
#classes_test_list =pickle.load(pickle_in)

#pickle_in = open("PATH OF MI(50:50).pickle FILE","rb")
#MI =pickle.load(pickle_in)

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#Execution sequence of this python  code using pickled results

# Cell 1 --> Cell 2 --> Cell 3 -->Cell 4-->cell 10-->cell 11-->cell 12--->Cell 13--> Cell 14 --> Cell 15-->Cell 16--->Cell 17--->cell 18
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

### Cell 1 ###
##importing  nltk##

import nltk
nltk.download('punkt')

#Cell 2 #
##installing num2words ##
pip install num2words

#Cell 3 #
#Importing all esentials#

from nltk.stem import PorterStemmer 
from nltk.tokenize import RegexpTokenizer
from nltk.tokenize import word_tokenize 
import numpy as np
import glob
from collections import Counter 
from sklearn.utils import shuffle  
import os
from num2words import num2words
from nltk.corpus import stopwords 
import pickle
import math
import operator
from sklearn.manifold import TSNE
import seaborn as sns
import matplotlib.pyplot as plt 
import random 
from sklearn.model_selection import train_test_split
import pandas as pd  

ps = PorterStemmer() 
tokenizer = RegexpTokenizer(r'\w+')

## CELL 4  ##
## Download stopwords ##

import nltk
nltk.download('stopwords')

## Cell 5 ##
##Splitting into Test & Train RANDOMLY using Test Train Split and shuffle ###



Data=pd.DataFrame(columns = ["file_name", "class"])
cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]


for group in cat_list:
  for filename in glob.glob("drive/My Drive/IR4/"+group+"/*"):
    
    length=len(filename)
    j=0
    for k in range(length-1,-1,-1):
      if filename[k]=='/':
        j=k
        break
  
    Data=Data.append({"file_name":filename[j+1:len(filename)],"class":group},ignore_index=True)

##Shuffling and split ##
Data = shuffle(Data)

x=Data["file_name"]
y=Data["class"]
xTrain, xTest, yTrain, yTest = train_test_split(x, y, test_size = 0.2, random_state = 12)

## Cell 6 ##
## Pre-processing Train Docs ###

stop_words = set(stopwords.words('english')) 
cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]
GLOBAL=[]
classes_list={}
for group in cat_list:
  global_doc=[]
  for filename in glob.glob("drive/My Drive/IR4/"+group+"/*"):
    
    length=len(filename)
    j=0
    for k in range(length-1,-1,-1):
      if filename[k]=='/':
        j=k
        break
    print(filename[j+1:len(filename)])
    if filename[j+1:len(filename)] in list(xTrain):
      if not os.path.isdir(filename):
        text = open(filename,"r+",errors='ignore') 
        var=(text.read())
        var=var.replace(',','')
        words_tokens=tokenizer.tokenize(var)
        words = [w for w in words_tokens if not w in stop_words] 
      
        Words=[]
        for w in words:
          if w.isdigit():
            Words.append(ps.stem(num2words(w)))
            GLOBAL.append(ps.stem(num2words(w)))
          else:
            Words.append(ps.stem(w))
            GLOBAL.append(ps.stem(w))
      global_doc.append(Words)
  classes_list.update({group:global_doc})


#pickle_out = open("drive/My Drive/classes_list(80:20).pickle","wb")
#pickle.dump(classes_list, pickle_out)
#pickle_out.close()


#pickle_out = open("drive/My Drive/Global(80:20).pickle","wb")
#pickle.dump(classes_list, pickle_out)
#pickle_out.close()

## Cell 7 ##
### Calculating MI for each Tuple(term,class) ####

MI=[]

Global_unique=np.unique(GLOBAL) #all terms of all the classes

for term in Global_unique:
  for clas in cat_list:
    N11=0
    N10=0
    N01=0
    N00=0

    for key in classes_list.keys():
      docs=classes_list.get(key)
      for doc in docs:
        if term in doc and key ==clas:
          N11=N11+1
        if term in doc and key !=clas:
          N10=N10+1
        if term not in doc and key ==clas:
          N01=N01+1
        if term not in doc and key !=clas:
          N00=N00+1
    N00=N00+0.0001
    N01=N01+0.0001
    N10=N10+0.0001
    N11=N11+0.0001      
    N=N00+N11+N01+N10
    

    val=(N11/N)*math.log(((N*N11)/((N11+N10)*(N01+N11)))+0.0001,2) + (N01/N)*math.log(((N*N01)/((N01+N00)*(N01+N11)))+0.0001,2) + (N10/N)*math.log(((N*N10)/((N11+N10)*(N00+N10)))+0.0001,2) + (N00/N)*math.log(((N*N00)/((N01+N00)*(N00+N10)))+0.0001,2)
    print(term,val)
    MI.append(tuple([term,clas,val]))

#### selecting the value of number of features (K) ###
### Feature Selection using TF-IDF ###

## Cell 8 ##

#cat_list=["comp.graphics","rec.sport.hockey","sci.med","sci.space","talk.politics.misc"]
#pickle_in = open("drive/My Drive/classes_list(70:30).pickle","rb")
#classes_list =pickle.load(pickle_in)

#pickle_in = open("drive/My Drive/Global(70:30).pickle","rb")
#GLOBAL =pickle.load(pickle_in)

#pickle_in = open("drive/My Drive/xTest(70:30).pickle","rb")
#xTest =pickle.load(pickle_in)


#pickle_in = open("drive/My Drive/classes_test_list(70:30).pickle","rb")
#classes_test_list =pickle.load(pickle_in)

## Cell 9 ##


#MI=[]
#file = open("drive/My Drive/MI_1(80:20).pickle", 'rb')      
#MI1 = pickle.load(file) 
#file = open("drive/My Drive/MI_2(80:20).pickle", 'rb')      
#MI2 = pickle.load(file) 
#file = open("drive/My Drive/MI_3(80:20).pickle", 'rb')      
#MI3 = pickle.load(file) 
#file = open("drive/My Drive/MI_4(80:20).pickle", 'rb')      
#MI4 = pickle.load(file) 
#file = open("drive/My Drive/MI_5(80:20).pickle", 'rb')      
#MI5 = pickle.load(file) 
#file = open("drive/My Drive/MI_6(80:20).pickle", 'rb')      
#MI6 = pickle.load(file)

#for item in range(0,len(MI1)):
#  MI.append(MI1[item])
#  MI.append(MI2[item])
#  MI.append(MI3[item])
#  MI.append(MI4[item])
#  MI.append(MI5[item])
#  MI.append(MI6[item])

#print(len(MI))

#pickle_out = open("drive/My Drive/MI(80:20).pickle","wb")
#pickle.dump(MI, pickle_out)
#pickle_out.close()

## Cell 10 ##
### Further proceesing of MI.Please note that I have selected 1/5 of total features for my calculations ##
Global_unique=np.unique(GLOBAL)
MI1=[]
MI2=[]
MI3=[]
MI4=[]
MI5=[]

for item in MI:
  if item[1]==cat_list[0]:
    MI1.append(item)
  if item[1]==cat_list[1]:
    MI2.append(item)
  if item[1]==cat_list[2]:
    MI3.append(item)
  if item[1]==cat_list[3]:
    MI4.append(item)
  if item[1]==cat_list[4]:
    MI5.append(item)

MI1.sort(key=lambda elem : elem[2],reverse=True)
MI2.sort(key=lambda elem : elem[2],reverse=True)
MI3.sort(key=lambda elem : elem[2],reverse=True)
MI4.sort(key=lambda elem : elem[2],reverse=True)
MI5.sort(key=lambda elem : elem[2],reverse=True)

length=int(len(MI1)/5)

Mutual_info=[]
Mutual_info.append(MI1[0:length])
Mutual_info.append(MI2[0:length])
Mutual_info.append(MI3[0:length])
Mutual_info.append(MI4[0:length])
Mutual_info.append(MI5[0:length])
################################

## Cell 11 ##
##  Making tuple (class,feature vector) for each training doc ##
train_vecs=[]
selected_features=[]

## making union of all selected features from each class ###
for cls in Mutual_info:
  for item in cls:
    selected_features.append(item[0])

selected_features=set(selected_features)
selected_features=list(selected_features)



for key in classes_list.keys():

  docs=classes_list.get(key)
  for doc in docs:
    #print(doc)
    vec=[]
    for feature in selected_features:
      vec.append(doc.count(feature))
    train_vecs.append(tuple([key,vec]))

## Cell 12 ##
##  Making tuple (class,feature vector) for each Testing doc ##

test_vecs=[]

for key in classes_test_list.keys():

  docs=classes_test_list.get(key)
  for doc in docs:
    print(doc)
    vec=[]
    for feature in selected_features:
      vec.append(doc.count(feature))
    test_vecs.append(tuple([key,vec]))

## Cell 13 ##
#### Matrix multiplication of Test and Train Docs for computing Cosing similarity###
TestV=[]
TrainV=[]
for test in test_vecs:
  TestV.append(test[1])

for train in train_vecs:
  TrainV.append(train[1])

TestV=np.array(TestV)
TrainV=np.array(TrainV)
dot=np.dot(TestV,TrainV.T)

## Cell 14 ##
## Computing Similarity Matrix from above matrix multiplication ##
similarity_matrix=[]
for i in range(0,len(test_vecs)):
  mag_test=np.linalg.norm(TestV[i])
  print(i)
  list1=dot[i]
  list1=list1/mag_test
  #print(len(list))
  temp=[]
  for j in range(0,len(train_vecs)):
    
    mag_train=np.linalg.norm(TrainV[j])
    temp.append(tuple([j,list1[j]/mag_train]))

  similarity_matrix.append(temp)

## Cell 15 ##
#similarity_matrix=dot
#pickle_out = open("drive/My Drive/similarity_matrix_MI_KNN(80:20).pickle","wb")
#pickle.dump(similarity_matrix, pickle_out)
#pickle_out.close()

## Cell 16 ##
## ## KNN logic##
import statistics 
  
i=0
ct=0
actual=[]
predicted=[]
for test in similarity_matrix:
  #print(test
  #print(item)
  
  item=sorted(test, key=lambda tup: tup[1],reverse=True)

  ## In order to select the k value of KNN change the second value of the below line of code. Say for K=5 below line will be--> item=item[0:5] 
  ## For K=3 below line will be--> item=item[0:3]  ###

  item=item[0:5]
  vecs=[]
  for it in item:
    x=it[0]
    vecs.append(train_vecs[x][0])

  res=Counter(vecs)
  
  class1=res.most_common(1)[0][0]
  predicted.append(class1)
  actual.append(test_vecs[i][0])
  if class1==test_vecs[i][0]:
    ct=ct+1
  i=i+1
acrcy=((ct*100)/len(similarity_matrix))
print("accuracy= ",acrcy)

## Cell 17 ##
## Printing Confusion Matrix ##

from sklearn.metrics import confusion_matrix 

CM=confusion_matrix(actual, predicted)
print(CM)


##pickle_out = open("drive/My Drive/confusion_matrix_TFIDF_KNN(k=5)(80:20).pickle","wb")
#ickle.dump(CM, pickle_out)
#pickle_out.close()


#pickle_out = open("drive/My Drive/accuracy_TFIDF_KNN(k=5)(80:20).pickle","wb")
#pickle.dump(acrcy, pickle_out)
#pickle_out.close()

## Cell 18 ##
## give value of accuracy in list y [] to plot graph for "Number of neighbours vs accuracy in MI & KNN"  ###

import matplotlib.pyplot as plt 


x=[1,3,5]
y=[]  ### Values dal yaha pe ###
tick_label = ['K=1', 'K=3', 'K=5'] 

plt.bar(x,y, tick_label = tick_label, 
		width = 0.8, color = ['red', 'green','blue']) 


plt.xlabel('number of neighbours') 

plt.ylabel('accuracy') 

plt.title('Number of neighbours vs accuracy in MI & KNN') 
plt.ylim(91,95) 
#plt.xlim(1,8) 

plt.show()

