ift7025-projet/Code/Rapport-Partiel.ipynb

779 lines
19 KiB
Text
Raw Normal View History

2019-03-23 17:45:40 +00:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Introduction\n",
"\n",
"## Définitions\n",
"\n",
"La **matrice de confusion** est un tableau où on décompte les valeurs réelle O et prédites S pour chaque observation du jeu de données dans un problème de classification. Par sa conception, on peut valider rapidement le nombre d'observations où la prédiction est égale à la valeur réelle sur la diagonale de la matrice. Par convention, on place les valeurs prédites à la verticale et les valeurs observées à l'horizontale. Lorsque le nombre de modalités de la variable prédite est de deux, on a un problème de classification binaire et on obtient alors le décompte des vrais positifs, faux positifs, faux négatifs et vrais négatifs.\n",
"\n",
"La **précision** correspont à la proportion d'observations où la prédiction et la valeur réelle est dans une même classe par rapport au nombre d'observations où la prédiction est dans cette classe\n",
"\n",
"$$ \\text{Précision}_c = \\frac{\\sum_{i=1}^N 1_{s_i=c}1_{o_i=c}}{\\sum_{i=1}^N 1_{s_i=c}}$$\n",
"\n",
"Le **rappel** correspond à la proportions d'observations où la prédiction est dans une classe par rapport au nombre d'observations où la valeur réelle est dans cette classe.\n",
"\n",
"$$ \\text{Rappel}_c =  \\frac{\\sum_{i=1}^N 1_{s_i=c}}{\\sum_{i=1}^N 1_{o_i=c}}$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Librairies utilisées\n",
"\n",
"Le project actuel est programmé dans le langage Python 3, et ce rapport est produit à l'aide de Jupyter Notebook. Seule les librairie standard `numpy` et `math` est utilisée, les autres ont été développées dans le cadre de ce projet."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# Librairies standard\n",
"import numpy as np\n",
"import math\n",
"# Librairies développées par l'étudiant\n",
"import load_datasets as ld\n",
"import BayesNaif\n",
"import Knn\n",
"import metrics"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Jeux de données\n",
"\n",
"Ce projet utilise 3 jeux de données: [Iris](https://archive.ics.uci.edu/ml/datasets/Iris), [MONKS](https://archive.ics.uci.edu/ml/datasets/MONK's+Problems) et [Congressional Voting Records Dataset](https://archive.ics.uci.edu/ml/datasets/Congressional+Voting+Records)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Algorithme des k plus proches voisins (kNN)\n",
"\n",
"Dans cette section, on présente les résultats obtenus pour l'algorithme des k plus proches voisins. Ce n'est pas un algorithme d'apprentissage à proprement parler, car il n'y a aucun modèle d'entrainé. On prédit la classe d'un nouvel élément en recherchant les k plus proches voisins selon une métrique choisie. Dans notre cas, nous utiliserons la distance de Minkowski, qui est une généralisation de la distance euclidienne et de la distance de Manhattan à l'aide d'un paramètre p. \n",
"\n",
"$${\\displaystyle D\\left(X,Y\\right)=\\left(\\sum _{i=1}^{N}|o_{i}-s_{i}|^{p}\\right)^{1/p}}$$\n",
"\n",
"On peut ainsi itérer sur différentes valeurs de ce paramètre pour trouver la mesure la plus adaptée au problème, tout en réutilisant la même fonction. Cette métrique s'utilise aurant pour des domaines de valeurs continus que discrets.\n",
"\n",
"## Pseudocode\n",
"\n",
"- Entrainement\n",
"\n",
"```\n",
"Copier le jeu d'entrainement et les étiquettes d'entrainement dans la mémoire du modèle\n",
"```\n",
"\n",
"- Prédiction Knn\n",
"```\n",
"Pour une observation x_i:\n",
" Entrainement <- Vrai si on fait le premier entrainement\n",
" T = copie jeu d'entrainement\n",
" L = copie des étiquettes d'entrainement\n",
" K = tableau de paires (point, distance) de longueur k\n",
" Si Entrainement:\n",
" Enlever x de T et l'étiquette de x_i de L\n",
" Pour chaque observation t_j, j=[1,k]) de T:\n",
" d(x_i,t_i) = distance de Minkowski entre x_i et t_j\n",
" K[j] <- (t_i,d(x_i,t_j)) \n",
" Pour chaque observation t_j, j=[k+1,N-1] de T:\n",
" d(x,t_i) = distance de Minkowski entre x_i et t_j\n",
" d_max <- distance maximum dans K\n",
" pos_d_max <- position de d_max dans K\n",
" Si d(x_i,t_j) < d_max\n",
" Remplacer le point K[pos_d_max] par (t_j,d(x,t_j))\n",
" s <- mode des valeurs des étiquettes des points dans K\n",
" retourner s\n",
"```\n",
"\n",
"- Test\n",
"\n",
"```\n",
"Pour chaque observation x_i, i=1,N:\n",
" S_i <- Prédiction(x_i)\n",
"M <- matrice de confusion avec les étiquettes d'entrainement et les étiquettes S\n",
"Calculer les métriques depuis M\n",
"```\n",
"\n",
"- Validation croisée\n",
"\n",
"```\n",
"K <- Valeurs à tester pour le nombre de voisins\n",
"Pour un jeu d'entrainement x\n",
"Permuter aléatoirement les nombre de 1 à N\n",
"Diviser la permutation en L groupes approximativement égaux\n",
"Pour l dans L:\n",
" \n",
"\n",
"Pour k dans K:\n",
" Pour l dans L:\n",
" Effectuer l'entrainement avec k voisins, x[sans l] comme jeu d'entrainement \n",
" Effectuer le test avec x[l] comme jeu de validation\n",
" Calculer l'exactitude\n",
" Prendre la moyenne des exactitudes\n",
"Prendre le k avec la meilleur exactitude moyenne\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Iris Dataset"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On utilise 70% des données pour le jeu d'entrainement et 30% des données pour le jeu de test"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"train1, train_labels1, test1, test_labels1 = ld.load_iris_dataset(train_ratio = 0.7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On crée un premier modèle afin d'identifier la meilleure valeur de k"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/francois/gitea/ift7025-projet/Code/metrics.py:40: RuntimeWarning: invalid value encountered in double_scalars\n",
" precision.append(cm[label_num,label_num] / sum(cm[:,label_num]))\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Le meilleur k est: 9\n"
]
}
],
"source": [
"findbest_Knn = Knn.Knn()\n",
"meilleur_k = findbest_Knn.set_best_k(train1, train_labels1, nb_split=5, k_potentiel=range(2,12))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On crée maintenant un nouveau modèle où on initialise la valeur de K avec celle trouvée précédemment"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"myKnn = Knn.Knn(meilleur_k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On effectue l'entrainement du modèle (la copie du jeu d'entrainement et des étiquettes en mémoire) et on obtient les mesures de validation pour ce jeu d'entraînement. Les valeurs des métriques de précision et de rappel sont calculées pour chacune des étiquettes."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[35. 0. 0.]\n",
" [ 0. 32. 1.]\n",
" [ 0. 3. 34.]]\n",
"\n",
"Accuracy:\n",
"0.9619047619047619\n",
"\n",
"Precision:\n",
"[1.0, 0.9142857142857143, 0.9714285714285714]\n",
"\n",
"Recall\n",
"[1.0, 0.9696969696969697, 0.918918918918919]\n"
]
}
],
"source": [
"training_iris_knn = myKnn.train(train1, train_labels1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On effectue maintenant le test avec l'échantillon de test"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[15. 0. 0.]\n",
" [ 0. 16. 1.]\n",
" [ 0. 1. 12.]]\n",
"\n",
"Accuracy:\n",
"0.9555555555555556\n",
"\n",
"Precision:\n",
"[1.0, 0.9411764705882353, 0.9230769230769231]\n",
"\n",
"Recall\n",
"[1.0, 0.9411764705882353, 0.9230769230769231]\n"
]
}
],
"source": [
"test_iris_knn = myKnn.test(test1, test_labels1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Monks Dataset"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"train2, train_labels2, test2, test_labels2 = ld.load_monks_dataset(1)\n",
"train3, train_labels3, test3, test_labels3 = ld.load_monks_dataset(2)\n",
"train4, train_labels4, test4, test_labels4 = ld.load_monks_dataset(3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Premier sous-ensemble"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On identifie la meilleure valeur de k"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Le meilleur k est: 4\n"
]
}
],
"source": [
"findbest_Knn = Knn.Knn()\n",
"meilleur_k = findbest_Knn.set_best_k(train2, train_labels2, nb_split=5, k_potentiel=range(2,12))"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"myKnn2 = Knn.Knn(meilleur_k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue l'entrainement du modèle"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[32. 30.]\n",
" [16. 46.]]\n",
"\n",
"Accuracy:\n",
"0.6290322580645161\n",
"\n",
"Precision:\n",
"[0.6666666666666666, 0.6052631578947368]\n",
"\n",
"Recall\n",
"[0.5161290322580645, 0.7419354838709677]\n"
]
}
],
"source": [
"training_monks1_knn = myKnn2.train(train2, train_labels2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue maintenant le test avec l'échantillon de test"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[129. 87.]\n",
" [ 38. 178.]]\n",
"\n",
"Accuracy:\n",
"0.7106481481481481\n",
"\n",
"Precision:\n",
"[0.7724550898203593, 0.6716981132075471]\n",
"\n",
"Recall\n",
"[0.5972222222222222, 0.8240740740740741]\n"
]
}
],
"source": [
"test_monks1_knn = myKnn2.test(test2, test_labels2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Second sous-ensemble"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On identifie la meilleure valeur de k"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Le meilleur k est: 5\n"
]
}
],
"source": [
"findbest_Knn = Knn.Knn()\n",
"meilleur_k = findbest_Knn.set_best_k(train3, train_labels3, nb_split=5, k_potentiel=range(2,12))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"myKnn3 = Knn.Knn(meilleur_k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue l'entrainement du modèle"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[104. 1.]\n",
" [ 63. 1.]]\n",
"\n",
"Accuracy:\n",
"0.621301775147929\n",
"\n",
"Precision:\n",
"[0.6227544910179641, 0.5]\n",
"\n",
"Recall\n",
"[0.9904761904761905, 0.015625]\n"
]
}
],
"source": [
"training_monks2_knn = myKnn3.train(train3, train_labels3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue maintenant le test avec l'échantillon de test"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[286. 4.]\n",
" [133. 9.]]\n",
"\n",
"Accuracy:\n",
"0.6828703703703703\n",
"\n",
"Precision:\n",
"[0.6825775656324582, 0.6923076923076923]\n",
"\n",
"Recall\n",
"[0.9862068965517241, 0.06338028169014084]\n"
]
}
],
"source": [
"test_monks2_knn = myKnn3.test(test3, test_labels3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Troisième sous-ensemble"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On identifie la meilleure valeur de k"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Le meilleur k est: 5\n"
]
}
],
"source": [
"findbest_Knn = Knn.Knn()\n",
"meilleur_k = findbest_Knn.set_best_k(train4, train_labels4, nb_split=5, k_potentiel=range(2,12))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"myKnn4 = Knn.Knn(meilleur_k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue l'entrainement du modèle"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[27. 35.]\n",
" [ 1. 59.]]\n",
"\n",
"Accuracy:\n",
"0.7049180327868853\n",
"\n",
"Precision:\n",
"[0.9642857142857143, 0.6276595744680851]\n",
"\n",
"Recall\n",
"[0.43548387096774194, 0.9833333333333333]\n"
]
}
],
"source": [
"training_monks3_knn = myKnn4.train(train4, train_labels4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue maintenant le test avec l'échantillon de test"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[ 99. 105.]\n",
" [ 8. 220.]]\n",
"\n",
"Accuracy:\n",
"0.7384259259259259\n",
"\n",
"Precision:\n",
"[0.9252336448598131, 0.676923076923077]\n",
"\n",
"Recall\n",
"[0.4852941176470588, 0.9649122807017544]\n"
]
}
],
"source": [
"test_monks3_knn = myKnn4.test(test4, test_labels4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Congressional Voting Records Dataset"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"train5, train_labels5, test5, test_labels5 = ld.load_congressional_dataset(0.7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On identifie la meilleure valeur de k"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Le meilleur k est: 9\n"
]
}
],
"source": [
"findbest_Knn = Knn.Knn()\n",
"meilleur_k = findbest_Knn.set_best_k(train5, train_labels5, nb_split=5, k_potentiel=range(2,12))"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"myKnn5 = Knn.Knn(meilleur_k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue l'entrainement du modèle"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[ 76. 33.]\n",
" [ 15. 180.]]\n",
"\n",
"Accuracy:\n",
"0.8421052631578947\n",
"\n",
"Precision:\n",
"[0.8351648351648352, 0.8450704225352113]\n",
"\n",
"Recall\n",
"[0.6972477064220184, 0.9230769230769231]\n"
]
}
],
"source": [
"training_congres_knn = myKnn5.train(train5, train_labels5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- On effectue maintenant le test avec l'échantillon de test"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrice de confusion:\n",
"[[42. 17.]\n",
" [ 6. 66.]]\n",
"\n",
"Accuracy:\n",
"0.8244274809160306\n",
"\n",
"Precision:\n",
"[0.875, 0.7951807228915663]\n",
"\n",
"Recall\n",
"[0.711864406779661, 0.9166666666666666]\n"
]
}
],
"source": [
"test_congres_knn = myKnn5.test(test5, test_labels5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Algorithme Naive Bayes"
]
},
{
"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.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}