CCINP Informatique Commune PSI 2019Sujet, corrigé et rapport du jury
- Bases de données : requêtes SQL, jointures, COUNT et GROUP BY
- Représentation des nombres et taille mémoire
- Programmation Python : listes et tableaux Numpy
- Complexité des algorithmes
- Algorithmes de tri : tri fusion et tri par insertion
- Récursivité
- Apprentissage : K plus proches voisins et classification bayésienne
Téléchargements
Présentation du sujet
AccessibleIntelligence artificielle et diagnostic médical : K plus proches voisins et classification naïve bayésienneAfficher ou masquer la section
Présentation du sujet
AccessibleLe sujet part d'une base de données décrivant le bassin et le rachis lombaire de patients pour prédire si un nouveau patient est sain ou atteint d'une hernie discale ou d'un spondylolisthésis. Il traite d'abord l'analyse des données (requêtes SQL, stockage avec Numpy, représentations graphiques), puis deux méthodes d'apprentissage : les K plus proches voisins avec un tri et une matrice de confusion, et la classification naïve bayésienne avec une loi gaussienne.
- 1Partie I : présentationContexte de l'intelligence artificielle en santé et objectif du problème, sans question.
- 2Partie II : analyse des donnéesRequêtes SQL avec jointure et agrégation, intérêt de Numpy, taille mémoire des données, séparation en groupes et lecture de diagrammes (Q1 à Q8).
- 3Partie III.1 : méthode KNNNormalisation, recherche du minimum et du maximum, distances euclidiennes, tri fusion récursif, matrice de confusion et choix de K (Q9 à Q16).
- 4Partie III.2 : classification naïve bayésienneMoyenne et variance en complexité linéaire, synthèse par groupe, densité gaussienne, probabilité d'appartenance, prédiction et comparaison des deux méthodes (Q17 à Q23).
Accessible. Le jury indique que l'épreuve a été très bien réussie par la majorité des candidats et que beaucoup de questions étaient des questions de cours.
L'épreuve en chiffres
Moyenne 10,92 / 20 · écart-type 4,07 · 5 127 présents · où vous situez-vous ?Afficher ou masquer la section
L'épreuve en chiffres
- Moyenne
- 10,92/ 20
- Écart-type
- 4,07
- Présents
- 5 127
- Coefficient
- 6
- Durée
- 3 h
Votre note sur 20 à ce sujet, en conditions de concours.
Source : document officiel du concours, épreuve du 3 mai 2019. Notes publiées par le concours (après harmonisation le cas échéant). Courbe : estimation par une loi normale.
Ce qu'a observé le jury
6 erreurs relevéesSyntaxe SQL imprécise · Intérêt de Numpy et taille mémoire · Minimum et maximum en une seule boucleAfficher ou masquer la section
Ce qu'a observé le jury
6 erreurs relevéesLe sujet couvrait l'ensemble des compétences du programme d'informatique, avec de nombreuses questions de cours. L'épreuve a été très bien réussie par la majorité des candidats, avec assez peu d'erreurs de syntaxe en Python et en SQL. Quelques maladresses reviennent : confusion entre / et //, suites de if au lieu de elif, else inutiles.
Les erreurs les plus sanctionnées
- 1Syntaxe SQL impréciseQ1, Q2
Guillemets oubliés autour des chaînes ou ajoutés autour des noms de champs, et champs non rattachés à leur table dans la jointure.
- 2Intérêt de Numpy et taille mémoireQ4, Q5
L'intérêt de Numpy tient à l'optimisation des opérations matricielles ; pour la mémoire, il faut connaître la taille des entiers et des flottants et le lien entre bit et octet.
« Beaucoup de candidats ne connaissent pas le lien entre 1 bit et 1 octet. »
- 3Minimum et maximum en une seule boucleQ10
Cette fonction classique devait trouver les deux valeurs en un seul parcours.
« Un nombre non négligeable de candidats n'arrivent pas à réaliser cette fonction correctement. »
- 4Somme non réinitialiséeQ11
Dans le calcul des distances euclidiennes, la somme doit être remise à zéro pour chaque ligne du tableau.
« De trop nombreux candidats ne pensent pas à initialiser la somme à chaque itération. »
- 5Complexité mal compriseQ12, Q17
Le tri fusion a une meilleure complexité que le tri par insertion mais n'est pas en place ; en Q17, appeler la moyenne dans la boucle fait perdre la complexité linéaire.
« Trop de candidats confondent la complexité rédactionnelle du programme avec sa complexité algorithmique. »
- 6Probabilités mal initialiséesQ20
Il fallait comprendre la spécification pour initialiser les probabilités et boucler sur les bonnes grandeurs.
« ce fut la question la moins bien traitée du sujet »
Ce qui a été bien réussi
- L'interprétation des diagrammes (Q8) est bien faite dans l'ensemble.
- La matrice de confusion (Q15) est comprise par la majorité des candidats.
- La fonction gaussienne (Q19) et la fonction de prédiction (Q21) n'ont pas posé de réelle difficulté.
Conseils du jury
- Lire chaque question en entier pour n'en oublier aucune partie.
- Répondre de façon brève aux questions d'analyse et commenter un algorithme en une ou deux lignes par partie.
- Écrire des algorithmes simples avec des noms de variables explicites, et remplacer des lignes répétées par une boucle.
- Savoir lire une documentation et utiliser la syntaxe Numpy d'extraction de colonnes.
- Utiliser une encre foncée et le brouillon pour les algorithmes compliqués afin de limiter les ratures.
- S'entraîner sur les derniers sujets et lire les derniers rapports.
Synthèse rédigée par WikiPrépa à partir du rapport officiel du jury (à télécharger en PDF). Les citations sont extraites du rapport.
Ces sujets peuvent vous intéresser
Lecture du sujet en ligne
L'énoncé complet, avec les formules et les figures, sans ouvrir le PDF.Afficher ou masquer la section
Lecture du sujet en ligne
ÉPREUVE SPÉCIFIQUE - FILIÈRE PSI
INFORMATIQUE
Vendredi 3 mai :
8h -
11h
Abstract
N.B. : le candidat attachera la plus grande importance à la clarté, à la précision et à la concision de la rédaction. Si un candidat est amené à repérer ce qui peut lui sembler être une erreur d'énoncé, il le signalera sur sa copie et devra poursuivre sa composition en expliquant les raisons des initiatives qu'il a été amené à prendre.
Les calculatrices sont interdites
Le sujet est composé de trois parties indépendantes.
Les différents algorithmes doivent être rendus dans leur forme définitive sur la copie en respectant les éléments de syntaxe du langage (les brouillons ne sont pas acceptés).
Il est demandé au candidat de bien vouloir rédiger ses réponses en précisant bien le numéro de la question traitée et, si possible, dans l'ordre des questions. Bien que largement indépendante, la partie III fait appel aux données et à la définition de fonctions définies dans la partie II.
La réponse ne doit pas se cantonner à la rédaction de l'algorithme sans explication, les programmes doivent être expliqués et commentés.
Annexe : page 12
Intelligence Artificielle - Application en médecine
Partie I - Présentation
L'Intelligence Artificielle progresse également dans le domaine de la santé. Le logiciel Watson développé par IBM peut analyser les données d'un patient : ses symptômes, ses consultations médicales, ses antécédents familiaux, ses données comportementales, ses résultats d'examen, etc. Il établit alors une prévision de diagnostic le plus vraisemblable et propose des options de traitement en s'appuyant sur une base de données établie sur un grand nombre de patients.
Objectif

- analyse et représentation des données,
- prédiction à l'aide de la méthode KNN,
- apprentissage et prédiction à l'aide de la méthode dite «Naïve Bayes ».
Partie II - Analyse des données
- id : identifiant d'un individu (entier), clé primaire;
- nom : nom du patient (chaîne de caractères);
- prenom : prénom du patient (chaîne de caractères);
- adresse : adresse du patient (chaîne de caractères);
- email : (chaîne de caractères);
- naissance : année de naissance (entier).
| PATIENT |
| id |
| nom |
| prenom |
| adresse |
| naissance |
- id : identifiant d'un ensemble de propriétés médicales (entier), clé primaire;
- data1 : donnée (flottant);
- data2 : donnée (flottant);
- ...;
- idpatient : identifiant du patient représenté par l'attribut id de la table PATIENT (entier);
- etat : description de l'état du patient (chaîne de caractères).
Q1. Écrire une requête SQL permettant d'extraire les identifiants des patients ayant une « hernie discale
Q4. Citer un intérêt d'utiliser la bibliothèque de calcul numérique Numpy quand les tableaux sont de grande taille.
- angle d'incidence du bassin en
^∘ ; - angle d'orientation du bassin en
^∘ ; - angle de lordose lombaire en
^∘ ; - pente du sacrum en
^∘ ; - rayon du bassin en mm;
- distance algébrique de glissement de spondylolisthésis en mm.
label_attributs = ['incidence_bassin', 'orientation_bassin', 'angle_lordose', 'pente_sacrum', 'rayon_bassin', 'glissement_spon'].
| incidence_bassin | orientation_bassin | angle_lordose | pente_sacrum | rayon_bassin | glissement_spon |
| 63,03 | 22,55 | 39,61 | 40,48 | 98,67 | -0,25 |
| 39,06 | 10,06 | 25,02 | 29,0 | 114,41 | 4,56 |
| 68,83 | 22,22 | 50,09 | 46,61 | 105,99 | -3,53 |
| 69,3 | 24,65 | 44,31 | 44,64 | 101,87 | 11,21 |
| 49,71 | 9,65 | 28,32 | 40,06 | 108,17 | 7,92 |
| 40,25 | 13,92 | 25,12 | 26,33 | 130,33 | 2,23 |
| 48,26 | 16,42 | 36,33 | 31,84 | 94,88 | 28,34 |
On obtient, à partir des données exploitées, les courbes de la figure 2 (zoom sur la figure 3).


Pour réaliser cette figure, il faut séparer les données en fonction de l'état du patient afin d'affecter un symbole par état. Ceci revient à classer les patients en plusieurs groupes.
fig = plt.figure()
mark = ['o','x','*']
label_attributs = ['incidence_bassin (deg)', 'orientation_bassin (deg)',
'angle_lordose (deg)', 'pente_sacrum (deg)',
'rayon_bassin (mm)', 'glissement_spon (mm)']
groupes = separationParGroupe(data,etat)
for i in range (len(groupes)):
groupes[i] = array(groupes[i])
n=len (data[0])
for i in range(n):
for j in range(n):
ax1 = plt.subplot(ARGS1)
plt.ylabel(label_attributs[j]) #mettre un label à l'axe y
if TEST :
for k in range(len(groupes)):
plt.xlabel(label_attributs[i]) #mettre un label à l'axe x
ax1.scatter(ARGS2)
else:
plt.xlabel("Nombre de patients") #mettre un label à l'axe x
ax1.hist(ARGS3)
plt.show()
La documentation du module matplotlib (plt) renseigne sur les arguments des fonctions subplot, scatter et hist.
ax1 = plt.subplot(a,b,k)
Cette instruction permet de sélectionner parmi un tableau de figures de taille a (nombre de lignes), b (nombre de colonnes), la
ax1.scatter(datax, datay, marker=mark[k])
Cette commande permet de tracer sur la sous-figure ax1 un nuage de points d'abscisses un vecteur datax et d'ordonnées un vecteur datay avec un symbole à choisir parmi ceux de la liste mark.
ax1. hist(datax)
Cette commande permet de tracer un histogramme des données datax sur la sous-figure ax1.
Q7. Définir les arguments ARGS1, ARGS2, ARGS3 ainsi que la condition TEST définis dans le script précédent permettant d'obtenir la figure 2.
Partie III - Apprentissage et prédiction
III. 1 - Méthode KNN
On note
Préparation des données
Une technique de normalisation consiste à rechercher pour chaque attribut
Détermination des
K plus proches voisins
- la distance entre le
n -uplet à classer et unn -uplet connu (on trie par ordre croissant sur ces valeurs); - la valeur de l'état correspondant au
n -uplet connu.
def tri(T):
if len (T) <= 1:
return T
else:
m = len(T)//2
tmp1 = []
for x in range(m):
tmp1.append(T[x])
tmp2 = []
for x in range(m,len(T)):
tmp2.append(T[x])
return fct(tri(tmp1),tri(tmp2))
def fct(T1,T2):
if T1 == []:
............. #ligne 1 à compléter
if T2 == []:
............ #ligne 2 à compléter
if T1[0][0] < T2[0][0]:
return [T1[0]]+fct(T1[1:],T2)
else:
#ligne 3 à compléter
def KNN(data,etat,z,K,nb):
#partie 1
T = []
dist = distance(z,data)
for i in range(len(dist)):
T.append([dist[i],i])
tri(T)
#partie 2
select = [0]*nb
for i in range(K):
select[etat[T[i][1]]]+=1
#partie 3
ind = 0
res = select[0]
for k in range(1,nb):
if select[k] > res:
res = select[k]
ind = k
return ind
Validation de l'algorithme
On définit la fonction suivante qui renvoie une matrice appelée "matrice de confusion".
def test_KNN(datatest, etattest, data, etat,K,nb):
etatpredit = []
for i in range(len(datatest)):
res = KNN(data,etat,datatest[i],K,nb)
etatpredit.append(res)
mat = np.zeros((nb,nb))
for i in range(len(etattest)):
mat[etattest[i],etatpredit[i]] += 1
return mat

III. 2 - Méthode de classification naïve bayésienne
On suppose que chaque attribut
L'appartenance de la donnée
Le théorème de Bayes permet de déterminer la probabilité qu'une donnée appartienne à un groupe
-
P(Y = y_j|X_0 = x_0, X_1 = x_1, …, X_(n − 1) = x_(n − 1)) est la probabilité d'appartenir au groupey_j sachant que les différentes variables aléatoiresX_i prennent respectivement les valeursx_i , -
P(Y = y_j) est la probabilité d'appartenir au groupey_j , -
P(X_0 = x_0, X_1 = x_1, …, X_(n − 1) = x_(n − 1)|Y = y_j) est la probabilité que les différentes variables aléatoiresX_i prennent respectivement les valeursx_i sachant que la donnée appartient au groupey_j , -
P(X_0 = x_0, X_1 = x_1, …, X_(n − 1) = x_(n − 1)) est la probabilité que les différentes variables aléatoiresX_i prennent respectivement les valeursx_i .
Des lois de probabilités diverses sont utilisées pour estimer
Apprentissage
On rappelle que, pour un vecteur
Q17. Écrire deux fonctions de complexité linéaire moyenne
|
|
|
|
|
|
|
|
| etat
|
|
|
|
|
|
|
| etat
|
|
|
|
|
|
|
| etat
|
|
|
|
|
|
|
Prédiction
Q19. Écrire une fonction gaussienne(a,moy,v) qui calcule la probabilité selon une loi gaussienne de moyenne moy et de variance
La décision de l'appartenance à un groupe particulier est prise en déterminant le maximum parmi les probabilités de groupes déterminées.
Q21. Écrire une fonction prediction, dont vous préciserez les arguments, qui renvoit le numéro du groupe auquel appartient un élément
L'algorithme mis en place peut être testé sur le jeu de 100 données test utilisé pour l'algorithme KNN dont on connaît déjà l'appartenance à chacun des groupes. On obtient alors la matrice de confusion suivante :
Q23. Calculer le pourcentage de réussite de la méthode KNN , à partir de la matrice de confusion pour
FIN
ANNEXE
Rappels des syntaxes en Python
| Python | |||||
| tableau à une dimension |
|
||||
| accéder à un élément |
|
||||
| ajouter un élément | L. append(5) uniquement sur les listes | ||||
| tableau à deux dimensions (matrice) | M=array(([1,2,3],[3,4,5])) | ||||
| accéder à un élément | M [1,2] donne 5 | ||||
| extraire une portion de tableau (2 premières colonnes) | M[:,0:2] | ||||
| extraire la colonne i | M[:,i] | ||||
| extraire la ligne i | M[i,:] | ||||
| tableau de 0 ( 2 lignes, 3 colonnes) | zeros((2,3)) | ||||
| dimension d'un tableau T de taille (
|
T. shape donne [i,j] | ||||
| produit matrice-vecteur |
|
||||
| séquence équirépartie quelconque de 0 à 10.1 (exclus) par pas de 0.1 | arange(0,10.1,0.1) | ||||
| définir une chaîne de caractères | mot='Python' | ||||
| taille d'une chaîne | len(mot) | ||||
| extraire des caractères | mot[2:7] | ||||
| boucle For |
|
||||
| condition If |
|
||||
| définir une fonction qui possède un argument et renvoie 2 résultats |
|
||||
| tracé d'une courbe de deux listes de points
|
plot(x,y) | ||||
| tracé d'une courbe de trois listes de points
|
gca(projection='3d').plot(x,y,z) | ||||
| ajout d'un titre sur les axes d'une figure |
|
||||
| ajout d'un titre principe sur une figure | title(texte) |
Questions fréquentes
4 questionsSur quoi porte le sujet d'informatique CCINP PSI 2019 ?Afficher ou masquer la section
Questions fréquentes
4 questionsSur quoi porte le sujet d'informatique CCINP PSI 2019 ?
Sur la prédiction d'une pathologie du rachis à partir d'une base de données médicale : requêtes SQL, manipulation de tableaux Numpy, méthode des K plus proches voisins avec tri fusion, puis classification naïve bayésienne.
Le sujet d'informatique CCINP PSI 2019 est-il difficile ?
Le jury indique qu'il a été très bien réussi par la majorité des candidats, avec beaucoup de questions de cours. La question la moins bien traitée est la Q20, sur le calcul des probabilités d'appartenance à un groupe.
Quelles erreurs le jury a-t-il relevées en informatique CCINP PSI 2019 ?
Des guillemets mal placés en SQL, le lien entre bit et octet ignoré, une somme non réinitialisée dans une boucle, la confusion entre longueur du code et complexité, et des confusions entre / et //.
Quels algorithmes réviser pour l'informatique CCINP PSI 2019 ?
Les requêtes SQL avec jointure et GROUP BY, la recherche de minimum et maximum, le tri fusion récursif, le calcul de moyenne et de variance en complexité linéaire et la méthode des K plus proches voisins.
Pas de description pour le moment
