# Question 1

import pandas
import matplotlib.pyplot as plt
iris=pandas.read_csv("iris.csv")
x=iris.loc[:,"petal_length"].tolist()
y=iris.loc[:,"petal_width"].tolist()
species=lab=iris.loc[:,"species"].tolist()
N=len(species)

plt.axis('equal')
plt.scatter([x[k] for k in range(N) if species[k]==0], [y[k] for k in range(N) if species[k]==0], marker='o', color='g', label='setosa')
plt.scatter([x[k] for k in range(N) if species[k]==1], [y[k] for k in range(N) if species[k]==1], marker='v',  color='r', label='versicolor')
plt.scatter([x[k] for k in range(N) if species[k]==2], [y[k] for k in range(N) if species[k]==2], marker='x',  color='b', label='virginica')
plt.legend()
plt.show()


#%%
# Question 2

plt.axis('equal')
plt.scatter([x[k] for k in range(N) if species[k]==0], [y[k] for k in range(N) if species[k]==0], color='g', label='setosa')
plt.scatter([x[k] for k in range(N) if species[k]==1], [y[k] for k in range(N) if species[k]==1],  color='r', label='versicolor')
plt.scatter([x[k] for k in range(N) if species[k]==2], [y[k] for k in range(N) if species[k]==2],  color='b', label='virginica')
plt.scatter(2.5, 0.75, color='black')
plt.legend()
plt.show()

# Pour ma part je prédis que l'iris est de l'espèce setosa.

#%%
# Question 3

data_flowers=[(x[k],y[k],species[k]) for k in range(N)]

#%%
# Question 4
 
def Dist(iris1,iris2):
    return ((iris1[0]-iris2[0])**2+(iris1[1]-iris2[1])**2)**(1/2)

#%%
# Question 5

def Majoritaire(L):
    """Renvoie un élément de L dont le nombre d'occurrences est maximal"""
    D={} # Dictionnaire du nombre d'occurrences des éléments de L
    Max=0
    for e in L: # Pour chaque élément de la liste
        if e in D: # Si on a déjà rencontré cet élément
            D[e]=D[e]+1 # Alors on l'a rencontré une fois de plus
        else:
            D[e]=1 # Sinon c'est la première fois qu'on le rencontre et donc on l'a rencontré une fois
        if D[e]>=Max: # S'il dépasse Max
            Max,emax=D[e],e # On actualise Max et emax l'élément qui a été rencontré Max-fois
    return emax

#%%
# Question 6
def KNN(iris,k):
    """Renvoie l'étiquette majoritaire parmi les k images les plus proches de images[i]"""
    def cle(voisin):#Clé de tri
        return Dist(iris,voisin)
    trié=sorted(data_flowers,key=cle)#la liste données est trié avec la clé:
    #les premiers éléments de trié sont les plus proches de images[i]
    L=[iris[2] for iris in trié[:k]]
    return Majoritaire(L)

#%%
# Question 7

new_iris=(2.5,0.75)

k=3
print("Pour k=",k,", l'iris est d'espèce",KNN(new_iris,k))

k=4
print("Pour k=",k,", l'iris est d'espèce",KNN(new_iris,k))

"""
La prédiction de l'espèce change car on considère 
les 4 proches voisins au lieu des 3 plus proches,
l'iris que l'on cherche à classer est relativement
équidistant des 2 nuages de points, donc il y a hésitation
"""

#%%
# Question 8

for k in range(1,20):
    print("Pour k=",k,",l'iris est de l'espèce :",KNN(new_iris,k))

""" 
On va retenir l'espèce 0 (setosa) car c'est le résultat renvoyé
pour davantage de valeurs de k au final.
La valeur de k=8 (ou 7 ou 9) semble relativement adaptée.
""" 

#%%
# Question 9

k=5    
champ_iris=[]
for x in range(10,70):
    for y in range(0,30):
        iris_test=(x/10,y/10)
        espece=KNN(iris_test, k)
        iris_test=(x//1,y//1,espece)
        champ_iris.append(iris_test)

print(len(champ_iris))

plt.axis('equal')
plt.scatter([fleur[0] for fleur in champ_iris if fleur[2]==0] , [fleur[1] for fleur in champ_iris if fleur[2]==0], color='g', label='setosa')
plt.scatter([fleur[0] for fleur in champ_iris if fleur[2]==1] , [fleur[1] for fleur in champ_iris if fleur[2]==1], color='r', label='versicolor')
plt.scatter([fleur[0] for fleur in champ_iris if fleur[2]==2] , [fleur[1] for fleur in champ_iris if fleur[2]==2], color='b', label='virginica')
plt.legend()
plt.show()

#%%

test_flowers=[data_flowers[k] for k in range(len(data_flowers)) if k%2==0]

data_flowers_2=[data_flowers[k] for k in range(len(data_flowers)) if k%2==1]

def KNN(iris,k):
    """Renvoie l'étiquette majoritaire parmi les k images les plus proches de images[i]"""
    def cle(voisin):#Clé de tri
        return Dist(iris,voisin)
    trié=sorted(data_flowers_2,key=cle)#la liste données est trié avec la clé:
    #les premiers éléments de trié sont les plus proches de images[i]
    L=[iris[2] for iris in trié[:k]]
    return Majoritaire(L)

def Mat_Confusion(k):
    C=[[0 for j in range(3)] for i in range(3)]
    for l in test_flowers:
        i=l[2]
        j=KNN(l,k) #la prédiction donné par l'algorithme KNN
        C[i][j]=C[i][j]+1
    return C

k=8
C=Mat_Confusion(k)
for i in range(3):
    print(C[i]) # affichage de C par ligne



for k in range(1,6):
    print("k=",k)
    C=Mat_Confusion(k)
    for i in range(3):
        print(C[i]) # affichage de C par ligne
