Catégoriser des tumeurs selon leur ARN

Nom: Bioinformaticien.ai

Pour un excellent article qui définit le séquençage ARN et ses utilités, voir cet excellent article dans Nature Reviews Genetics de Stark, R., Grzelak, M. & Hadfield, J ou cet article wiki. Sinon, en voici mon résumé rapide.

L’acide ribonucléique (ARN) est vraiment une molécule fascinante. Une de ses fonctions est de se polymériser dans la cellule pour agir comme matériel génétique. Prenant le nom d’ARN messager  (ARNm), cette molécule agit comme l’intermédiaire entre le matériel génétique du noyau de la cellule et la protéine qui sera produite.

Image produite sur Maestro PDB: 4GXY (tutoriel d’illustration s’en viens!)

Regarder les niveaux d’ARN peut être extrêmement informateur pour plusieurs raisons:

  1. Cela permet de quantifier l’activité  d’une certaine région génétique, c’est-à-dire si une région exprime beaucoup ou peu de transcrits.
  2. Cela permet de déterminer les variations génétiques telles que l’épissage alternatif.
  3. Lorsque différentes populations de cellules ou conditions sont analysées, il est possible de déterminer les altérations dans les cascades de signallement. Ceci est particulièrement important dans la recherche pharmaceutique et oncologique.

Pour séquencer les approximativement 26 000 gènes humains, plusieurs technologies existent. La plus populaire est Illumina (quoique PacBio gagne en popularité). Pour mieux comprendre ce qui se produit dans la machine Illumina, je recommande cette merveilleuse vidéo de 5 minutes. 

En bref, la machine produit un fichier FASTQ. Les séquences génétiques de l’ARN sont ensuite placées sur une séquence standardisée du génome de l’espèce étudiée pour créer un fichier de mapped read qui, une fois transformé en images, ressemble à ceci:

Par la suite, des algorithmes comptent le nombre de séquences positionnées au-dessus de chaque région génétique. Par exemple, dans l’image ci-dessus, il y a 7 ARNm pour la région génétique donnée. La séquence du haut est le génome standardisé. Ce qui n’est pas indiqué sur l’image, c’est que le génome est annoté comme un dictionnaire. Donc quand les transcrits trouvent leur région homologue, on peut associer un gène (comme P53) à ce transcrit. Plus les transcrits se chevauchent, plus le gène est exprimé. Avec cette information, nous pouvons obtenir le jeu de données que nous allons utiliser. (Pour une super vidéo sur le sujet)

Catégoriser les profils génétiques par type de tumeurs

Le jeu de données 

Notre jeu de données est assez simple. Celui-ci vient d’un extrait du genome atlas pan-cancer analysis project. En partant de la droite, le nom de nos échantillons, le type de tumeur (BRCA: breast cancer, COAD: colorectal adenocarcinoma, KIRC: kidney renal clear cell carcinoma, LUAD: lung adenocarcinoma, PRAD: prostate adenocarcinoma) et ensuite 3000 des 16382 gènes originaux non identifiés (laissés non identifiés pour des raisons éthiques)

Puisque l’algorithme que nous allons construire ne va pas supporter les 16382 gènes du jeu de données original, j’ai isolé les 300 meilleurs. Ceci est aussi pour m’assurer que KNIME ne crash pas sur votre ordinateur. Qu’est-ce que je veux dire par les 300 meilleurs? Je veux vous donner les 300 gènes qui sont le plus différentiellement exprimés entre les types de cancer. Visuellement, suivant un diagramme de Venn, on veut prendre les gènes qui ont le profil de gauche et éviter ceux qui sont similaires comme dans le profil de droite:

Pour ce faire, j’ai écrit un petit script qui compare les types de cancer pour chaque gène en utilisant le test de Kruskal-Wallis. Sans rentrer trop dans les détails c’est un test non paramétrique qui permet de comparer plusieurs groupes. Pour une excellente vidéo sur ce test, je vous conseille d’aller voir celle-ci! Une fois que chaque gène a obtenu un score du test et une valeur p, j’ai ordonné le jeu de données de la meilleure à la pire valeur p (si jamais le phénomène de valeur p n’est pas clair, voici une bonne vidéo). J’ai ensuite pris les 300 meilleurs gènes. Et voilà, c’est ce que j’ai rendu disponible pour vous! Pour voir mon code, vous pouvez trouver la version texte de mon script python ici.

L’algorithme

Si vous ne voulez pas construire l’algorithme et simplement le télécharger:

En premier lieu, ouvrons notre session KNIME et importons notre CSV. Pour ce faire, importons notre node préférée: CSV Reader. Pour ce faire, simplement aller dans I/O > Read > CSV reader.

Par la suite, allons chercher le jeu de données (RNAseq_Cancer.csv) dans le menu de configuration de la node ouverte en double-cliquant sur la node.

Après avoir cliqué sur Apply et Ok, nos données seront maintenant importées. Commençons par les visualiser. Pour ce faire, nous allons devoir associer des couleurs à chaque groupe de cancers. Pour ce faire, nous allons utiliser une node nommée Color Manager. Celle-ci est trouvé sous Views > Property > Color Manager.

En ouvrant la fenêtre de configuration nous pouvons voir que nous avons attaché une couleur spécifique à chacun de nos 5 types de cancer.

L’analyse en composantes principales

Maintenant que c’est fait, plongeons dans un des gros concepts de ce tutoriel: l‘analyse en composantes principales ou en anglais principal component analysis (PCA). Puisque c’est un concept qui peut être difficile à comprendre, voici quelques excellentes vidéos qui abordent le concept différemment: Computerphile (20 min) et StatQuest (6 min).

PCA est une technique qui permet de réduire le nombre de dimensions d’un jeu de données. Qu’est-ce que ça veut dire ? Eh bien, prenons notre jeu de données dans lequel nous avons 300 variables (nos 300 meilleurs gènes). Si nous voulons faire un graphique, le nombre d’axes que ce graphique aurait été de 300! En utilisant PCA, nous pouvons diminuer ce nombre d’axes à quelque chose de plus utilisable tel que 1, 2 ou 3!

Mais qu’est-ce que ces nouveaux axes représentent? Eh bien ce sont les axes qui séparent le mieux nos données. Pour illustrer ce qui se passe dans la machinerie de l’algorithme, prenons un graphique avec 2 axes où nous avons deux groupes de points.  Cependant, nous voulons voir si nous pouvons encore mieux séparer nos deux populations.

Pour ce faire, l’algorithme de PCA va calculer la distance moyenne de chaque point sur chacun des axes (représentée par l’étoile jaune).

Par la suite, le point occupant les coordonnées données par les moyennes (illustré par le X jaune) est trouvé et devient la nouvelle origine de notre graphique.

Par la suite, l’algorithme va tenter de créer une nouvelle droite, passant par l’origine, qui passe par le plus de points. Plus précisément, la droite va tenter de limiter la distance perpendiculaire entre chaque point. Cette droite sera notre première composante principale (PC1). Cette droite a ainsi la propriété de permettre la meilleure séparation entre nos points!

Pour les composantes principales, on a tout simplement à continuer le même processus jusqu’à ce qu’on ait obtenu le nombre de dimensions désirées. Dans notre cas, la seconde composante principale est à 90° de la PC1.

Maintenant, tout ce qu’il reste à faire, c’est d’effacer les axes originaux de notre graphique et pivoter PC1 et PC2 pour faire de celles-ci nos nouveaux axes. Et voilà! 

Pour exécuter la même chose dans KNIME nous allons avoir besoin de la node savamment nommée: PCA. Celle-ci peut être trouvée sous Analytics > Mining > PCA > PCA.

Tout devrait être beau dans le module de contrôle sauf le nombre d’axes. Nous allons augmenter le nombre de dimensions de 1 à 2. Pour ce faire, il faut simplement entrer 2 dans la petite fenêtre nommée: Dimension(s) to reduce to.

Maintenant, visualisons notre chef-d’oeuvre! Pour cela, utilisez la node Scatter Plot trouvée sous Views > JavaScript > Scatter Plot

Dans le module de contrôle de la node Scatter Plot, changez les colonnes utilisées pour les axes pour PCA Dimension 0 et PCA Dimension 1

Ensuite, cliquez sur la node avec le bouton droit de votre souris, puis cliquez sur l’option: Execute et Open Views.

Cela devrait vous donner une figure similaire à celle-ci:

Cette figure est très intéressante puisqu’on peut maintenant aisément discerner les points liés au cancer du sein (BRCA), de la prostate (PRAD)  et des reins (KIRC). Par contre, il semble y avoir un léger chevauchement entre les points liés au cancer colorectal (COAD) et du poumon (LUAD). C’est pour ces deux populations de points que nous allons tenter de créer un algorithme qui les sépares de manière optimale en diminuant les faux positifs ainsi que les faux négatifs.

Modèle d’apprentissage supervisé: Classification naïve bayésienne

Maintenant que nous avons organisé nos données, regardons le modèle que nous allons utiliser. Encore, je veux mentionner que plusieurs modèles sont excellents dans cette situation, mais je veux introduire le classificateur bayésien naïf ou naïve Bayes classification. Encore une fois, pour une introduction très visuelle, ma suggestion vidéo est la suivante

Prenons un exemple en 2 dimensions comme le nôtre suite au PCA de l’exemple précédent .

L’algorithme, par la suite, va créer une courbe normale, aussi nommée fonction Gaussienne, pour la distribution des nuages de points. Comme toujours, voici une vidéo qui détaille le concept en détail.

Techniquement, puisque nos courbes couvrent tout l’espace de notre graphique et que chaque point sur notre graphique représente une probabilité de faire partie du groupe orange ainsi qu’une probabilité de faire partie du groupe bleu, on peut utiliser une équation (version naïve du Théorème de Bayes, d’où le nom du modèle) pour trouver de quel groupe un nouveau point fait partie. Pour plus de matériel sur le classificateur bayésien naïf vidéo par Louis Serrano et une approche par Augmented Startups.

Pour utiliser ce modèle dans KNIME, nous allons devoir amarrer notre algorithme à la sortie de la node PCA. Par contre, avant d’aller de l’avant nous allons devoir diviser nos données en un ensemble d’examination et un ensemble d’entraînement. Par peur de me répéter, voir ma version allongée de mon explication dans ce tutoriel. Pour ce faire, simplement ajouter une node nommée Partitioning. Celle-ci peut être trouvée sous Manipulation > Row > Transform > Partitioning.

Le panneau de contrôle peut être laissé à lui-même et la node exécutée.

Par la suite, nous pouvons bâtir notre circuit pour notre classification naïve bayésienne. Pour ce faire, nous devons connecter la sortie supérieure de la node Partitioning à la node Naïve Bayes Learner accessible sous Analytics > Mining > Bayes > Naïve Bayes Learner. Ensuite, nous pouvons connecter la sortie inférieure de la node Partitioning à la node Naïve Bayes Predictor sous Analytics > Mining > Bayes > Naïve Bayes Predictor. Finalement, connectez la Naïve Bayes Learner à la Naïve Bayes Predictor. Pour un guide visuel, simplement suivre le gif ci-dessous.

Les deux nodes peuvent être exécutées sans changer quoi que ce soit à la fenêtre de contrôle.

Il ne nous reste plus qu’à créer la matrice de confusion pour notre algorithme! 

Je vais répéter cette section du dernier tutoriel, car c’est super important!

Il existe plusieurs manières de quantifier la qualité d’un algorithme. La matrice de confusion est l’une d’elles et selon moi la plus simple. Elle consiste d’une matrice 2X2 qui contient 4 valeurs: les vrai positifs, les faux positifs, les vrai négatifs et les faux négatifs. En détail:

  1. Un vrai positif est une valeur qui est une prédiction que l’algorithme classifiée comme vrai lorsqu’elle est aussi vrai dans la réalité. Example: un algorithme qui classifie une personne ayant un cancer de la prostate et la personne a, en effet, un cancer de la prostate.  
  2. Un faux positif est une valeur prédite comme vrai, lorsque dans la réalité elle ne l’est pas. Reprenant l’example initial, un faux positif serait une classification d’un individus dans la catégorie ayant un cancer lorsque cette personne n’en a pas. Un point important en médecine: Le tests médicaux, dans la majorité des cas, tentent de garder cette valeur à un minimum. 
  3. Un vrai négatif est une valeur prédite comme négative et qui est en effet négative dans la réalité. L’équivalent d’être identifié par un test comme n’ayant pas le cancer et que ca soit le cas. 
  4. Un faux négatif est lorsqu’une valeur est prédite comme négative ne l’est pas. C’est l’équivalent de prédire qu’une personne n’as pas le cancer lorsque celle-ci en a un.

Visuellement, la matrice de confusion ressemble à ceci:

 

Par définition, en haut à gauche nous retrouvons nos vrais positifs, en haut à droite le faux positif, en bas à droite les faux négatifs et en bas à droite les vrais négatifs.

Avec la matrice de confusion, il est ensuite facile de calculer la sensibilité et la spécificité. Celles-ci sont calculé avec les équations suivantes:

Sensibilité = VP ÷ (VP + FN)

Spécificité = VN ÷ (VN + FP)

Dans notre cas, nous allons créer notre matrice de confusion avec la node Scorer sous Analytics > Mining > Scoring > Scorer et connecter la node avec la sortie de données du SVM Predictor

Finalement, dans le menu de configuration vous devrez vous assurer que l’on compare Class et Prediction (Class).

Ensuite, cliquez Apply et Ok, puis cliquez Execute and Open Views

Et voilà, un algorithme hyper précis pour catégoriser les tumeurs selon leur profil d’expression d’ARN! 

Il faut d’abord noter que l’Accuracy (Exactitude) va varier. De plus, cette matrice de confusion illustre une confusion entre LUAD et COAD. Ceci est expliqué par le fait que nous divisions de manière complètement aléatoire nos données qui se retrouvent dans nos données d’entraînement et nos données test. Par conséquent, certains vont avoir des valeurs tests plus difficiles à classifier comme ces points-ci:

C’est pourquoi que lorsque nous créons un véritable algorithme, nous allons faire la moyenne de centaines d’itérations où nous allons recommencer le processus de séparation entraînement-test pour donner la chance à l’algorithme de s’exposer aux points plus difficiles à classifier.