Méthodes de recherche de similarités dans les séquences biologiques Module MIG Eric Tannier, INSA 4BIM, 2016-2017 [email protected] Cours/TD les mardi matin Deuxième série de cours au deuxième semestre Projet commun à la fin Support (ce document) disponible à partir de ma page internet Buts de la comparaison de séquences: En général, tout ce qui peut concerner la comparaison de textes, ou plus généralement de séquences linéaires - Fouille de données (de grep à Google) - Comparaison de fichiers (diff) - Linguistique comparée - Études littéraires - Analyse de séquences musicales - Détection de plagiat En bioinformatique, comparaisons de séquences protéiques ou nucléiques pour la détection de l'homologie - prédiction de fonction - phylogénie - biodiversité - annotation - assemblage Activité quotidienne de milliers de bioinformaticiens - utilisation de méthodes et logiciels standards - domaine de recherche en informatique toujours actif, toujours demandeur de nouvelles fonctionnalités et performances, publications, conférences... Spécificités bioinformatiques de la comparaison de séquences - les séquences sont très grandes, très nombreuses, fixes, sur des alphabets petits - on recherche ou compare des séquences qui se ressemblent mais peuvent différer jusqu'à extinction de la ressemblance - le processus de différenciation des séquences est issu de mécanismes biologiques Les méthodes, générales par certains aspects, sont adaptées à ces spécificités Plan du cours 1/ Rappel sur l'homologie et la similarité 2/ Recherche de séquences exactes 3/ Recherche de séquences approchées, alignement 4/ Méthodes et logiciels actuels Plan du cours 1/ Rappel sur l'homologie et la similarité 2/ Recherche de séquences exactes 3/ Recherche de séquences approchées, alignement 4/ Méthodes et logiciels actuels Rappel sur l'homologie et la similarité Appliquées aux séquences Ce cours est consacré aux recherches de similarités entre séquences, en vue de détecter des homologies. Rappel sur l'homologie et la similarité Appliquées aux séquences Deux séquences sont homologues si elles sont issues d'un ancêtre commun. C'est valable à plusieurs niveaux - deux génomes peuvent être homologues - deux chromosomes peuvent être homologues - deux gènes peuvent être homologues - deux nucléotides peuvent être homologues Les niveaux sont indépendants - deux génomes peuvent être homologues sans que leurs chromosomes soient homologues - deux gènes peuvent être homologues sans que leurs nucléotides soient homologues Rappel sur l'homologie et la similarité Appliquées aux séquences La recherche de similarité de séquences biologiques a pour but la détermination de l'homologie. On se base sur l'hypothèse d'une corrélation entre similarité et homologie. Cette corrélation a des limites: - deux séquences peuvent être homologues sans être similaires - deux séquences peuvent être similaires sans être homologues (convergence, faible complexité, seuil statistique de similarité) La similarité est une notion quantitative L'homologie est une notion qualitative Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCG CCGATACTTGCGGCTCAGAT Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCG CCGATACTTGCGGCTCAGAT Composition : nucléotides Longueur : 20 Sites correspondants : 7 Si les séquences ne sont pas homologues, la probabilité d'avoir un site correspondant est ¼. L'espérance du nombre de sites correspondants est donc 5. Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCG CCGATACTTGCGGCTCAGAT Composition : nucléotides Longueur : 20 Sites correspondants : 7 Le probabilité d'en avoir au moins 7 est ~0.2 (loi binomiale) On ne peut pas en déduire l'homologie (ni l'absence d'homologie) Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? ATATATATATATATATATAT ATATATATATATATATATAT Composition : nucléotides Longueur : 20 Sites correspondants : 20 La probabilité que cette similarité soit due au hasard est très faible Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? ATATATATATATATATATAT ATATATATATATATATATAT Pourtant, on ne peut pas en déduire l'homologie Ces séquences de faibles complexité sont courantes. (Définition intuitive de la complexité: peut-on exprimer cette séquence de façon plus compacte, comme 10xAT) (Attention à ne pas confondre avec la complexité des algorithmes, qu'on va aborder bientôt) Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCG CTAGCCAGTACGTAGCATCG Composition : nucléotides Longueur : 20 Sites correspondants : 19 Probabilité que cette similarité soit due au hasard: 0.00000000001 Peut-on en déduire l'homologie? Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCG CTAGCCAGTACGTAGCATCG Mais comment a-t-on trouvé cette similarité? Si c'est dans un génome de taille 3Gb La probabilité de trouver par hasard un mot donné devient ~0.2 Et on ne peut pas en déduire l'homologie. Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCGCAGTGCAGGCAGTACGTACGCAGTCAGTCA CTAGCCAGTACGTAGCATCGCAGTGCAGGCAGTACGTACGCAGTCAGTCA Rappel sur l'homologie et la similarité Appliquées aux séquences Par exemple: Ces deux séquences sont-elles similaires? Sont-elles homologues? CTAGTCAGTACGTAGCATCGCAGTGCAGGCAGTACGTACGCAGTCAGTCA CTAGCCAGTACGTAGCATCGCAGTGCAGGCAGTACGTACGCAGTCAGTCA n=50 Probablement : si on dispose de 1000 génomes de taille 3Gb, il reste très improbable (10-16) de trouver deux fois par hasard une séquence de taille 50b, à une base près. Mais il faut encore tenir compte de la complexité, de la composition des génomes... Plan du cours 1/ Rappel sur l'homologie et la similarité 2/ Recherche de séquences exactes 3/ Recherche de séquences approchées, alignement 4/ Méthodes et logiciels actuels Recherches de mots exacts dans un texte C'est un sujet classique en informatique, qui répond aux besoins de nombreuses applications. Il y a toujours aujourd'hui des articles, livres, des conférences, des sites internet sur le sujet. Par exemple, http://monge.univ-mlv.fr/~lecroq/string/ Recense plus de 85 algorithmes différents pour cette même tâche, les plus célèbres datant des années 1970, mais plus de la moitié ont moins de 10 ans. Définitions A alphabet a élément de A caractère, lettre S séquence de lettres |S|=n taille d'une séquence de lettres M mot, séquence courte T texte, séquence longue S[i] caractère de la ième position (départ à 1) S[i:j] sous-chaîne entre les positions i et j S[1..i] préfixe S[j..n] suffixe Définition du problème : M un mot, T un texte, M est-il une sous-chaîne de T ? Déterminer toutes les cous-chaînes de T égales à M. Exemple : M=CGATGCGTAC T= ACGTAGTCAGCTAGCTGACTAGCTAGCTGATCGACTGAGTCAGCGAGTCA GCTAGCTGACTGACTGACTGACTGACTGAGACTCTGACTGACTGACTGAG CTGGCTGACTGGATCGTAGCAGTCGACGATGCGTACGTAGCTAGCTGTGT CTAGCAGAAGCGAACGCTGAGCTGTCGCTGGACGAGCGCTTGACGAGCAT GACGTACTA Le mot est-il dans le texte? Définition du problème : M un mot, T un texte, M est-il une sous-chaîne de T ? Déterminer toutes les cous-chaînes de T égales à M. Exemple : M=CGATGCGTAC T= ACGTAGTCAGCTAGCTGACTAGCTAGCTGATCGACTGAGTCAGCGAGTCA GCTAGCTGACTGACTGACTGACTGACTGAGACTCTGACTGACTGACTGAG CTGGCTGACTGGATCGTAGCAGTCGACGATGCGTACGTAGCTAGCTGTGT CTAGCAGAAGCGAACGCTGAGCTGTCGCTGGACGAGCGCTTGACGAGCAT GACGTACTA Occurrence i = 127 Algorithme : T : xabxyabxyabxz M : abxyabxz * abxyabxz ­­­­­­­* abxyabxz * abxyabxz * abxyabxz * abxyabxz ­­­­­­­­ Algorithme : Pour un indice i parcourant le texte T (de 1 à |T|-|M|+1) j←1 Tant que j ≤ |M| et que T[i+j-1] = M[j] j←j+1 Si j = |M|+1 alors afficher T[i] i←i+1 En Python for i in range(len(T)­len(M)): j = 0 while j < len(M) and T[i+j] == M[j]: j = j + 1 if j == len(M): print i Comment évaluer la performance de cet algorithme? Calculer le nombre d'opérations effectuées pour connaître un ordre de grandeur du temps mis par une machine pour l'exécuter. Ce nombre dépend - de la taille de T - de la taille de M - du langage de programmation - du compilateur ou de l'interpréteur - de l'architecture de l'ordinateur Le nombre précis est impossible à calculer. Il faut une approximation, un ordre de grandeur qui ne dépende que - de la taille de T - de la taille de M Notations pour le calcul de la complexité des algorithmes : f et g sont deux fonctions (de la taille des données) f = O(g) s'il existe un nombre k tel que quel que soit x, f(x) <= k * g(x) ce qui veut dire que f ne croît pas beaucoup plus vite que g Propriétés : O(k*f) = O(f) (k est une constante et f une fonction) O(f+g) = O(f) + O(g) (f et g deux fonctions) O(f*g) = O(f) * O(g) (f et g deux fonctions) 1 est utilisé pour noter une fonction constante qui vaut 1 partout Par exemple, O(1) veut dire une fonction qui est bornée par une constante. O(n) est une fonction bornée par une constante fois une variable n (taille des données) Notations pour le calcul de la complexité des algorithmes : Petits exemples : i=3 Notations pour le calcul de la complexité des algorithmes : Petits exemples : i=3 → O(1) Notations pour le calcul de la complexité des algorithmes : Petits exemples : pour i de 1 à n : écrire i Notations pour le calcul de la complexité des algorithmes : Petits exemples : pour i de 1 à n : écrire i → O(n) Notations pour le calcul de la complexité des algorithmes : Petits exemples : La notation permet de simplifier les expressions : O(2n) => O(n) O(n² + n) => O(n²) Algorithme : Pour un indice i parcourant le texte T (de 1 à |T|-|M|) j←1 Tant que j ≤ |M| et que T[i+j] = M[j] j←j+1 Si j = |M|+1 alors afficher T[i] i←i+1 Algorithme : Pour un indice i parcourant le texte T (de 1 à |T|-|M|) j←1 Tant que j ≤ |M| et que T[i+j] = M[j] j←j+1 Si j = |M|+1 alors afficher T[i] i←i+1 O(1) O(1) O(1) O(1) O(1) Algorithme : Pour un indice i parcourant le texte T (de 1 à |T|-|M|) j←1 Tant que j ≤ |M| et que T[i+j] = M[j] j←j+1 Si j = |M|+1 alors afficher T[i] i←i+1 O(1) O(1) O(1) O(1) O(1) O(|M|) Algorithme : Pour un indice i parcourant le texte T (de 1 à |T|-|M|) j←1 Tant que j ≤ |M| et que T[i+j] = M[j] j←j+1 Si j = |M|+1 alors afficher T[i] i←i+1 O(1) O(1) O(1) O(1) O(1) O(|M|) O(|M|*|T|) Algorithme : Pour un indice i parcourant le texte T (de 1 à |T|-|M|) j←1 Tant que j ≤ |M| et que T[i+j] = M[j] j←j+1 Si j = |M|+1 alors afficher T[i] i←i+1 O(1) O(1) O(1) O(1) O(1) O(|M|) O(|M|*|T|) Notation : n = |T|, m = |M| O(n*m) Combien de temps pour rechercher les similarités entre deux génomes complets de mammifères avec cet algorithme ? 1/ Découper le premier génome en morceaux de taille 50 2/ Rechercher chaque morceau dans le deuxième génome Combien de temps pour rechercher les similarités entre deux génomes complets de mammifères avec cet algorithme ? 1/ Découper le premier génome en morceaux de taille 50 2/ Rechercher chaque morceau dans le deuxième génome Il y a 3.10⁹ / 50 = 6 millions de mots à rechercher. Chaque mot est recherché en environ 50 * 3.10⁹ opérations En tout, il faut de l'ordre de 9.10¹⁸ opérations. En combien de temps un ordinateur faisant 10¹² opérations par seconde pourra-t-il finir le calcul ? Algorithme 1: T : xabxyabxyabxz M : abxyabxz * Pour une même position du texte, on abxyabxz fait plusieurs fois la comparaison. ­­­­­­­* abxyabxz * abxyabxz * abxyabxz * abxyabxz ­­­­­­­­ Algorithme 1: Algorithme 2: T : xabxyabxyabxz T : xabxyabxyabxz M : abxyabxz M : abxyabxz * * abxyabxz abxyabxz ­­­­­­­* ­­­­­­­* abxyabxz abxyabxz * ­­­­­­­­ abxyabxz * abxyabxz * abxyabxz ­­­­­­­­ Algorithme 1: Algorithme 2: Algorithme 3: T : xabxyabxyabxz T : xabxyabxyabxz T : xabxyabxyabxz M : abxyabxz M : abxyabxz M : abxyabxz * * * abxyabxz abxyabxz abxyabxz ­­­­­­­* ­­­­­­­* ­­­­­­­* abxyabxz abxyabxz abxyabxz * ­­­­­­­­ ­­­­­ abxyabxz * abxyabxz * abxyabxz ­­­­­­­­ Amélioration (algorithme de Knuth, Morris, Pratt) Le principe est de transformer une comparaison de T et M en une comparaison de M avec lui-même : Propriété : si i et j sont tels que T[i...i+j-1] = M[1...j] et T[i+j] != M[j+1] alors on peut avoir une occurrence de M dans T[i+k...i+k+|M|-1], 1<=k<j, seulement si M[k...j-1] = M[1...j-k] On peut calculer, pour tous les j, le plus long suffixe de M[2..j] qui soit un préfixe de M On note ce nombre k(j) Amélioration (algorithme de Knuth, Morris, Pratt) k(i) est le plus long suffixe de M[2..j] qui soit un préfixe de M i←1 # Indice parcourant T j←1 # Indice parcourant M Tant que i ≤ |T| Si T[i] = M[j] alors i ← i + 1 et j ← j + 1 Si j = |M| + 1, afficher i - |M| Sinon si j = 1 alors i ← i + 1 Sinon j ← k(j-1)+1 Amélioration (algorithme de Knuth, Morris, Pratt) Calcul de la complexité : Nombre de fois où j est augmenté : ≤ n (à chaque fois que j augmente, i augmente aussi) Nombre de fois où j est diminué : ≤ n (on ne peut pas le diminuer plus de fois que ce qu'on l'augmente, puisqu'il augmente tout le temps de 1) Donc la complexité est O(n) Mais il faut calculer tous les k(i) Algorithme naïf en O(m³), possibilité en O(m) Exercice : Utiliser KMP pour déterminer si ACGTACT est dans ACGACGTACACGTACGTACTA Autre exercice : Combien de temps pour rechercher les similarités entre deux génomes complets de mammifères avec cet algorithme ? 1/ Découper le premier génome en morceaux de taille 50 2/ Rechercher chaque morceau dans le deuxième génome Il existe des dizaines de variantes de cet algorithme. KMP a une valeur standard et historique, mais n’est pas tellement utilisé en pratique. Certaines variantes ont une complexité O(mn) au pire, mais en pratique fonctionnent mieux que KMP. Chaque variante est efficace dans un domaine particulier. Faro, Lecrocq, 2013 En bioinformatique, le pré-traitement du texte est plus efficace que le pré-traitement du mot Pour un texte relativement stable (un génome, ou un ensemble de mots d'une langue), on peut établir un dictionnaire trié par ordre alphabétique, et faire la recherche plus rapidement. Quelle est la complexité de la recherche d'un mot dans un dictionnaire? De la construction d'un dictionnaire si on a la liste des mots? Algorithme de recherche dans un dictionnaire Tant qu'on n'a pas trouvé le mot M: Ouvrir le dictionnaire au milieu Si le mot T[i] < M: Restreindre sa recherche aux positions > i Si le mot T[i] > M: Restreindre sa recherche aux positions < i Algorithme de recherche dans un dictionnaire Tant qu'on n'a pas trouvé le mot M: Ouvrir le dictionnaire au milieu Si le mot T[i] < M: Restreindre sa recherche aux positions > i Si le mot T[i] > M: Restreindre sa recherche aux positions < i Combien de mots examine-t-on? C(n) = 1+C(n/2) Algorithme de recherche dans un dictionnaire (recherche dichotomique) Tant qu'on n'a pas trouvé le mot M: Ouvrir le dictionnaire au milieu Si le mot T[i] < M: Restreindre sa recherche aux positions > i Si le mot T[i] > M: Restreindre sa recherche aux positions < i Combien de mots examine-t-on? C(n) = 1+C(n/2) C(n) = log2(n) Attention : ceci suppose que le coût de la comparaison est constant, ce n’est pas toujours le cas. n log(n) La croissance des fonctions n ou log(n) montrent pourquoi la recherche dans un dictionnaire est possible Dictionnaires de séquences génomiques Il faut stocker tous les mots d’un texte de façon organisée Combien y a-t-il de mots dans un texte de taille n? Dictionnaires de séquences génomiques Il faut stocker tous les mots d’un texte de façon organisée Combien y a-t-il de mots dans un texte de taille n? n2/2 Mais on n’a pas besoin de stocker tous les mots, par exemple s’il y a GAC et GACC, le fait qu’il y ait GACC nous renseigne sur la présence de GACC. On peut ne stocker que les suffixes de T Il y en a n Dictionnaires de séquences génomiques Par exemple, si T = CACGTACGTACTA, On stocke la liste CACGTACGTACTA ACGTACGTACTA CGTACGTACTA GTACGTACTA TACGTACTA ACGTACTA CGTACTA GTACTA TACTA ACTA CTA TA A Dictionnaires de séquences génomiques Par exemple, si T = CACGTACGTACTA, On stocke la liste, triée par ordre alphabétique CACGTACGTACTA ACGTACGTACTA CGTACGTACTA GTACGTACTA TACGTACTA ACGTACTA CGTACTA GTACTA TACTA ACTA CTA TA A A ACTA ACGTACGTACTA ACGTACTA CACGTACGTACTA CGTACGTACTA CGTACTA CTA GTACGTACTA GTACTA TA TACGTACTA TACTA Algorithmes de tri Un ensemble d’éléments (mots, nombres) qu’on peut comparer deux à deux Sortir ces éléments dans l’ordre Algorithmes de tri Un ensemble d’éléments (mots, nombres) qu’on peut comparer deux à deux Sortir ces éléments dans l’ordre Algorithme 1: Tant que la liste a des éléménts Chercher le minimum, l’enlever de la liste et l’afficher Complexité? Algorithmes de tri Un ensemble d’éléments (mots, nombres) qu’on peut comparer deux à deux Sortir ces éléments dans l’ordre Algorithme 1: Tant que la liste a des éléménts Chercher le minimum, l’enlever de la liste et l’afficher Complexité? O(n2) Algorithmes de tri Un ensemble d’éléments (mots, nombres) qu’on peut comparer deux à deux Sortir ces éléments dans l’ordre Algorithme 2: Tri(liste): Couper la liste en deux parties égales L1 et L2 Tri(L1) et Tri(L2) Fusionner les listes triées Fusion(L1,L2): Tant que les deux listes contiennent des éléments, comparer le premier élément de L1 et de L2, enlever et écrire le plus petit. Compléter par la liste qui reste. Algorithmes de tri Complexité : Fusion(L1,L2): Tant que les deux listes contiennent des éléments, comparer le premier élément de L1 et de L2, enlever et écrire le plus petit. Compléter par la liste qui reste. → O(n) Tri(liste): C(n) Couper la liste en deux parties égales L1 et L2 Tri(L1) et Tri(L2) Fusionner les listes triées O(1) 2C(n/2) O(n) C(n) = O(n) + O(1) + 2C(n/2) C(n) = O(n * log(n)) Attention : si la comparaison n’est pas O(1), il faut multiplier par le coût de la comparaison! Algorithmes de tri Comme pour la recherche de mots dans un texte, le tri se fait souvent avec des algorithmes (quicksort) dont la complexité au pire est moins bonne, mais qui sont meilleurs en pratique. Recherche dans un dictionnaire de suffixes Construction du dictionnaire: O(n2 log(n)) (tri * coût de la comparaison) Recherche dans le dictionnaire O(n log(n)) (recherche dichotomique * coût de la comparaison) La recherche (tâche la plus fréquente) a une complexité meilleure que KMP, mais il faut construire le dictionnaire et la composante n2 est beaucoup trop élevée. D’autre part stocker les suffixes prend aussi un espace O(n2). Structures compactes pour stocker les suffixes Il faut stocker tous les mots d’un texte de façon organisée Par exemple un arbre de suffixes Pour T=abxab b x a a x b a x a b b b Arbre des suffixes Complexité de la recherche? (rechercher abx) b x a a x b a x a b b b Arbre des suffixes Complexité de la recherche? O(m) (m=|M|) b x a a x b a x a b b b Arbre des suffixes On peut compresser la structure pour la construire et la stocker en O(n) (n= |T|) 1/ Enlever les noeuds redondants b x a b a x b a xab b ab x xab a b b xab Arbre des suffixes On peut compresser la structure pour la construire et la stocker en O(n) (n= |T|) 2/ Indexer par des labels T=abxab xab ab xab b (3,5) (1,2) xab (3,5) (2,2) (3,5) Arbre des suffixes La construction en temps linéaire (O(n)) implique des structures de graphes et de pointeurs complexes, qui font de l’arbre des suffixes un objet théorique intéressant mais rarement (un peu quand même) utilisé pour la recherche de mots en pratique. (Au moins 30Gb nécessaires pour indexer le génome humain de 3Gb). Table de suffixes Par exemple, si T = CACGTACGTACTA, On stocke non pas la liste des suffixes, mais la liste des indices CACGTACGTACTA ACGTACGTACTA CGTACGTACTA GTACGTACTA TACGTACTA ACGTACTA CGTACTA GTACTA TACTA ACTA CTA TA A 13 A 10 ACTA 2 ACGTACGTACTA 6 ACGTACTA 1 CACGTACGTACTA 3 CGTACGTACTA 7 CGTACTA 11 CTA 4 GTACGTACTA 8 GTACTA 12 TA 5 TACGTACTA 9 TACTA Table de suffixes Par exemple, si T = CACGTACGTACTA, On peut faire la recherche dichotomique avec uniquement l’information 13 10 2 6 1 3 7 11 4 8 12 5 9 Construction et stockage O(n) Table de suffixes T = CACGTACGTACTA, TABLE = 13 10 2 6 1 3 7 11 4 8 12 5 9 Recherche O(m log(n)) l = 1, r = |T| Tant que l /= r m = (l+r)/2 S = T[TABLE[m],n] Si M < S : r=m Si M > S : l=m Quelques astuces de programmation permettent une recherche en O(m+log(n)) Table de suffixes Structure utilisée dans quelques logiciels bioinformatiques. Toujours un peu coûteuse en stockage. 15Gb et quelques secondes pour le génome humain Transformation de Burrows Wheeler Écrire n+1 fois le texte avec un décalage circulaire, et classer les n+1 occurrences par ordre alphabétique Transformation de Burrows Wheeler Isoler la dernière lettre de chaque occurrence (Remarque : la première lettre est la première lettre des suffixes rangés selon la table des suffixes) Transformation de Burrows Wheeler BWT(ACATACAGATG$) = GT$CCGAATAAA Transformation de Burrows Wheeler BWT(ACATACAGATG$) = GT$CCGAATAAA La structure d’indexation du texte a la taille du texte, et permet une compression optimale. C’est le texte dans un ordre différent, au lieu d’une série de chiffres. Chaque caractère prend 4 bits au lieu de 64 pour un nombre. Souvent, même si ce n’est pas systématique, les caractères identiques sont regroupés dans BWT, ce qui permet une meilleure compression que le texte lui-même. Transformation de Burrows Wheeler Décodage : on connaît GT$CCGAATAAA et on cherche à retrouver le texte T=ACATACAGATG$ G $ T A $ A C A C A G Tri A Collage A C A C T G A G A T A T G$ TA $A CA CA GATri AC AC TG AG AT AT $A AC AC AG AT AT Collage CA CA G$ GA TA TG G$A TAC $AC CAG CAT GAT Tri...Collage... ACA ACA TG$ AGA ATA ATG Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot P = taca Transformation de Burrows Wheeler Recherche d’un mot e←1 f←n j←m Tant que e <= f et j >= 1: r ← numéro de la première occurrence de M[j] dans L[e,f] s ← numéro de la dernière occurrence de M[j] dans L[e,f] e ← indice de la r ième occurrence de M[j] dans F f ← indice de la s ième occurrence de M[j] dans F j←j-1 Pour un calcul en temps linéaire, il faut avoir accès en temps constant aux numéros et aux indices. C’est possible par un précalcul. Transformation de Burrows Wheeler Recherche d’un mot Pointeurs à stocker Indice du r ième x dans F Nombre de x dans L[1..i] Nombre de x dans T Implémentations compactes de ces fonctions possibles Transformation de Burrows Wheeler Structure couramment utilisée dans les logiciels de bioinformatique les plus performants et les plus utilisés (Bowtie, BWA). Complexité O(n) en ayant stocké les pointeurs appropriés. Indexation du génome humain 2.2GB (contre 10 à 15Gb pour une table de suffixes) Mais dans des version de recherche approchée. Exercices Combien un mot a-t-il de préfixes? De suffixes? De sous-mots? De sous-séquences? (un sous-mot est une suite de caractères consécutifs, une sous-séquence non consécutifs) Quelle est la complexité d’un algorithme dont le nombre d’opérations peut s’exprimer par f(1) = a f(n) = b*n + 2*f(n/2) Adapter l’algorithme KMP pour un texte circulaire Dans un arbre des suffixes, comment, à partir de l’algorithme de recherche d’un mot, peut-on facilement obtenir le nombre d’occurrences de ce mot? Exercices Le décodage BWT vu dans le cours est très coûteux. Comment l’optimiser? Etant donnée la transformée BWT = e$elplepa, reconstituer le texte. Qu’indique cet exemple sur les capacités de compression de BWT? Avec BWT, comment, à partir de l’algorithme de recherche d’un mot, peut-on facilement obtenir le nombre d’occurrences de ce mot? Comment obtenir rapidement la BWT à partir de la table des suffixes? Plan du cours 1/ Rappel sur l'homologie et la similarité 2/ Recherche de séquences exactes 3/ Recherche de séquences approchées, alignement 4/ Méthodes et logiciels actuels Problème de la recherche approchée Étant donné un texte T de taille n, un mot M de taille m, donner toutes les positions i telles que d(T[i..],M) <= e Il faut définir une distance entre mots : Par exemple, nombre minimum d’éditions à faire pour transformer un mot en un autre. Une édition est un changement d’un caractère en un autre, l’insertion ou la délétion d’un caractère (ce qui mime des mutations). La définition de la distance, en particulier le choix de mutations autorisées et surtout, le choix des mutations interdites (inversions, duplications), est dictée par les techniques mises en oeuvre dans la solution. Méthodes de recherche approchée À partir de la recherche exacte A partir d’un mot M, on peut générer tous les mots M’ tels que d(M,M’) < e Puis faire la recherche exacte sur chaque M’ Comme la recherche exacte est en O(m log(n)), on a une complexité O(m v(M) log(n)) où v(M) est la taille du voisinage de M La taille du voisinage grandit avec e, m, et a la taille de l’alphabet: v(M) <= choose(2m+1,e) e^a Méthodes de recherche approchée À partir de la recherche exacte Pour faire diminuer m et e, on peut appliquer le principe des cages à pigeons : S’il y a neuf pigeons pour dix cages, au moins une sera vide. Si un sous-mot du texte T a neuf différences avec M, alors si on coupe M en dix parties, au moins une de ces parties n’a aucune erreur. Si on cherche un sous-mot de T avec e différences, alors nécessairement en coupant M en k morceaux, un morceau au moins a e/k erreurs. On peut donc chercher des mots de taille m/k avec e/k erreurs. Méthodes de recherche approchée À partir de la recherche exacte On peut donc chercher des mots de taille m/k avec e/k erreurs. Ces mots peuvent servir d’ancres pour une recherche de m entier. Le choix de k est un compromis entre la complexité de la recherche (on voudrait un k grand) et la probabilité de tomber sur une similarité par hasard (on voudrait un k petit). Un compromis habituel (arguments théoriques et empiriques) est de prendre k = log_a n Tables de hachage Accès au texte en temps constant pour des petits mots: Pour tous les mots possibles de taille k (4^k possibilités pour l’ADN), pointer vers tous les indices du texte qui le contiennent (complexité O(kn)) Si k devient trop grand, introduire une possibilité d’erreur : Pour tout mot de taille l > k, calculer un équivalent numérique du mot (traduire le mots en bits, et calculer le nombre dont la chaîne binaire est la représentation), modulo 4^k Certains pointeurs pointent sur des occurrences erronées, mais il est plus rapide de vérifier que de parcourir le texte ou même l’index du texte. Définition d’une distance entre deux mots Par exemple, d(CTAGTCAGTACGTAGCATCG,CTAGTCAGTACGTAGCATCG) = 0 d(CTAGTCAGTACGTAGCATCG,CTACTCAGTACGTAGCATCG) = 1 d(CTAGTCAGTACGTAGCATCG,CCGATACTTGCGGCTCAGAT) = ? Alignement La distance définit un sous-problème : Étant donnés deux mots A et B, calculer d(A,B) C’est le problème de l’alignement. Il en existe plusieurs variantes, selon les scores associés aux opérations d’édition. Le score sert à donner un poids au évènements: Correspondance, substitution, indel Variante 1 : Plus longue sous-séquence commune On note S[i] l'élément en position i de S (début en 1) S[i..j] le sous-mot entre les indices i et j L(i,j) la taille de la plus longue sous-séquence commune de M[1..i] et T[1..j] Édition avec score(match) = 1, score(indel) = 0, score(substitution) = -1 Variante 1 : Plus longue sous-séquence commune L(i,j) la taille de la plus longue sous-séquence commune de M[1..i] et T[1..j] L(0,i) = L(i,0) = 0 pour tout i Si M[i]=T[j] alors L(i,j) = 1+L(i-1,j-1) Sinon L(i,j) = max(L(i-1,j),L(i,j-1)) Principe de la programmation dynamique (ne cherchez pas d’explication rationnelle à ce nom) : - équation de récurrence qui résout un problème à partir de sa solution sur des problèmes plus petits - transformation en algorithme itératif Variante 1 : Plus longue sous-séquence commune Pour i de 0 à m : l[i,0] = 0 Pour j de 0 à t : l[0,j] = 0 Pour i de 1 à m, j de 1 à t : Si M[i] = T[j] : l[i,j] = 1 + l(i-1,j-1) chemin = i et j Sinon, si l[i-1,j] < l[i,j-1] : l[i,j] = l[[i,j-1] chemin = j Sinon : l[i,j] = l[[i-1,j] chemin = i Variante 1 : Plus longue sous-séquence commune Retour : i = m, j = t Tant que i > 0 et j > 0 : Si chemin = i et j : Afficher M[i] i=i-1 j=j-1 Si chemin = i i=i-1 Si chemin = j j=j-1 Exercice : calculer la complexité de l’algorithme Variante 2 : Alignement global de deux séquences Présupposé : les deux séquences sont homologues sur toutes leur longueur. En conséquence toutes les différences doivent être expliquées par des évènements évolutifs. On doit donc aligner les deux séquences : déterminer les sites homologues et les insertions/délétions Par exemple, AGACTAGTTAC et CGAGACGT A G A C T A G T T A C C G A G A C G T Variante 2 : Alignement global de deux séquences Score d'un alignement : Correspondance : Absence de correspondance : Insertion/délétion : 2 -1 -1 Ici, score total -2 Meilleur score? A G A C T A G T T A C C G A G A C G T Variante 2 : Alignement global de deux séquences Meilleur score d'un alignement entre M et T (Algorithme de Needleman-Wunch) a(i,j) = meilleur score d’un alignement entre M[1..i] et T[1..j] a(i,j) = max( a(i-1,j-1) + score(m[i],t[j]), a(i,j-1) + score(indel) a(i-1,j) + score(indel) ) a(0,j) = j * score(indel) a(i,0) = i * score(indel) A G A C T A G T T A C C G A G A C G T Variante 2 : Alignement global de deux séquences a(i,j) = max( a(i-1,j-1) + score(m[i],t[j]), a(i,j-1) + score(indel) a(i-1,j) + score(indel) ) score(m[i],t[j]) est donné par une matrice de substitutions Variante 3 : Alignement local de deux séquences On ne présuppose plus que les séquences sont homologues sur toute leur longueur. Les sites sont supposés homologues entre le premier et le dernier site alignés. Au-delà et en-deçà, les insertions/délétions sont gratuites comme dans la plus longue sous-séquence commune. A G A C T A G T T A C C G A G A C G T Variante 3 : Alignement local de deux séquences Meilleur score d'un alignement LOCAL entre M et T (algorithme de Smith-Waterman) a(i,j) = max( a(i-1,j-1) + score(m[i],t[j]), a(i,j-1) + score(indel), a(i-1,j) + score(indel), 0) a(0,j) = 0 a(i,0) = 0 A G A C T A G T T A C C G A G A C G T Alignements - Utilisation de la programmation dynamique: Une équation de récurrence => Un algorithme Remplissage d’une matrice + chemin du retour - Complexité de la comparaison de deux séquence O(nm) Impraticable pour des données génomiques - Principe théoriquement extensible à 3 séquences O(mnl), ou à k séquences O(nk) - Baisse de la complexité possible en supposant qu’on ne cherche que les solutions meilleures qu’un certain score (comme le problème de départ : recherche de mots approchés à une distance au plus e). Alignements - Ces algorithmes font partie de la boîte à outil standard de la bioinformatique. Ils sont disponibles dans plusieurs logiciels, et utilisés pour des comparaisons fines entre séquences pas trop longues - Ils sont aussi utilisés comme brique dans des outils de recherche plus rapides - Le principe de la programmation dynamique se retrouve souvent dans d’autres algorithmes, recherches de chemin dans les graphes, parcours d’arbres phylogénétiques,... Exercices 1/ Ecrire un algorithme efficace qui calcule les nombres selon les formules: - f(1) = 1 et f(n) = n * f(n-1) - f(n,0) = 1, f(n,n) = 1, f(i,j) = f(i-1,j-1) + f(i-1,j) pour i <= j 2/ Ecrire un algorithme qui énumère le voisinage d’un mot (tous les mots à distance e), avec une formule de récurrence. 3/ Donner un algorithme qui compte le nombre de plus grandes sous-séquences communes. Exercices 4/ Au lieu de trouver une plus longue sous-séquence commune, on voudrait décider si la taille de la plus longue sous-séquence commune est plus grande qu’un nombre K. Est-ce que ceci permet de faire baisser la complexité de l’algorithme? Indice: pour i,j, calculer la taille maximale de la plus longue sousséquence commune qui utilise la case i,j, quelles que soient les séquences. 5/ Pour deux mots, donner un algorithme qui calcule la plus longue plus longue sous-séquence commune S entre deux préfixes, telle que tout préfixe de S couvre au moins K% d’un préfixe des deux mots. Exercices 6/ Détection de plagiat: Donner un algorithme qui prend en entrée deux textes et qui sort les sous-mots sur lesquels la sousséquences commune est maximale Exercices 7/ Une super-séquence de S est une séquence dont S est une sous-séquence. A partir de la plus longue sous-séquence commune, trouver un algorithme qui renvoie la plus courte superséquence commune. 8/ Ecrire l’algorithme de la recherche d’un plus court chemin dans un graphe comme une équation de programmation dynamique. 9/ Adapter l’algorithme de recherche d’une plus grande sousséquence commune au calcul de la distance de Lewenstein, à savoir le plus petit nombre d’insertions, délétions et substitutions pour transformer un mot en un autre. Plan du cours 1/ Rappel sur l'homologie et la similarité 2/ Recherche de séquences exactes 3/ Recherche de séquences approchées, alignement 4/ Méthodes et logiciels actuels BLAST (1994) Recherche de mots exacts (ancres) avec tables de suffixes Extension avec Needleman-Wunch tant que le score ne diminue pas Calcul d’une e-value Bowtie (2007): Recherche exacte En cas d’incuccès, tentatives de recherche dans le voisinage des morceaux alignés BWA (2008) Même principe mais autorise les indels Kallisto, Sailfish, Salmon (2015-2016) “quasi-mapping”, “pseudo-alignment” Indexer la présence de “k-mer”, mots courts de taille fixe Recherche de k-mer en temps constant avec table de hachage Décider de la présence d’un mot approché sur des bases statistiques de présences de k-mer plutôt que sur un alignement.