"...et on définit dans la cellule suivante une fonction `plot_dendrogram` permettant d'afficher le dendrogramme issu d'une classification calculée par la fonction `AgglomerativeClustering` de scikit-learn (on n'utilise pas la classification hiérarchique de scipy, contrairement à l'exercice 1)."
"...et on définit dans la cellule suivante une fonction `plot_dendrogram` permettant d'afficher le dendrogramme issu d'une classification calculée par la fonction `AgglomerativeClustering` de scikit-learn."
]
},
{
...
...
@@ -328,7 +328,7 @@
"m = len(Data)\n",
"editdist = np.zeros((m,m))\n",
"\n",
"# votre code ici (calcul du tableau editdist, prend approximativement 2 minutes): \n"
"# votre code ici (calcul du tableau editdist, prend une à deux minutes): \n"
# Introduction à l'apprentissage automatique: TP2 - Exercice 2
<br>
## Un problème de bioinformatique: philogénie moléculaire
<br>
L'objectif de cet exercice est d'étudier une application du partitionnement (classification non supervisée) à un problème de _bioinformatique_, la science du traitement automatique des données biologiques. Naturellement, le problème ne sera pas traité de manière exhaustive pour rester accessible. Il s'agit d'un sujet de recherche en soi.
<br>
__Avertissement__: le rédacteur du sujet n'étant pas biologiste, la présentation peut être jugée approximative par un spécialiste.
<br>
Les organismes vivants peuvent être classés selon des critères physiologiques observés: mode de respiration, de digestion, de reproduction, nombres de membres... Voir la [classification classique des espèces](https://fr.wikipedia.org/wiki/Classification_scientifique_des_esp%C3%A8ces#Classification_traditionnelle_ou_classique).
Avec les progrès du séquençage du génôme et celle des moyens de calcul, les outils informatiques permettent depuis la fin du XXème siècle de classifier le vivant à partir de données moléculaires, notamment les gènes (qui codent l'information permettant de synthétiser les protéines). Chaque gène est codé dans l'ADN par une succession de quatre nucléotides: adénine (**A**), guanine (**G**), cytosine (**C**) et thymine (**T**). Un gène est donc représenté par un mot sur cet alphabet de quatre lettres. La _phylogénie moléculaire_ permet d'établir un arbre retraçant l'évolution des espèces à partir de ces données.
En effet, dans le cadre de la théorie de l'évolution, les gènes des organismes modernes sont considérés comme étant issus de gènes ancestraux communs à plusieurs espèces. Les gènes issus du même ancètre sont dits _homologues_. L'évolution se traduit par des insertions, suppressions, ou substitutions dans le génome. Un faible nombre d'insertions, suppressions, substitutions entre deux gènes homologues indique une proximité évolutive entre les espèces auxquelles appartiennent ces gènes.
Une manière d'obtenir un arbre phylogénique est de construire le dendrogramme associé à une classification hiérarchique ascendante basé sur une distance entre des gènes homologues appartenant à différentes espèces.
Une distance possible est la _distance d'édition_.
%% Cell type:markdown id:ecdaf33c tags:
## 1. Distance d'édition
Soient $x$ et $y$ deux mots sur un alphabet.
On note $d(x,y)$ le nombre minimal d’insertions, de suppressions, ou de substitutions de caractères
pour passer du mot $x$ au mot $y$.
Par exemple, on peut passer de "mines" à "mimes" des trois manières suivantes :
* mines $\rightarrow$ mies (suppression) $\rightarrow$ mimes (insertion)
La distance $d$ est la _distance d'édition_, aussi appelée _distance de Levenshtein_.
Si vous souhaitez en savoir davantage, lisez ce [polycopié](https://members.loria.fr/FSur/enseignement/RO/poly_RO_FSur.pdf) pages 13-14 et 76-78.
La fonction suivante ([source](https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Python)) implémente l'algorithme de calcul de la distance d'édition par _programmation dynamique_, conformément aux explications du polycopié.
Des implémentations plus rapides sont disponibles dans des librairies que nous n'utiliserons pas dans cet exercice, pour éviter des problèmes d'installation.
<br>
__Si vous avez besoin d'une distance d'édition rapide pour un projet__ (potentiellement 100x plus rapide que la fonction précédente): vous pouvez installer https://pypi.org/project/editdistance/ :
`conda install editdistance` puis `import editdistance` dans votre programme Python.
%% Cell type:markdown id:5fbb2f83 tags:
__Question 1__. Calculez les distances d'édition entre différents mots de votre choix et vérifiez que la distance obtenue correspond bien à la définition.
%% Cell type:code id:d6743c96 tags:
``` python
# votre code ici:
```
%% Cell type:markdown id:1e681807 tags:
## 2. Données génétiques
On considère les séquences ADN du _gène mitochondrial du cytochrome b_ (ce gène intervient dans le métabolisme énergétique des cellules) pour douze ongulés. Ce gène est souvent utilisé en philogénétique.
Les données de cet exercice sont extraites d'un [TP à l'Université de Lille](https://www.fil.univ-lille.fr/~varre/enseignement/enseignement.html), sauf pour le cochon ([source](https://www.ebi.ac.uk/ena/browser/view/CAA39742)).
Par curiosité, on ajoute la séquence ADN correspondant à ce gène pour l'humain ([source](https://www.ncbi.nlm.nih.gov/gene?Db=gene&Cmd=ShowDetailView&TermToSearch=4519)) et le béluga (un cétacé) ([source](https://www.ebi.ac.uk/ena/browser/view/MF919123)).
Par exemple, les périssodactyles sont les ongulés dont les membres inférieurs ont un nombre impair de doigts; les artiodactyles ont un nombre pair de doigts.
%% Cell type:markdown id:3de630e6 tags:
__Question 2__ A titre d'exemple, calculez les valeurs de la distance d'édition entre quelques paires de séquences.
%% Cell type:code id:3d18b2bd tags:
``` python
# votre code ici
```
%% Cell type:markdown id:0b51133e tags:
__Remarque__. Dans le cadre de la biologie moléculaire, on calcule plutôt la distance par l'[algorithme de Needleman–Wunsch](https://en.wikipedia.org/wiki/Needleman%E2%80%93Wunsch_algorithm) qui donne un coût différents aux insertions ou suppressions selon le nucléotides inséré ou supprimé. Le calcul de la distance d'édition en est un cas particulier dans lequel toutes les insertions et suppressions ont le même coût. L'algorithme de Needleman-Wunch est une adaptation de l'algorithme de calcul de la distance d'édition par programmation dynamique.
%% Cell type:markdown id:77ed565b tags:
## 3. Construction d'un arbre phylogénétique
On commence par importer les bibliothèques utiles:
%% Cell type:code id:a46fa1c9 tags:
``` python
importtime
importnumpyasnp
importmatplotlib.pyplotasplt
fromscipy.cluster.hierarchyimportdendrogram
fromsklearn.clusterimportAgglomerativeClustering
%matplotlibnotebook
%matplotlibinline
```
%% Cell type:markdown id:ff5c683c tags:
...et on définit dans la cellule suivante une fonction `plot_dendrogram` permettant d'afficher le dendrogramme issu d'une classification calculée par la fonction `AgglomerativeClustering` de scikit-learn (on n'utilise pas la classification hiérarchique de scipy, contrairement à l'exercice 1).
...et on définit dans la cellule suivante une fonction `plot_dendrogram` permettant d'afficher le dendrogramme issu d'une classification calculée par la fonction `AgglomerativeClustering` de scikit-learn.
# Create linkage matrix and then plot the dendrogram
# create the counts of samples under each node
counts=np.zeros(model.children_.shape[0])
n_samples=len(model.labels_)
fori,mergeinenumerate(model.children_):
current_count=0
forchild_idxinmerge:
ifchild_idx<n_samples:
current_count+=1# leaf node
else:
current_count+=counts[child_idx-n_samples]
counts[i]=current_count
linkage_matrix=np.column_stack(
[model.children_,model.distances_,counts]
).astype(float)
# Plot the corresponding dendrogram
dendrogram(linkage_matrix,**kwargs)
```
%% Cell type:markdown id:ff977620 tags:
__Question 3__. Calculez la matrice des distances des gènes deux à deux. Il faut déterminer un tableau `numpy` $D$ de taille $14 \times 14$ (14 gènes) tel que $D(i,j)$ est la distance d'édition entre le gène $i$ et le gène $j$.
Gagnez du temps en remarquant que le tableau est symétrique et que les termes diagonaux sont nuls.
Ensuite, affichez cette matrice.
%% Cell type:code id:573eb9a7 tags:
``` python
m=len(Data)
editdist=np.zeros((m,m))
# votre code ici (calcul du tableau editdist, prend approximativement 2 minutes):
# votre code ici (calcul du tableau editdist, prend une à deux minutes):
```
%% Cell type:code id:32be4a6c tags:
``` python
# affichage
print(Names)
print("\nmatrice des distances:")
print(editdist)
#print(dist)
```
%% Cell type:markdown id:58cf4d54 tags:
La fonction `AgglomerativeClustering` de scikit-learn permet de calculer des classifications hiérarchiques ascendantes à l'aide des critères de Ward, single-linkage, complete-linkage, average-linkage.
__Question 4__. Pourquoi peut-on utiliser dans ce problème les critères single-linkage, complete-linakge, average-linkage, mais pas Ward?
%% Cell type:markdown id:bc7ddcdf tags:
<fontcolor=red>
_Votre réponse ici_.
</font>
%% Cell type:markdown id:ad775f35 tags:
__Question 5__. Observez les dendrogrammes selon ces trois critères (utilisez le modèle ci-dessous), et commentez.