A travers ce livre, vous apprendrez à :
✅ traduire des besoins métiers en un projet de création d’application web ;
✅ implémenter dans une application web interactive un processus de prise de décision basée sur les données ;
✅ développer une mise en page de base de l’interface utilisateur (UI) d’une application web Shiny ;
✅ développer un interface utilisateur dynamique en donnant la possibilité aux utilisateurs contrôler les affichages de l’application ;
✅ écrire les codes dans le server pour générer les sorties (outputs) tout en utilisant la Réactivité ;
✅ contrôler le comportement réactif de votre application web pour une utilisation optimale ;
✅ réaliser des applications web performantes à la demande et sur-mesure et de les déployer afin de constituer votre portfolio de projets et ainsi montrer votre talent au monde 🙂 En plus de toutes ces capacités citées ci-dessus, à l’issue de cette formation, vous améliorez considérablement votre niveau en Programmation informatique avec l’un des langages les plus utilisés et les plus puissants au monde en général et dans la Data Science en particulier : R. Si vous souhaitez valoriser vos travaux en donnant vie à vos analyses de données et acquérir l’une des compétences les plus demandées dans le monde de la DATA, ce livre est la solution🙂.
Je suis un Consultant Data Scientist avec une solide expérience en analyse, visualisation des données et développement de programmes d’automatisation de tâches en utilisant des outils tels que R, Python, R Shiny et R Markdown.
En plus de mes compétences, j’ai également écrit plusieurs livres, publiés sur Amazon, sur les thématiques de la Data Science (Python, R, Statistique, Machine Learning, Intelligence Artificielle, Développement web, etc.), ce qui me permet de partager mes connaissances avec un public plus large. J’ai également une chaîne YouTube sur ces thématiques, où je partage mes expériences et mes connaissances avec la communauté de la Data Science : https://www.youtube.com/c/JADATATECHCONSULTING
Je crois fermement en la valeur de la formation et de l’éducation des clients. C’est pourquoi, en plus de fournir des solutions de pointe pour résoudre les problèmes complexes de mes clients, je suis également capable de les former sur les techniques en Machine Learning. Cela permet à mes clients de mieux comprendre les solutions que je leur propose et de s’approprier les connaissances nécessaires pour prendre des décisions éclairées.
En travaillant en tant que freelance, je suis en mesure de fournir des services personnalisés pour répondre aux besoins spécifiques de chaque client, offrant ainsi une expérience client exceptionnelle et une valeur ajoutée élevée.
Je suis passionné par deux choses :
✅ 1) Développement de “Data Products” :
✨ Je conçois des applications web avec R Shiny et Streamlit (Python) et d’autres types de Data Products afin d’automatiser des tâches d’analyse complexes et de Modélisation (Statistique, Machine Learning). Je suis capable de créer des outils à la demande pour répondre à vos besoins en termes d’acquisition, de traitement, d’analyse et de modélisation des données.
✨ Pour le développement d’applications web, de graphiques interactifs et autres Data Products, j’utilise principalement : R Shiny, Streamlit, R Markdown, Plotly, GoogleViz, Shinydashboard, etc.
✨ Je maîtrise les langages R et Python. Mes IDE favoris : RStudio, Jupyter Notebook et Google Colab.
✨ Gestion de mes projets avec Git et GitHub.
✅ 2) Transmission du savoir à travers la formation et le coaching:
✨ Pour moi la meilleure manière de renforcer mes connaissances est de les transmettre à d’autres personnes. Je suis donc toujours dans le partage.
✨ Ma chaîne YouTube “J.A DATATECH CONSULTING” où je distribue des formations 100% pratique en Data Science et en Machine Learning. : https://www.youtube.com/channel/UCpd56FfjlkKbkHlbgY6XE3w
✨ Je suis aussi auteur de plusieurs livres dont :
📚 Initiation à la programmation et à la manipulation des données avec le langage R
📚 Statistique et Simulation avec Python : Cours et Exercices corrigés
📚 Machine Learning par la pratique avec Python: Projets réels dans les Finances, l’Immobilier, le Trading, la Santé, le Marketing, etc.
📚 Analyse financière et Gestion des Risques avec Python: Application à la création et l’optimisation des Portefeuilles
📚 Savoir programmer avec le langage Python appliqué à l’analyse des données: Cours, Exercices corrigés et Projets réels
Tous mes livres sont disponibles sur les marches Amazon en version papier et version numérique.
✅ Pour me contacter :
En tant que Data Scientist ou Data Analyst, tu crois peut-être que créer une application web ne te concerne pas et que c’est uniquement le rôle des développeurs. C’est une croyance généralisée donc c’est tout à fait normal que tu penses ainsi. Néanmoins, la pensée générale est-elle forcément une vérité absolue !? Bon, je ne vais pas te faire ici un cours de philosophie :). Je voudrais simplement que tu lises ce chapitre jusqu’à la fin afin de comprendre les raisons pour lesquelles il faut absolument que tu apprennes à créer des applications web. A la fin de ta lecture, tu pourras te faire ta propre idée et je suis certain que tu basculeras dans la minorité très recherchée des Data Analyst / Scientist possédant la compétence de développement d’applications web.
Mais avant de te présenter les motivations de l’apprentissage du développement web, laisse-moi d’abord te présenter R Shiny.
R Shiny est tout simplement un package de R qui permet de créer des applications web en utilisant uniquement le langage R. Oui ! Je dis bien en utilisant uniquement le langage R. C’est encore un courant de pensée générale qui dit que R est uniquement bon pour faire des analyses statistiques et que pour développer des applications il faut apprendre à coder avec Python, JavaScript, Ruby, HTML, CSS, etc. Bien que ces outils soient largement utilisés pour créer des applications, sache que R est un langage que tu peux utiliser pour effectuer non seulement toutes tes tâches en Data Science mais aussi pour créer des applications web interactives complètes et performantes. Le fait de savoir écrire du code en HTML et/ou JavaScript est sans aucun doute un grand avantage dans la conception d’applications web mais cette compétence n’est pas forcément nécessaire lorsqu’on utilise R Shiny.
Chaque langage possède des fonctions intrinsèques qui permettent de faire des choses “simples”. Mais pour des tâches complexes, tu auras forcément besoin de packages additionnels pour compléter les fonctions intrinsèques. C’est exactement comme ton smartphone. Il y a des applications déjà pré-installées mais pour une utilisation optimale et pour ton confort, tu télécharges et tu installes d’autres applications.
Donc de la même manière que Pandas est un package de Python pour réaliser des analyses de données, Shiny est un package de R pour créer des applications web. Avec Shiny, tu pourras transformer tes codes pour les analyses de données en des applications web interactives et engageantes. Les utilisateurs de ton application pourront ainsi interagir avec des graphiques, des algorithmes et modèles de Machine Learning sans aucune installation préalable sur leur ordinateur et surtout sans coder.
C’est vrai, je devrais te l’expliquer avant de commencer à parler blablablablablablablablablabla :). Pour faire simple, tout ce que tu rencontres sur internet est une application web. Par exemple, mon site web https://afouda-datascience.com/, comme tous les sites sur internet, est une application web. Tout ce qui se présente à toi et que tu vois est ce qu’on appelle l’interface utilisateur (User Interface ou UI) qu’on appelle encore frontend. C’est avec l’interface utilisateur que tu interagis. Derrière l’interface utilisateur, il y a ce qu’on appelle Serveur (backend). C’est dans le serveur qu’il y a tout le code qui permet de faire tous les calculs nécessaires et de mettre à jour les affichages au niveau de l’interface utilisateur afin que les interactions entre l’utilisateur et l’application puissent se faire normalement. Le serveur est donc le cerveau de l’application web.
Maintenant que tu as compris ce qu’est Shiny et ce qu’est une application web, tu te poses certainement cette question : dois-je coder aussi bien le frontend et le backend !?
Oui, c’est souvent le cas ! C’est vrai que parfois il peut avoir deux développeurs sur un projet : un qui s’occupe uniquement de l’interface utilisateur et l’autre qui s’occupe du serveur. Les deux collaborent étroitement pour créer une application fonctionnelle. Mais, il est absolument possible qu’un seul développeur code entièrement l’application.
Bonne nouvelle pour toi ! Avec R Shiny, tu peux créer une application web (frontend + backend) en utilisant uniquement le langage R.
Après avoir créé ton application web, tu peux l’utiliser en local c’est-à-dire dans ton PC. Ce faisant, c’est ton ordinateur qui joue le rôle de serveur et c’est donc dans ton ordinateur que tous les calculs s’opèrent. Par ailleurs, l’intérêt de créer une application web réside justement dans le fait de permettre à d’autres personnes de pouvoir l’utiliser directement sur internet sans avoir à rien installer sur leur ordinateur.
Pour rendre cela possible, il faudra alors déployer ton application web. Ainsi n’importe quelle personne disposant de l’adresse internet (URL) de ton application pourra l’utiliser aisément. Par exemple, l’adresse ci-contre : https://afoudajosue.shinyapps.io/portfolio_analysis/ est le lien de mon application de création, d’analyse et d’optimisation de portefeuille d’actifs boursiers. Cette application fait partie des projets que tu réaliseras à travers ce livre et qui te permettront de mâitriser le développement d’applications web avec R Shiny. Je ne vais pas rentrer ici dans les détails techniques du déploiement d’une application web mais sache qu’avec R Shiny il n’y a rien de plus simple que le déploiement d’une application.
OK ! Josué, tout ça c’est très cool ! Mais tu ne m’as toujours pas expliqué pourquoi en tant que data analyst ou data scientist je dois apprendre à créer des applications web.
Je vais te l’expliquer ! Calme down :) Je voulais m’assurer d’abord que tu comprennes exactement de quoi il s’agit, c’est-à-dire que tu comprennes bien le contexte. Maintenant que c’est fait, nous pouvons rentrer dans le vif du sujet. Les raisons pour lesquelles tu dois savoir créer des applications web trouvent leurs fondements dans le concept de Data Product.
De la même manière qu’il y a des produits finis en industrie, un data product est le produit fini d’une analyse statistique. C’est ce qui ressort d’une analyse des données. C’est la valeur ajoutée de l’analyse statistique. Un data product permet d’améliorer la prise de décisions basées sur les données. Il peut se présenter sous différentes natures : dashboards (tableaux de bords), graphiques interactifs, rapports, e-book, applications web, etc.
Et c’est sur l’application web en tant que data product que j’aimerais attirer ton attention. Une application web en tant que data product permet d’automatiser la chaîne de traitement des données. Qui dit automatisation dit gain de temps et par conséquent gain d’argent (time is money) et c’est ce que veulent les entreprises.
Le fait de transformer tes codes R en applications web présente un avantage considérable pour toi-même et aussi pour l’entreprise. En effet, avec l’application web, tu n’auras plus à recoder pour effectuer une nouvelle analyse des données. Par exemple, si tu modifies ton code pour en faire une application web de prévision des ventes de l’entreprise, lorsque tu recevras de nouvelles données il suffira d’utiliser l’application pour faire tes prévisions et visualiser les résultats. Ceci se fera uniquement avec des clics au niveau de l’application. Il s’agit là d’une sorte de mise en production de ton code. De plus, tu permets ainsi à ton Manager et aux décideurs de l’entreprise de pouvoir interagir facilement avec l’application et de comprendre comment la modification de paramètres d’entrées du modèle impacte les prévisions. Ainsi, les décisions pourront être prises rapidement et efficacement.
Dans le paragraphe ci-dessous, je vais te présenter quelques situations où, en tant que data analyst / scientist, tu dois absolument créer des applications web pour améliorer le processus de prise de décisions basées sur les données au sein de l’entreprise dans laquelle tu travailles.
Avec le package shinydashboard ou encore le package flexdashboard, tu peux créer des tableaux de bords dynamiques permettant de visualiser les résultats d’une analyse des données et de piloter un business. Le lien ci-contre : https://afoudajosue.shinyapps.io/airbnb_dashboard/ est le tableau de bord pour analyser les prix des logements Airbnb dans 03 grandes villes à savoir : Amsterdam, New York et San Francisco. Tu apprendras aussi à construire ce dashboard à travers ce livre (Chapitre 3).
Il existe sur le marché plusieurs applications de Business Intelligence (BI) qui permettent de créer des tableaux de bord. Alors où se trouve l’importance de créer encore soi-même une application web pour réaliser ce type de tâches ?
En créant toi-même une application qui génère des tableaux de bords et rapports, tu auras beaucoup plus de contrôle. Très souvent les applications de BI qui existent déjà sont des solutions générales qui ne vont pas forcément être adaptées précisément à la situation de l’entreprise. Tu peux donc créer une application web qui automatise la génération des tableaux de bords et rapports. Donc à chaque fois que tu veux réaliser un nouveau rapport, il suffira de rentrer les paramètres au niveau de l’application et boom, le rapport est généré. Trop cool n’est-ce pas :)
Le marché de la création d’applications à la demande et sur-mesure est en plein essor avec l’avènement du Big Data et de l’intelligence artificielle. Donc en tant que data analyst / data scientist, si tu es encore doté de la compétence développement d’applications, tu vas gagner beaucoup d’argent. Il y a beaucoup de Data Scientists les perles rares sont les personnes qui possèdent à la fois les compétences d’un Data Scientist et d’un développeur. et qui comprennent les problématiques d’ingénierie des données et de déploiement de modèles de Machine Learning.
La segmentation de clientèle est une tâche récurrente en entreprise.
Imagine un scénario tout simple : tu es data analyst / scientist dans une entreprise où tu dois effectuer la segmentation de clientèle afin de permettre au département Marketing d’améliorer l’impact de ses campagnes. Tu as donc réalisé un clustering avec l’algorithme des k-moyennes (K-means) en utilisant 3 clusters. Tu montres le résultat sous forme de graphique nuage de points à ton Manager afin qu’il visualise ta segmentation. Ton manager te demande quel serait le résultat si on considérait 4, 5, 6 clusters au lieu de 3 ? De plus, il veut voir d’autres variables autre que celles que tu lui as présenté dans le nuage de points. Tu retournes dans ton bureau et tu transformes ton code en une fonction qui a le nombre de clusters en argument (paramètre d’entrée) et qui permet de générer un nuage de points pour visualiser les clusters. Tu envoies le code à ton Manager. Sauf que ce dernier n’aime pas voir du code. Donc à chaque fois qu’il va vouloir utiliser ce code pour faire varier les paramètres et afficher les résultats, il va devoir t’appeler. Cette façon de faire n’est pas du tout efficace et ne facilite pas la prise de décision.
La solution simple mais efficace est de transformer ton code en une application web interactive qui permettra au Manager, à partir de simples clics, de varier différents paramètres de la segmentation et de visualiser automatiquement les résultats. Ce serait une application R Shiny comme celle ci https://afoudajosue.shinyapps.io/kmeans_dim_reduction_app/ que j’ai créé pour le traitement et l’analyse de données brutes par l’algorithme de clustering K-means dont l’image de l’interface est ci-dessus.
Il faut que tu prennes conscience qu’en entreprise, les décideurs ne se soucient pas de ton code encore moins de sa longueur. Ce qui compte pour eux, c’est la manière dont ton travail améliore les performances de l’entreprise et comment tu peux les aider à prendre des décisions éclairées sur la base des données (driven-data). Ce n’est pas facile de coder et je sais combien de fois on galère parfois avec les codes. Mais malheureusement, le fait que tu saches écrire 100, 500, 1000 lignes de code n’intéresse personne. La meilleure manière dont tu disposes pour valoriser tes compétences en programmation est de créer des applications web à forte valeur ajoutée qui permettront à l’entreprise d’automatiser plusieurs tâches même les plus complexes.
Tu peux aussi utiliser tes compétences en création d’application web pour ton usage personnel. Par exemple, tu peux créer ton propre site web ou créer ton CV en ligne. Et tout ça avec R Shiny.
Il y a beaucoup d’autres exemples de situations où vous devez absolument savoir créer des applications web. Je ne peux pas toutes les citer ici mais tu as compris l’idée : cette compétence supplémentaire va te permettre de sortir de la grande foule et de décrocher des opportunités intéressantes d’emploi et de business.
Pour te montrer qu’il est bel et bien possible qu’un data analyst / scientist sache créer des applications web, j’aimerais te partager ma propre expérience avec R Shiny. En l’espace d’une semaine de travail intensif, j’ai créé deux applications web à forte valeur ajoutée :
Application R Shiny pour le traitement et l’analyse de données brutes par l’algorithme de clustering K-means : https://afoudajosue.shinyapps.io/kmeans_dim_reduction_app/ ;
Application R Shiny pour la création, l’analyse, la gestion et l’optimisation de portefeuilles d’actifs financiers : https://afoudajosue.shinyapps.io/portfolio_analysis.
Je t’invite à cliquer sur les liens ci-dessus afin d’être redirigé vers ces applications pour pouvoir les utiliser. Regarde aussi les vidéos ci-dessous qui concernent la prise en main de ces applications :
Mon objectif en créant ma chaîne YouTube JA DATATECH CONSULTING est de démocratiser les connaissances dans le domaine de la DATA et de la programmation informatique. Je crée des contenus (livres, formations, vidéos YouTube, Tutoriels, etc.) accessibles à tout le monde et dans lesquels j’explique de manière claire, précise et concise différents concepts relatifs à la DATA. Je ne fais pas de bruit car le bruit ne fait pas de bien et le bien ne fait pas de bruit. Vas-y regarder par toi-même pour te faire ta propre opinion.
Revenons-en à R Shiny. Il existe plusieurs cours et tutoriels sur ce package et qui sont disponibles gratuitement sur Internet. Mais crois-en mon expérience quand je te dis que la majorité de ces tutoriels n’effleurent que la surface de Shiny. C’est-à-dire même pas les 5% de ce que tu peux réellement faire avec Shiny. Non seulement ces tutos sont éparpillés sur le net, mais ils pourront juste t’aider à créer des onglets et construire quelques petits graphiques interactifs comme des histogrammes. Et ce n’est pas avec juste un histogramme que tu pourras résoudre une problématique business ! Ces tutoriels ne te permettront pas de pouvoir vraiment comprendre la programmation modulaire encore moins la programmation réactive qui sont des concepts absolument incontournables si tu veux pouvoir créer des applications web performantes. Regarde encore mon application sur l’analyse de portefeuille https://afoudajosue.shinyapps.io/portfolio_analysis/. Dans cette application, il s’agit purement de la programmation dynamique et ce n’est pas avec de simples tutos internet que tu vas pouvoir réaliser ce genre d’applications qui apportent une réelle valeur ajoutée.
Par ailleurs, je forme et je coach beaucoup d’étudiants de grandes universités et de “Grandes Écoles” que ce soit en France, Allemagne, Canada, … qui sont dans des filières Data Science, Statistique, etc. Très souvent ce n’est rien que de la théorie à l’Université. Bon, that’s another story :).
Alors, mon objectif est de t’éviter de galérer et de perdre du temps en tâtonnant sur le net. Ce qu’il te faut c’est une formation bien structurée et 100% pratique qui te donnera la pleine capacité de pouvoir réaliser des applications web à forte valeur ajoutée en utilisant Shiny. Le présent livre retranscrit sur papier ladite formation et complète avec d’autres cas rencontrés en Entreprise. Par ailleurs, je mets à ta disposition tous les codes (Interface Utilisateur + Serveur) des applications au niveau des projets mais aussi tous les codes des applications des chapitre 2 et 3.
Dans ce chapitre, je t’ai expliqué ce qu’est R Shiny ainsi que les raisons pour lesquelles tu dois absolument apprendre à créer des applications web. Ci-dessous, le résumé en images de ces 05 raisons principales :
Ce chapitre couvrira les sujets suivants :
Installation de Shiny et Exécution de quelques exemples d’applications disponibles dans le package ;
Création d’une application Shiny “Hello, world” ;
Structuration de l’interface utilisateur (panneau latéral et panneau principal) ;
Inputs (Entrées) et Outputs (Sorties) ;
Création d’onglets dans le panneau principal ;
Quelques associations Fonctions de création d’espace réservé - Fonctions de rendu.
Comme tu le sais maintenant, Shiny n’est qu’un package de R. Donc pour utiliser Shiny, il faut préalablement disposer d’un environnement de développement (IDE) te permettant d’écrire du code R. Si tu ne disposes pas de R dans ton ordianteur, tu peux le télécharger via ce site https://mirrors.nics.utk.edu/cran/. Après avoir téléchargé et installé R, tu dois aussi faire de même avec RStudio https://www.rstudio.com/. Si tu es débutant en programmation avec R, je te conseille de te proccurer ce livre : APPRENDRE À PROGRAMMER AVEC R ET RSTUDIO: MANUEL DE COURS ET EXERCICES CORRIGÉS POUR DÉBUTANTS disponible en vente sur tous les marchés Amazon.
Le package RShiny peut être installé avec le code ci-dessous au niveau de la console de RStudio :
# Installation de R Shiny
install.packages("shiny")
Après l’installation de Shiny, il faut l’importer avant de pouvoir l’utiliser. Exécutez le code ci-dessous :
# Importation de Shiny
library(shiny)
Shiny dispose en son sein de plusieurs applications exemples que vous pouvez exécuter. Certaines de ces applications sont mêmes accompagnées des codes sources. Pour avoir la liste des noms de ces applications, exécutez le code ci-dessous :
# Applications exemples disponibles dans le package Shiny
runExample()
## Valid examples are "01_hello", "02_text", "03_reactivity", "04_mpg", "05_sliders", "06_tabsets", "07_widgets", "08_html", "09_upload", "10_download", "11_timer"
Pour exécuter par exemple l’application nommée “01_hello”, tapez au niveau de la console :
# Exécution de l'application "01_hello"
runExample("01_hello")
Vous devez obtenir l’affichage ci-dessous :
Exécutons un autre exemple :
# Exécution de l'application "03_reactivity"
runExample("03_reactivity")
Il y a d’autres exemples d’applications dans la gallerie Shiny : https://shiny.rstudio.com/gallery/. Dans la suite de ce chapitre, vous apprendrez à créer votre propre application Shiny et à la déploier sur internet.
Dans cette section, vous apprendrez les différentes composantes d’une application Shiny. De plus, vous apprendrez à créer une simple application web qui affiche “Hello, world”. Pour commencer, ouvrez une nouvelle session RStudio puis créez un nouveau projet qui hébergera toutes les applications de ce livre. Cliquez successivement sur File, New Project, New Directory, Shiny Web Application. Donnez un nom au dossier dans l’espace Directory Name (par exemple Apps_Shiny) puis cliquez sur Browse afin de choisir votre répertoire (par exemple le disque D de votre ordinateur) puis cliquez enfin sur Create Project. Vous devez obtenir une interface pareille à l’image ci-dessous :
Dans le panneau des Fichiers et Graphiques qui montre les différents fichiers se trouvant dans votre répertoire, cliquez sur le fichier app.R. Vous obtiendrez l’affichage ci-dessous :
app.R est le nom par défaut donné aux applications R Shiny. Les fichiers app.R comportent à la fois le code du frontend et celui du backend. Il est possible de séparer l’interface utilisateur et le serveur. Dans ce cas, vous aurez deux fichiers : ui.R (pour le frontend) et server.R (pour le backend). Dans ce livre, pour des raisons de simplicité, nous utiliserons uniquement les fichiers app.R.
Cliquez sur le boutton ▶️ Run App pour exécuter l’application. Vous obtiendrez l’affichage ci-dessous :
L’application par défaut ci-dessus permet à l’utilisateur de varier le nombre de bins et de visualiser un histogramme.
Passons maintenant à la structure du code d’une application R Shiny. Toute application web est constituée de deux parties principales (voir Chapitre 1) et les applications Shiny n’en font pas exception :
une interface utilisateur qui est présentée aux utilisateurs de l’application et
un serveur qui est le cerveau de l’application dans lequel se produisent tous les calculs.
Le code d’une application Shiny respecte donc ces deux composantes. Ce code est composé d’une fonction d’interface d’utilisateur à savoir la fonction fluidpage https://shiny.rstudio.com/reference/shiny/0.14/fluidPage.html et une fonction server https://shiny.rstudio.com/articles/server-function-testing.html pour le serveur de l’application. Il existe une troisième composante dans la structure du code d’une application Shiny. Il s’agit de la fonction ShinyApp qui rend possible l’exécution de l’application.
Pour créer une application Hello World!, commençons d’abord par effacer les codes à l’intérieur des fonctions fluidpage et server.
Appuyez sur le bouton 💾 Save (ou Ctrl + S) puis exécutez l’application. Vous obtenez une application vide. Puisque tout ce qu’on écrit dans la fonction fluidpage est affiché dans l’interface utilisateur, alors nous pouvons écrire Hello World! puis exécutez l’application.
N.B : N’oubliez pas de toujours appuyer sur le bouton 💾Save (ou Ctrl + S) avant d’exécuter votre application.
Améliorons un peu cette application en augmentant la taille de Hello World! et en mettant le nom de l’auteur de l’application (vous pouvez mettre votre nom) :
library(shiny)
# Interface utilisateur
ui <- fluidPage(
h1("Application Hello World!"),
h2("Auteur : Josué Afouda"),
"Cette application permet d'afficher 'Hello World!'"
)
# Serveur
server <- function(input, output) {
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Nous obtenons l’afficahge ci-dessous après exécution :
NB : Au niveau de la fonction fluidpage, n’oubliez pas de toujours mettre la virgule , à chaque fois que vous devez écrire d’autres lignes de code en bas.
Pour cette section, vous pouvez retenir que tout ce qui s’affiche dans l’interface utilisateur d’une application Shiny trouve son origine dans le code de la fonction fluidpage. Sachez qu’il existe d’autres types de fonction frontend comme flowLayout https://shiny.rstudio.com/reference/shiny/0.14/flowLayout.html, verticalLayout https://shiny.rstudio.com/reference/shiny/0.14/verticalLayout.html, splitLayout https://shiny.rstudio.com/reference/shiny/0.14/splitLayout.html, et navbarPage https://shiny.rstudio.com/reference/shiny/1.0.5/navbarPage.html. N’hésitez pas à consulter la documentation de chacune de ces fonctions sur le site de Shiny : https://shiny.rstudio.com/. Dans ce livre, nous n’utiliserons que la fonction fluidpage qui est largement utilisée par les développeurs d’application R Shiny.
Dans cette section, vous apprendrez à structurer l’interface utilisateur d’une application web R Shiny en la subdivisant en deux parties : panneau latéral et panneau principal. Très souvent le panneau latéral accueille les commandes d’entrée (inputs) et le panneau principal permet de loger les différentes sorties (outputs) telles que les tableaux, les graphiques, les cartes, etc. C’est la fonction sidebarLayout https://shiny.rstudio.com/reference/shiny/1.3.1/sidebarLayout.html qui permet de faire cette division. A l’intérieur de cette fonction, vous devez définir deux autres fonctions :
sidebarPanel https://shiny.rstudio.com/reference/shiny/0.11/sidebarPanel.html pour définir le panneau latéral et
mainPanel https://shiny.rstudio.com/reference/shiny/0.11/mainPanel.html pour définir le panneau principal.
Après avoir effacé le contenu de la fonction fluidpage, tapez et exécutez le code ci-dessous :
# Interface Utilisateur
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
"Voici le panneau latéral où se trouve souvent les inputs"
),
mainPanel(
"Voici le panneau principal où on affiche souvent les sorties :
Tables de données, graphiques, cartes, etc."
)
)
)
# Serveur
server <- function(input, output) {
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Maintenant que vous savez diviser votre interface utilisateur en deux parties, essayons de créer un input dans le panneau latéral et un grahique dans le panneau principal. Dans la section prochaine, nous reviendrons de manière plus approfondie sur les entrées (inputs) et les sorties (outputs).
# Interface Utilisateur
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(
inputId = 'age',
label = "Quel votre âge",
value = 10, min = 1,
step = 1, max = 150
)
),
mainPanel(
tableOutput(
outputId = 'iris_data'
)
)
)
)
# Serveur
server <- function(input, output) {
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Après exécution de l’application, nous obtenons l’affichage ci-dessous :
La table de données iris ne s’affiche pas dans le panneau principal (mainPanel) parce-que nous n’avons pas écrit dans le serveur, le code qui va servir à générer cette table. Pour ce faire, compléter le code de l’application en écrivant cette fois-ci dans la fonction server :
# Interface Utilisateur
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(
inputId = 'age',
label = "Quel votre âge",
value = 10, min = 1,
step = 1, max = 150
)
),
mainPanel(
tableOutput(
outputId = 'iris_data'
)
)
)
)
# Serveur
server <- function(input, output) {
output$iris_data <- renderTable({
iris
})
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Après exécution de l’application, nous obtenons l’affichage ci-dessous :
Le célèbre ensemble de données sur les espèces d’iris est directement intégré dans R sous forme de dataframe nommée iris. A présent, notre application dispose d’une commande d’entrée où l’utilisateur peut choisir son âge et d’une sortie qui est la table de données iris.
Pour cette section, vous pouvez retenir qu’il est possible de diviser l’interface utilisateur d’une application R Shiny en deux parties : un panneau latéral (fonction sidebarPanel) où se trouve souvent les inputs et un panneau principal (fonction mainPanel) où se trouve souvent les outputs tels que les graphiques, les tableaux, les cartes, etc.
Les inputs et les outputs sont deux concepts qu’il faut bien comprendre en matière de développement web. Dans cette section, nous verrons différents types d’inputs et différents types d’outputs ainsi que leur fonctionnement dans une application R Shiny.
Pour bien fonctionner et être vraiment utiles, les applications Shiny ont besoin d’entrées (inputs) et de sorties (outputs). Les inputs donnent aux utilisateurs la possibilité d’interagir avec l’application et sont très souvent placés dans le panneau latéral (sidebarPanel).
Voici quelques types d’inputs que vous pouvez avoir dans une application Shiny :
numericInput : https://shiny.rstudio.com/reference/shiny/0.11/numericInput.html
sliderInput : https://shiny.rstudio.com/reference/shiny/0.11/sliderInput.html
selectInput : https://shiny.rstudio.com/reference/shiny/0.11/selectInput.html
dateRangeInput : https://shiny.rstudio.com/reference/shiny/0.11/dateRangeInput.html
actionButton : https://shiny.rstudio.com/reference/shiny/0.11/actionButton.html
checkboxInput : https://shiny.rstudio.com/reference/shiny/1.6.0/checkboxInput.html
fileInput : https://shiny.rstudio.com/reference/shiny/1.6.0/fileInput.html
Les deux premiers arguments de toutes les fonctions d’entrées sont pareils et obligatoires pour tous les inputs. Ces deux premiers arguments sont :
inputId : c’est l’identifiant unique de l’input. La valeur de cet argument doit être unique pour chaque entrée car vous l’utiliserez dans le serveur.
label : c’est le texte descriptif de l’input qui s’affiche au-dessus de cet input dans l’interface utilisateur. Ce texte permet de dire à l’utilisateur ce qu’il doit faire avec cette entrée.
Les autres arguments sont optionnels et spécifiques à chaque input.
Les sorties (outputs) peuvent être n’importe quel objet R (dataframe, graphique, carte, liste, texte, etc.) qu’on veut afficher au niveau de l’interface utilisateur (très souvent au niveau du panneau principal). Le processus de création d’une sortie se fait en deux étapes :
1- Création d’un espace réservé à cette sortie au niveau de l’interface utilisateur :
Cet espace est souvent créé dans la fonction mainPanel. Par exemple pour construire un immeuble, il faut préablement trouver un terrain sur lequel faire la construction. De la même manière, pour générer une sortie, il faut préalablement créer dans l’interface utilisateur (très souvent dans le panneau principal) un espace qui va accueillir cette sortie.
Il existe une fonction de création d’espace réservé pour chaque type de sortie que vous voulez créez. Voici quelques-unes :
plotOuput : https://shiny.rstudio.com/reference/shiny/1.6.0/plotOutput.html
tableOutput : https://shiny.rstudio.com/reference/shiny/1.6.0/tableOutput.html
DTOutput : https://www.rdocumentation.org/packages/DT/versions/0.17/topics/dataTableOutput
downloadButton : https://shiny.rstudio.com/reference/shiny/1.0.4/downloadButton.html
plotlyOutput : https://www.rdocumentation.org/packages/plotly/versions/4.9.3/topics/plotly-shiny
textOutput : https://shiny.rstudio.com/reference/shiny/1.6.0/textOutput.html
verbatimTextOutput : https://shiny.rstudio.com/reference/shiny/1.6.0/textOutput.html
Ces fonctions ont le même premier argument qui est aussi obligatoire. Il s’agit de l’argument outpuId qui est l’identifiant unique de cette sortie.
2- Ecriture du code R pour générer cette sortie. Ce code est écrit au niveau du serveur :
Au niveau du serveur, le code pour générer une sortie (output) est écrit à l’intérieur d’une fonction de rendu (render…). Les fonctions de rendu correspondantes aux fonctions de création d’espace réservé citées ci-dessus sont :
renderPlot : https://shiny.rstudio.com/reference/shiny/1.6.0/renderPlot.html
renderTable : https://shiny.rstudio.com/reference/shiny/1.6.0/renderTable.html
renderDT : https://www.rdocumentation.org/packages/DT/versions/0.17/topics/dataTableOutput
downloadHandler : https://shiny.rstudio.com/reference/shiny/1.0.4/downloadHandler.html
renderPlotly : https://www.rdocumentation.org/packages/plotly/versions/4.9.3/topics/plotly-shiny
renderText : https://shiny.rstudio.com/reference/shiny/1.6.0/renderPrint.html
renderPrint : https://shiny.rstudio.com/reference/shiny/1.6.0/renderPrint.html
Il existe plusieurs autres types de fonctions pour les inputs ainsi que de fonctions de création d’espace réservés et leurs fonctions de rendu associées. N’hésitez pas à aller regarder dans la documentation officielle de Shiny : https://shiny.rstudio.com/.
Pour cette section, vous devez retenir que la création d’entrées (inputs) et la création d’espaces réservés pour les sorties (outputs) se fait entièrement dans l’interface utilisateur. Les codes qui vont générer les sorties s’écrivent dans le serveur.
Dans cette section, vous apprendrez comment créer des onglets (c’est la même chose que les onglets que vous créez dans votre navigateur web) au niveau de l’interface utilisateur d’une application Shiny.
A l’étape actuelle de notre application, la commande d’entrée pour
choisir l’âge semble être inutile puisqu’aucune sortie n’est liée à
cette commande. Nous allons donc créer deux onglets : un onglet où se
trouvera la table des données iris et un autre onglet où il y
aura cet affichage : Vous avez 18 ans si
l’utilisateur choisit 18 comme âge. Ce faisant, vous apprendrez comment
utiliser l’identifiant d’un input au niveau du code qui va
générer une sortie dans le serveur.
Pour subdiviser le panneau principal en des onglets, vous devez utiliser la fonction tabsetPanel https://shiny.rstudio.com/reference/shiny/0.14/tabsetPanel.html à l’intérieur de la fonction mainPanel(). Et à l’intérieur de la fonction tabsetPanel(), chaque onglet est créé avec la fonction tabPanel https://shiny.rstudio.com/reference/shiny/0.14/tabPanel.html comme le montre le code ci-dessous :
# Interface Utilisateur
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(
inputId = 'age',
label = "Quel votre âge",
value = 10, min = 1,
step = 1, max = 150
)
),
mainPanel(
tabsetPanel(
# Onglet des données iris
tabPanel(
title = "Data Iris",
tableOutput(
outputId = "iris_data"
)
),
# Onglet accueillant le texte d'affichage de l'âge de l'utilisateur
tabPanel(
title = "Age",
textOutput(
outputId = "age_sortie"
)
)
)
)
)
)
# Serveur
server <- function(input, output) {
# Construction de la sortie dont l'identifiant est "iris_data"
output$iris_data <- renderTable({
iris
})
# Construction de la sortie dont l'identifiant est "age_sortie"
output$age_sortie <- renderText({
paste("Vous avez", input$age, "ans")
})
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Après sauvegarde et exécution du code ci-dessus, nous constatons que les deux onglets et leurs affichages ont bel et bien été créées :
La table de données iris est longue (15O lignes). Imaginez que vous devez afficher une dataframe de 1000 lignes ! Ce sera vraiment pénible comme affichage. Fort heureusement, il est possible de rendre cette table interactive et d’améliorer son affichage. Pour ce faire, au lieu d’utiliser les fonctions tableOutput() et renderTable(), nous les remplacerons respectivement par les fonctions DTOutput https://www.rdocumentation.org/packages/DT/versions/0.17/topics/dataTableOutput et renderDT https://www.rdocumentation.org/packages/DT/versions/0.17/topics/dataTableOutput du package DT https://rdocumentation.org/packages/DT/versions/0.16. Commençons par installer ce package puis importons-le :
install.packages("DT")
library(DT)
Voici le code mis à jour pour permettre l’affichage interactive de la table des données iris :
library(shiny)
library(DT)
# Interface Utilisateur
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(
inputId = 'age',
label = "Quel votre âge",
value = 10, min = 1,
step = 1, max = 150
)
),
mainPanel(
tabsetPanel(
# Onglet des données iris
tabPanel(
title = "Data Iris",
DTOutput(
outputId = "iris_data"
)
),
# Onglet accueillant le texte d'affichage de l'âge de l'utilisateur
tabPanel(
title = "Age",
textOutput(outputId = "age_sortie")
)
)
)
)
)
# Serveur
server <- function(input, output) {
# Construction de la sortie dont l'identifiant est "iris_data"
output$iris_data <- renderDT({
iris
})
# Construction de la sortie dont l'identifiant est "age_sortie"
output$age_sortie <- renderText({
paste("Vous avez", input$age, "ans")
})
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Voici le nouveau affichage de l’onglet Data Iris :
Les observations sont maintenant réparties par page contenant par défaut 10 lignes. Vous pouvez naviguer à travers les pages de la table et aussi choisir d’afficher par exemple 25 lignes par page et même faire une recherche au niveau de la table. Cet affichage est meilleur par rapport à l’ancien et nous l’utiliserons donc pour toutes les autres prochaines applications dans ce livre.
Dans cette section, vous apprendrez à utiliser d’autres fonctions de création d’espace réservé et leurs fonctions de rendu correspondantes. Ceci vous permettra de mieux maîtriser le lien entre l’interface utilisateur et le serveur.
Tout d’abord, nous allons supprimer l’onglet Age et tout ce qui y est lié, ensuite nous allons créer un onglet permettant d’afficher le résumé statistique des données iris et enfin créer un troisième onglet qui affichera l’histogramme de chaque variable quantitative choisie par l’utilisateur.
Voici le code :
library(shiny)
library(DT)
# Interface Utilisateur
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
# Commande pour sélectionner une variable quantitative
selectInput(
inputId = "var",
label = "Choisis une variable :",
choices = names(iris[, -5])
)
),
mainPanel(
tabsetPanel(
# Onglet des données iris
tabPanel(
title = "Data Iris",
DTOutput(outputId = "iris_data")
),
# Onglet accueillant le résumé statistique
tabPanel(
title = "Statistiques",
verbatimTextOutput(outputId = "summary")
),
# Onglet accueillant les histogrammes
tabPanel(
title = "Histogramme",
plotOutput(outputId = "hist")
)
)
)
)
)
# Serveur
server <- function(input, output) {
# Construction de la sortie dont l'identifiant est "iris_data"
output$iris_data <- renderDT({
iris
})
# Construction de la sortie dont l'identifiant est "summary"
output$summary <- renderPrint({
summary(iris)
})
# Construction de la sortie dont l'identifiant est "hist"
output$hist <- renderPlot({
hist(iris[, input$var],
main = "Histogramme",
xlab = input$var)
})
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
La fonction selectInput
a un argument choices qui prend une liste ou un vecteur de
valeurs (chaînes de caractères) parmi lesquelles l’utilisateur va
choisir. Etant donné que nous voulons uniquement l’histogramme de chaque
variable numérique, nous éliminons la variable Species
(cinquième colonne) de la liste de choix possibles d’où le code
choices = names(iris[, -5]).
La fonction verbatimTextOutput a permis de créer un espace pour accueillir le résumé statistique des données. Sa fonction de rendu correspondante utilisée dans le serveur est renderPrint.
La fonction plotOutput a permit de créer un espace dans l’interface utilisateur pour accueillir un graphique. Sa fonction de rendu correspondante utilisée dans le serveur est renderPlot.
Après sauvegarde et exécution du code ci-dessus, voici les affichages des onglets Statistiques et Histogramme :
Ce chapitre couvrira les sujets suivants :
Notion de Réactivité dans Shiny ;
Fonctions downloadButton et downloadHandler ;
Conditionnement de l’affichage d’un élément de l’application ;
Interfaces utilisateur réactives ;
Quelques éléments de finition d’une application Shiny ;
Déploiement d’une application web Shiny.
L’un des concepts les plus importants du développement web avec R Shiny est la Réactivité. La Réactivité est ce qui permet aux sorties de réagir automatiquement aux changement des entrées c’est-à-dire des inputs. Considérons l’exemple ci-dessous :
x <- 7
y <- x * 5
Valeur de y :
y
## [1] 35
Changeons la valeur de x :
x <- 10
Affichons encore la valeur de y :
y
## [1] 35
Nous constatons que y est toujours égal à 35. Si x et y étaient toutes deux des variables réactives, alors à chaque changement de la valeur de x, la valeur de y changerait automatiquement étant donné que y est fonction de x.
Construisons une petite application afin de mieux comprendre ce concept de Réativité. Créez un nouveau fichier app.R en cliquant successivement sur : File, New File, Shiny Web APP. Vous pouvez nommer le dossier ‘app_reactivity’ et cliquez sur Create. Comme nous le savons déjà, chaque nouveau fichier app.R contient par défaut le code d’une application de visualisation d’histogramme.
Commençons par effacer ce que contient les fonctions fluidPage() et server() puis donnons un nom à l’application en utilisant la fonction titlePanel https://shiny.rstudio.com/reference/shiny/0.14/titlePanel.html. L’application que nous voulons construire permettra à l’utilisateur de choisir deux nombres. Dans le panneau principal s’affichera la somme de ces deux nombres ainsi que leur moyenne tout en faisant intervenir la Réactivité. La fonction reactive https://www.rdocumentation.org/packages/shiny/versions/1.6.0/topics/reactive permet de créer des variables réactives :
library(shiny)
# UI
ui <- fluidPage(
titlePanel('Application pour montrer la Réactivité'),
numericInput('num1', 'Choisis un premier nombre',
value = 0),
numericInput('num2', 'Choisis un deuxième nombre',
value = 0),
textOutput('phrase')
)
# server
server <- function(input, output) {
# Créaction d'une variable réactive qui est la somme
somme <- reactive({
input$num1 + input$num2
})
# Créaction d'une variable réactive qui est la moyenne
moyenne <- reactive({
somme() / 2
})
# Création de la sortie dont l'identifiant est : 'phrase'
output$phrase <- renderText({
paste("La somme des nombres", input$num1,
"et", input$num2, "est égale à", somme(),
"et leur moyenne est égale à", moyenne())
})
}
# Run the application
shinyApp(ui = ui, server = server)
Voici l’affichage de l’application :
Chaque fois que l’utilisateur change l’un des inputs, la somme des nombres est mise à jour automatiquement et puisque la moyenne dépend de la somme, elle aussi sera mise à jour automatiquement. Par ailleurs la phrase d’affichage sera aussi naturellement mise à jour automatiquement.
Remarque : Pour accéder à une variable réactive, vous devez forcément utiliser les parenthèses () à la fin du nom de la variable (Exemple : la variable réactive somme()).
Mais il y a un petit souci que nous devons régler. Regardez l’affichage ci-dessous :
Lorsque rien n’est encore choisi comme nombre, des NA apparaissent au niveau de la phrase étant donné qu’il s’agit de valeurs réactives. Cela peut être déroutant pour les utilisateurs. Donc la réactivité, cest bien ! Mais il faut pouvoir la contrôler au sein d’une application pour une meilleure expérience d’utilisation.
Dans une application Shiny, la Réactivité peut être contrôlée avec la fonction isolate. Nous pouvons isoler la sortie de l’application précédente (la phrase) en mettant le code qui génère cette sortie à l’intérieur de la fonction isolate :
# Isolation de la sortie dont l'identifiant est : 'phrase'
output$phrase <- renderText({
isolate({
paste("La somme des nombres", input$num1, "et", input$num2,
"est égale à", somme(), "et leur moyenne est égale à",
moyenne())
})
})
Après sauvegarde et exécution du code, on obtient :
Puisque le morceau de code qui génère la sortie a été isolé, cette sortie ne réagit plus automatiquement aux modifications des inputs. Pour donner le contrôle à l’utilisateur, nous pouvons utiliser un autre input appelé actionButton https://www.rdocumentation.org/packages/shiny/versions/1.6.0/topics/actionButton :
# UI
ui <- fluidPage(
titlePanel('Application pour montrer la Réactivité'),
numericInput('num1', 'Choisis un premier nombre', value = 0),
numericInput('num2', 'Choisis un deuxième nombre', value = 0),
# Création d'un boutton d'exécution de l'application.
# Ce boutin permet de contrôler la réactivité
actionButton(inputId = 'run', label = 'Execution'),
textOutput('phrase')
)
# server
server <- function(input, output) {
# Créaction d'une variable réactive qui est la somme
somme <- reactive({
input$num1 + input$num2
})
# Créaction d'une variable réactive qui est la moyenne
moyenne <- reactive({
somme() / 2
})
# Création de la sortie dont l'identifiant est : 'phrase'
output$phrase <- renderText({
input$run # Ajout de l'ID de actionButton juste au-dessus de isolate()
isolate({
paste("La somme des nombres", input$num1, "et", input$num2,
"est égale à", somme(), "et leur moyenne est égale à",
moyenne())
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
L’utilisation de actionButton se fait donc en deux étapes :
Création de la commande actionButton au niveau de l’interface utilisateur ;
Ajout de l’identifiant unique de cette commande au-dessus de la fonction isolate().
Le boutton ainsi créé permet à l’utilisateur de saisir les paramètres d’entrée puis d’exécuter l’application après les avoir saisi. Ce faisant, la réactivité est totalement contrôlée. Après avoir cliqué sur le boutton Execution, on obtient l’affichage ci-dessous :
Le contrôle de la réactivité est une étape très importante dans le développement d’une application Shiny surtout lorsque l’application contient des calculs très lourds qui consomment beaucoup de mémoire. Par contre, pour d’autres types d’application, l’utilisateur a une meilleure expérience d’utilisation lorsqu’il constate directement la réactivité à chaque fois qu’il change l’un des paramètres d’entrée (inputs).
Pour cette leçon, retenez que vous pouvez créer des variables réactives en utilisant la fonction reactive(). De plus, vous pouvez contrôler le phénomène de réactivité de votre application Shiny en utilisant conjointement les fonctions isolate() et actionButton().
Dans cette section, vous apprendrez à conditionner l’affichage d’un ou plusieurs éléments d’une application en utilisant la fonction conditionalPanel https://www.rdocumentation.org/packages/shiny/versions/1.6.0/topics/conditionalPanel. Cette fonction fait partie des outils de R Shiny qui donnent beaucoup plus de dynamisme à une application.
Pour bien comprendre l’utilisation de la puissante fonction conditionalPanel(), je vous suugère de regarder ma vidéo YouTube sur le sujet : https://youtu.be/QXcjjwkA1YU
Ci-dessous le code qui a généré l’application montrée dans la vidéo :
library(shiny)
library(DT)
# UI
ui <- fluidPage(
# Application title
titlePanel("Deuxième Application Iris"),
sidebarLayout(
sidebarPanel(
selectInput('plot_type',
'Type de Graphique',
choices = c('Histogram',
'Scatter Plot')),
selectInput('var', 'Choisis une variable :',
choices = names(iris[, -5])),
conditionalPanel(
condition = "input.plot_type == 'Scatter Plot'",
selectInput('var2', 'Choisis une 2è variable :',
choices = names(iris[, -5]))
)
),
mainPanel(
tabsetPanel(
tabPanel('Data', DTOutput('iris_data'),
downloadButton('save_data', 'Save to CSV')),
tabPanel('Statistiques',
verbatimTextOutput('summary')),
tabPanel('Graphique',
conditionalPanel(
condition = "input.plot_type == 'Histogram'",
plotOutput('hist')),
conditionalPanel(
condition = "input.plot_type == 'Scatter Plot'",
plotOutput('nuage'))
)
)
)
)
)
# server
server <- function(input, output) {
df <- reactive({
iris
})
output$iris_data <- renderDT({
df()
})
# Résumé statistique
output$summary <- renderPrint({
summary(df())
})
# Histogramme
output$hist <- renderPlot({
hist(df()[, input$var], main = 'Histogramme',
xlab = input$var)
})
# Sauvegarde de df au format csv
output$save_data <- downloadHandler(
filename <- function(){
paste("data_", Sys.Date(), ".csv", sep = ',')
},
content <- function(filename){
write.csv(df(), filename)
}
)
# Nuage de points
output$nuage <- renderPlot({
plot(df()[, input$var], df()[, input$var2],
xlab = input$var, ylab = input$var2)
})
}
# Run the application
shinyApp(ui = ui, server = server)
L’affichage conditionnel se trouve au niveau de la liste déroulante Type de Graphique et au niveau de l’onglet comme le montre la vidéo ainsi que les images ci-dessous :
C’est génial de savoir utiliser la fonction ConditionalPanel() afin de donner plus de dynamise à votre application Shiny. Est-ce que vous pouvez aller au-delà de ce dynamisme ? Bien sûr que oui ! Les fonctions uiOutput https://shiny.rstudio.com/reference/shiny/0.14/renderUI.html et renderUI https://shiny.rstudio.com/reference/shiny/0.14/renderUI.html permettent de rendre votre application Shiny extraordinairement dynamique. Elles permettent principalement de créer une interface utilisateur réactive. Cela vous permet de modifier votre interface utilisateur (par exemple, le nombre ou le contenu des boutons radio) en fonction des fonctions réactives.
Regardez cette vidéo explicative : https://youtu.be/frKiUnhX4yI
Ci-dessous le code qui a permi de créer l’application montrée dans la vidéo :
# Dynamisme avec les fonctions uiOutput et renderUI
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Application pour expliquer les fonctions uiOutput et renderUI"),
sidebarLayout(
sidebarPanel(
numericInput("numInputs",
"Combien d'inputs voulez-vous ?", 2),
uiOutput("inputGroup")
),
mainPanel(textOutput("inputValues"))
)
))
# Server
server <- shinyServer(function(input, output) {
# observation des changements dans "numInputs" et création du nombre correspondant d'entrées
observeEvent(input$numInputs, {
output$inputGroup = renderUI({
input_list <- lapply(1:input$numInputs, function(i) {
# pour chaque entrée générée dynamiquement, donnez un nom différent
inputName <- paste("input", i, sep = "")
numericInput(inputName, inputName, 1)
})
do.call(tagList, input_list)
})
})
# Petite démo pour montrer les valeurs par l'utilisateur au niveau de chaque input
output$inputValues <- renderText({
paste(lapply(1:input$numInputs, function(i) {
inputName <- paste("input", i, sep = "")
input[[inputName]]
}))
})
})
# Run the application
shinyApp(ui = ui, server = server)
Le code ci-dessus vous sera certainement utile surtout dans le projet 3 (Chapitre 6).
Vous avez à présent toutes les armes recquises pour affronter les projets de ce livre (Chapitres 4, 5 et 6). Mais avant de commencer les projets, laissez-moi vous montrer comment vous pouvez embellir une application R Shiny. Sachez que l’esthétique est aussi un paramètre très important à prendre en compte dans le développement de votre application web.
Le premier élément d’esthétique concerne les thèmes. Pour changer le thème d’une application Shiny, vous avez besoin du package shinythemes https://rdocumentation.org/packages/shinythemes/versions/1.2.0 :
install.packages('shinythemes')
library(shinythemes)
Voici quelque thèmes que vous pouvez utiliser pour votre application web : https://rstudio.github.io/shinythemes/. Les noms de cest thèmes sont : cerulean, cosmo, cyborg, darkly, flatly, journal, lumen, paper, readable, sandstone, simplex, slate, spacelab, superhero, united, yeti.
Pour choisir par exemple le thème superhero, écrivez le code
theme = shinytheme(superhero) au niveau de l’interface
utilisateur :
# Changement du thème de l'application Iris
library(shiny)
library(DT)
library(shinythemes)
# Interface Utilisateur
ui <- fluidPage(
# Thème 'superhero'
theme = shinytheme('superhero'),
# Nom de l'application
titlePanel("Application Iris"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var",
label = "Choisis une variable :",
choices = names(iris[, -5]))
),
mainPanel(
tabsetPanel(
# Onglet des données iris
tabPanel(title = "Data Iris",
DTOutput(outputId = "iris_data"),
# Ajout d'un bouton de téléchargement
downloadButton('save_data', 'Save to CSV')
),
# Onglet accueillant le résumé statistique
tabPanel(title = "Statistiques",
verbatimTextOutput(outputId = "summary")),
# Onglet accueillant les histogrammes
tabPanel(title = "Histogramme",
plotOutput(outputId = "hist"))
)
)
)
)
# Serveur
server <- function(input, output) {
# Création d'une dataframe réactive stockant les données iris
df <- reactive({
iris
})
# Sauvegarde de la dataframe au format CSV
# équivaut à la création de la sortie dont l'identifiant est "save_data"
output$save_data <- downloadHandler(
filename <- function(){
paste("data_", Sys.Date(), ".csv", sep = ",")
},
content <- function(filename){
write.csv(df(), filename)
}
)
# Construction de la sortie dont l'identifiant est "iris_data"
output$iris_data <- renderDT({
df()
})
# Construction de la sortie dont l'identifiant est "summary"
output$summary <- renderPrint({
summary(df())
})
# Construction de la sortie dont l'identifiant est "hist"
output$hist <- renderPlot({
hist(df()[, input$var],
main = "Histogramme",
xlab = input$var)
})
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
On obtient l’affichage ci-dessous :
A la place du code theme = shinytheme(superhero), vous
pouvez juste mettre le code themeSelector(). Ce faisant,
vous permettez à l’utilisateur de choisir lui-même, dans une liste
déroulante, le thème qui lui convient :
En dehors des thèmes, vous pouvez aussi ajouter, comme élément de finition à votre application, un lien web (votre profil Linkedin, votre site web, etc.) en utilisant tags$a :
library(shiny)
library(DT)
library(shinythemes)
# Interface Utilisateur
ui <- fluidPage(
# Liste déroulante de thèmes
themeSelector(),
# Nom de l'application
titlePanel("Application Iris"),
h2("Auteur : Josué AFOUDA"),
# Ajout d'un lien web
tags$a("Mon site web", href = "https://afouda-datascience.com/"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var",
label = "Choisis une variable :",
choices = names(iris[, -5]))
),
mainPanel(
tabsetPanel(
# Onglet des données iris
tabPanel(title = "Data Iris",
DTOutput(outputId = "iris_data"),
# Ajout d'un bouton de téléchargement
downloadButton('save_data', 'Save to CSV')
),
# Onglet accueillant le résumé statistique
tabPanel(title = "Statistiques",
verbatimTextOutput(outputId = "summary")),
# Onglet accueillant les histogrammes
tabPanel(title = "Histogramme",
plotOutput(outputId = "hist"))
)
)
)
)
# Serveur
server <- function(input, output) {
# Création d'une dataframe réactive stockant les données iris
df <- reactive({
iris
})
# Sauvegarde de la dataframe au format CSV
# équivaut à la création de la sortie dont l'identifiant est "save_data"
output$save_data <- downloadHandler(
filename <- function(){
paste("data_", Sys.Date(), ".csv", sep = ",")
},
content <- function(filename){
write.csv(df(), filename)
}
)
# Construction de la sortie dont l'identifiant est "iris_data"
output$iris_data <- renderDT({
df()
})
# Construction de la sortie dont l'identifiant est "summary"
output$summary <- renderPrint({
summary(df())
})
# Construction de la sortie dont l'identifiant est "hist"
output$hist <- renderPlot({
hist(df()[, input$var],
main = "Histogramme",
xlab = input$var)
})
}
# Exécution de l'application
shinyApp(ui = ui, server = server)
Lorsque l’utilisateur clique sur Mon site web, il est redirigé automatiquement sur : https://afouda-datascience.com/
L’embellissement d’une application web ne nécessite donc pas de connaître forcément les langages CSS et HTML. Toujours en utilisant du code R, vous pouvez rendre votre application beaucoup plus attrayante.
Dans la prochaine et dernière section de ce chapitre, nous verrons comment déployer une application web R Shiny.
Shiny est aussi apprécié pour sa facilité de déploiement. Dans cette section, je vais vous montrer comment déployer une application Shiny dans le server de R Studio c’est-à-dire shinyapps.io https://www.shinyapps.io/. Tout ce qui suit provient de la documentation officielle de R Studio concernat le déploiement des applications web Shiny. Vous pouvez consulter l’article intititulé : Shiny - Getting started with shinyapps.io (rstudio.com) sur : https://shiny.rstudio.com/articles/shinyapps.html
Suivez rigoureusement les étapes ci-dessous :
install.packages('rsconnect')
library(rsconnect)
Dès que votre compte est créé, Shinyapps.io vous génère automatiquement un token et un secret. Ces codes vous permettront de configurer le package rsconnect pour pouvoir déployer vos applications depuis votre RStudio.
vous devez cliquer sur Copy to clipboard pour copier vos codes d’accès
Au niveau de la console de RStudio, collez ce que vous avez copié précédemment puis exécuté. Après cette étape, vous pouvez maintenant déployez vos applications.
Dans cette vidéo : https://youtu.be/56Lo1oNqpCw, je vous montre un exemple de déploiement et comment récupérer l’url de votre application afin de la partager à qui vous voulez.
Les 3 chapitres qui vont suivre concernent les projets. Vous vous plongerez dans la peau d’un Développeur web R Shiny pour réaliser une application dans des situations différentes.
La majorité des informations commerciales potentiellement utilisables par les entreprises ne sont pas structurées, mais souvent sous la forme de données textuelles. L’exploration de texte fournit un ensemble de techniques qui permettent de tirer des informations exploitables à partir de données non structurées.
Il y a plusieurs façons d’analyser des textes pour en tirer des informations utiles. Le nuage de mots (Word cloud) est certainement l’un des moyens les plus utilisés. Un nuage de mots est une représentation visuelle des données textuelles. Un mot qui apparaît plus souvent dans un morceau de texte apparaîtra plus grand dans le nuage de mots.
L’une des utilisations courantes de R Shiny est la transformation d’une fonction en une application graphique pour faciliter son partage avec d’autres personnes sans que ces dernières aient besoin d’installer R sur leur PC. Dans ce projet, je vous fournit une fonction qui génère un nuage de mots à partir d’un texte. Votre rôle est de créer une application web R Shiny interactive à partir de cette fonction. Cette application, comme le montre la vidéo (lien ci-dessous) doit permettre à l’utilisateur de rentrer du texte (une ou plusieurs lignes) et avoir un nuage de mots comme sortie.
La vidéo ci-contre vous montre un exemple de l’application que vous devez créer : https://youtu.be/N-g4clHVURo
Comme vous l’avez vu dans la vidéo, les nuages de mots constituent un outil très utile pour mettre en évidence les mots les plus utilisés, et donc les mots les plus importants, dans un document texte.
Voici la fonction à transformer en application R Shiny pour créer des nuages de mots à partir d’un texte.
# Fonction pour créer un nuage de mots
library(wordcloud2)
library(tm)
create_wordcloud <- function(data, num_words = 100, background = "white") {
# Conversion du texte fournu en une dataframe de fréquences de mots
if (is.character(data)) {
corpus <- Corpus(VectorSource(data))
corpus <- tm_map(corpus, tolower)
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeNumbers)
corpus <- tm_map(corpus, removeWords, stopwords("french"))
tdm <- as.matrix(TermDocumentMatrix(corpus))
data <- sort(rowSums(tdm), decreasing = TRUE)
data <- data.frame(word = names(data), freq = as.numeric(data))
}
# num_words
if (!is.numeric(num_words) || num_words < 3) {
num_words <- 3
}
# top n des mots qui apparaissent le plus dans le texte
data <- head(data, n = num_words)
if (nrow(data) == 0) {
return(NULL)
}
wordcloud2(data, backgroundColor = background)
}
La fonction ci-dessus a 03 arguments :
data : le texte fourni par l’utilisateur. Le nuage
de mots est généré à partir de ce texte.
num_words : le nombre maximal de mots qui seront
affichés dans le nuage de mots. Par défaut il est égal à 100.
Vous devez donner la possibilité à l’utilisateur de spécifier
une valeur pour cet argument.
background : la couleur du fond.
L’utilisateur doit pouvoir choisir la couleur qu’il
veut.
Voilà ! Vous avez toutes les armes nécessaires pour développer cette application web. Je vous conseille de réfléchir et de concevoir cette application selon votre inspiration.
Bon travail !
Ci-dessous, le code de mon application ( https://afoudajosue.shinyapps.io/word_cloud/) que je vous propose comme correction de ce projet.
# Importation des librairies necessaires
library(shiny)
library(shinythemes)
library(wordcloud2)
library(colourpicker)
library(tm)
# Fonction Word cloud ########################################
create_wordcloud <- function(data, num_words = 100, background = "white") {
# Conversion du texte fournu en une dataframe de fréquences de mots
if (is.character(data)) {
corpus <- Corpus(VectorSource(data))
corpus <- tm_map(corpus, tolower)
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeNumbers)
corpus <- tm_map(corpus, removeWords, stopwords("french"))
tdm <- as.matrix(TermDocumentMatrix(corpus))
data <- sort(rowSums(tdm), decreasing = TRUE)
data <- data.frame(word = names(data), freq = as.numeric(data))
}
# num_words
if (!is.numeric(num_words) || num_words < 3) {
num_words <- 3
}
# top n des mots qui apparaissent le plus dans le texte
data <- head(data, n = num_words)
if (nrow(data) == 0) {
return(NULL)
}
wordcloud2(data, backgroundColor = background)
}
##################################################################
ui <- fluidPage(
theme = shinytheme("flatly"),
h1("APPLICATION WEB R SHINY POUR LA VISUALISATION DE NUAGE DE MOTS"),
h2("Auteur : Josue AFOUDA"),
tags$a("Josue Afouda", href='https://afouda-datascience.com/'),
sidebarLayout(
sidebarPanel(
# textarea input
textAreaInput("text", "Enter text", rows = 10),
numericInput("num", "Maximum number of words",
value = 100, min = 5),
colourInput("col", "Background color", value = "white"),
actionButton(inputId = "run", label = "Run")
),
mainPanel(
wordcloud2Output("cloud")
)
)
)
server <- function(input, output) {
output$cloud <- renderWordcloud2({
input$run
isolate({
# Graphique de visualisation du nuage de mots
create_wordcloud(data = input$text, num_words = input$num,
background = input$col)
})
})
}
shinyApp(ui = ui, server = server)
Le succès d’une entreprise dépend largement de sa connaissance du comportement de sa clientèle. Dans la plupart des cas, il est impossible de connaître chaque client de façon individuelle. Heureusement, il existe des techniques (Clustering) permettant de céer des groupes de clients en fonction de similitudes identifiées (caractéristiques communes) : segmentation de la clientèle.
La segmentation de clientèle est une tâche récurrente en entreprise. Dans ce projet n°2, vous devez développer une application performante et complète R Shiny qui permet d’automatiser cette tâche. Vous devez implémenter des méthodes pour la recherche du meilleur nombre de clusters avec visualisation des résultats. Toutefois, l’utilisateur devra avoir un contrôle total sur le choix du nombre de clusters et pourra ainsi varier ce nombre et observer les changements.
De plus, vous devez implémenter au moins deux techniques de réduction de la dimensionnalité afin de permettre aux utilisateurs de l’application de pouvoir réduire la dimension de grands ensembles de données.
La vidéo ci-contre présente un exemple de l’application que vous devez réaliser : https://youtu.be/LaqjRe_PUgA
Dans cette partie, je vous présente le processus de segmentation des données en utilisant l’algorithme des k-moyennes (k-means).
L’algorithme de clustering K-means est un algorithme de partitionnement qui permet de trouver un nombre prédéfini k de sous-groupes (clusters) homogènes dans un grand ensemble de données. Il fait partie de l’apprentissage automatique non supervisé. L’idée basique des méthodes de regroupement (ou de partitionnement) est de définir des clusters de telle sorte que la distance inter-cluster soit minimisée et que la distance intra-cluster soit maximale.
Sauf dans certains cas précis, on ne connait pas d’avance le nombre de clusters. Plusieurs méthodes comme la méthode du coude (elbow method) et la méthode de la silhouette moyenne (average silhouette) permettent de déterminer le nombre optimal de clusters.
Avec la méthode du coude, le meilleur k est celui à partir duquel on n’observe plus d’amélioration sensible de la qualité de la segmentation (clustering) au fur et à mesure que k augmente (k = 1 à 10 par exemple). Pour cette valeur k, on observera une coude au niveau de la courbe donnant l’inertie en fonction du nombre de clusters (k).
La méthode de la silhouette moyenne mesure à quel point chaque individu (observation) est intégré dans son groupe. Une largeur de silhouette moyenne élevée indique un bon cluster. La méthode de la silhouette moyenne calcule la silhouette moyenne des observations pour différentes valeurs de k. Le nombre optimal de groupes k est celui qui maximise la silhouette moyenne sur une plage de valeurs possibles pour k.
Nous allons segmenter les données du jeu de données iris en supposant que les données soient non-étiquetées.
L’algorithme des K-means utilise la distance entre les points. Donc, il est absolument nécessaire que les données soient à la même échelle afin qu’il n’y ait pas de variables qui aient beaucoup plus de poids que d’autres. Vous pouvez soit normaliser les données (répartir les valeurs entre 0 et 1) soient les standardiser (moyenne = 0 et écart-type = 1).
# Données iris
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
# Suppression de la colonne 'Species'
iris$Species <- NULL
# Normalisation des données
normalize <- function(x) {
return ((x - min(x)) / (max(x) - min(x)))
}
iris_norm <- normalize(iris)
# Statistiques des données normalisées
summary(iris_norm)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :0.5385 Min. :0.2436 Min. :0.1154 Min. :0.00000
## 1st Qu.:0.6410 1st Qu.:0.3462 1st Qu.:0.1923 1st Qu.:0.02564
## Median :0.7308 Median :0.3718 Median :0.5449 Median :0.15385
## Mean :0.7363 Mean :0.3791 Mean :0.4690 Mean :0.14094
## 3rd Qu.:0.8077 3rd Qu.:0.4103 3rd Qu.:0.6410 3rd Qu.:0.21795
## Max. :1.0000 Max. :0.5513 Max. :0.8718 Max. :0.30769
# Standardisation des données
iris_stand <- as.data.frame(scale(iris))
# Statistiques des données standardisées
summary(iris_stand)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :-1.86378 Min. :-2.4258 Min. :-1.5623 Min. :-1.4422
## 1st Qu.:-0.89767 1st Qu.:-0.5904 1st Qu.:-1.2225 1st Qu.:-1.1799
## Median :-0.05233 Median :-0.1315 Median : 0.3354 Median : 0.1321
## Mean : 0.00000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.67225 3rd Qu.: 0.5567 3rd Qu.: 0.7602 3rd Qu.: 0.7880
## Max. : 2.48370 Max. : 3.0805 Max. : 1.7799 Max. : 1.7064
La fonction fviz_nbclust du package factoextra permet de déterminer et de visualiser le nombre optimal de clusters pour un ensemble de données. Pour utiliser ces fonctions, vous devez préalablement installer le package factoextra :
# Installation du package factoextra
install.packages('factoextra')
# Importation de la librairie factoextra
library(factoextra)
# Méthode du coude pour déterminer le meilleur nombre de clusters
elbow_method <- fviz_nbclust(iris_stand,
FUNcluster = kmeans,
method = "wss")
elbow_method
La méthode du coude suggère 3 clusters pour les données.
Au niveau de l’application, vous devez donner la possibilité à l’utilisateur de choisir entre les données normalisées et celles standardisées.
Voyons à présent le nombre de clusters suggéré par la méthode de la silhouette moyenne :
#Méthode de la silhouette moyenne
silhouette_method <- fviz_nbclust(iris_stand, FUNcluster = kmeans, method = "silhouette")
silhouette_method
Deux clusters ont été suggérés par la méthode de la silhouette moyenne.
set.seed(123)
#Exécution de l'algorithme k-means avec k = 3
model <- kmeans(iris_stand,
centers = 3,
nstart = 20)
# Visualisation des résultats
plot(iris[, c("Sepal.Width", "Petal.Length")],
col = as.factor(model$cluster),
pch = 20, cex = 3)
Comme dans la vidéo (https://youtu.be/LaqjRe_PUgA) montrant un exemple de l’application que vous devez créer, l’utilisateur de votre application doit avoir le contrôle sur le choix du nombre de clusters.
Par ailleurs, vous avez le libre choix d’aller au-delà des objectifs fixés pour ce projet en ajoutant d’autres fonctionnalités à votre application.
Il existe plusieurs techniques plus ou moins complexes pour réduire la dimension d’un ensemble de données. La technique la plus populaire est certainement l’Analyse en Composantes Principales (ACP). En dehors de cette technique, il y a aussi l’algorithme t-SNE ou t-Distributed Stochastic Neighbour Embedding. L’objectif ici n’est pas de vous donner un cours exhaustif sur ces techniques qui relèvent de l’apprentissage automatique non-supervisé, mais plutôt de vous montrer comment les implémenter dans une application R Shiny.
L’ACP est une technique d’extraction linéaire de variables. L’ACP crée de nouvelles variables indépendantes (appelées composantes principales) à partir des variables originelles tout en maximisant la variance des données dans le nouvel espace de faible dimension.
Ci-dessous un exemple d’application de l’ACP à l’ensemble de données iris :
# Création d'un modèle ACP
model_acp <- prcomp(iris_stand,
scale = FALSE,
center = FALSE)
# Visualisation du % de variance expliquée par chaque composante
fviz_screeplot(model_acp,
ncp = ncol(iris_stand))
# Nuage de points des deux premières composantes
plot(model_acp$x[, 1:2])
En utilisant des données normalisées ou standardisées, nous pouvons
mettre en toute sécurité FALSE aux arguments
center et scale de la fonction prcomp
https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/prcomp.
La visualisation du diagramme à barre montrant le pourcentage de variance expliquée par chaque composante principale permet de choisir le nombre de composantes optimal qui expliquent la majorité de la variance contenue dans les données.
La matrice du nouvel ensemble de données se trouve dans l’attribut
x de model_pca. Au niveau de
l’application, vous devez donner la possibilité à l’utilisateur de
télécharger ce nouvel ensemble de données pour une utilisation
ultérieure.
La technique d’analyse en composantes principales peut capturer uniquement la structure linéaire présente dans l’ensemble originel. La technique d’Incorporation de voisin stochastique t-distribué (t-SNE) fait partie des techniques avancées de réduction de dimensionnalité qui permettent de lever cette limitation de l’ACP. t-SNE est une technique de réduction de dimensionnalité non-linéaire qui permet de bien visualiser les ensembles de données de très grande dimension.
# Installation de la librairie Rtsne
install.packages('Rtsne')
# Importation de la librairie Rtsne
library(Rtsne)
Ci-dessous un exemple d’application de l’algorithme t-SNE à l’ensemble de données iris :
set.seed(123)
# Modèle t-SNE
model_tsne <- Rtsne(iris_stand,
pca = FALSE,
dims = 2,
check_duplicates = FALSE,
max_iter = 1000)
# Graphique
plot(model_tsne$costs,
type = 'l',
ylab = 'Costs')
# Nouvel ensemble de données
data_tsne <- data.frame(tsne_x = model_tsne$Y[, 1],
tsne_y =model_tsne$Y[, 2])
head(data_tsne)
## tsne_x tsne_y
## 1 1.3240557 18.82725
## 2 0.8582019 15.50260
## 3 1.7228626 16.36917
## 4 1.7741727 15.67820
## 5 1.8117423 19.30537
## 6 1.3601846 20.94415
La fonction Rtsne
https://www.rdocumentation.org/packages/Rtsne/versions/0.15/topics/Rtsne
permet d’implémenter l’algorithme t-SNE dans R. Etant donné
qu’il s’agit d’un processus aléatoire, il est bien de s’assurer de la
reproductibilité des résultats à chaque exécution du code
(set.seed(123)).
l’argument pca permet de spécifier si on réalise ou
non une ACP sur les données d’origine avant d’appliquer l’algorithme
t-SNE. Au niveau de l’application à développer, vous
devez donner le contrôle à l’utilisateur sur cet
argument.
l’argument dims permet de spécifier le nombre de
dimensions que l’on souhaite avoir dans le nouvel ensemble de données.
Par défaut, il est égal à 2.
-check_duplicates = FALSE veut dire qu’on ne veut pas
rechercher s’il y a des doublons ou pas dans l’ensemble originel.
L’argument max_iter indique le nombre maximal
d’itérations. Par défaut, il est égal à 1000. Le nombre optimal
d’itérations dépend des données. Vous devez donc donner le
contrôle à l’utilisateur sur cet argument.
le but de t-SNE est de minimiser la divergence K-L entre l’espace d’origine et le nouveau. Ces valeurs proches de zéro (graphique des coûts) correspondent à des données qui conservent leur structure d’origine dans le nouvel espace de faible dimension.
Voilà ! Vous avez toutes les armes nécessaires pour développez cette application web. Je vous conseille de réfléchir et de concevoir cette application selon votre inspiration.
Ci-dessous, le code de mon application (https://afoudajosue.shinyapps.io/kmeans_dim_reduction_app/) que je vous propose comme correction de ce projet n°2 :
# Proposition de code pour le projet 2
# Importation des packages nécessaires
library(shiny)
library(shinythemes)
library(ggplot2)
library(plotly)
library(DT)
library(factoextra)
library(Rtsne)
# S'assurer de la reproductibilité des résultats de l'algorithme t-SNE qui est un processus aléatoire
seed = 111
set.seed(seed)
# Fonction pour normaliser les donnees entre 0 et 1
normalize <- function(x) {
return ((x - min(x)) / (max(x) - min(x)))
}
# Interface Utilisateur (frontend)
ui <- fluidPage(
theme = shinytheme("flatly"),
h1("R SHINY APP FOR K-MEANS CLUSTERING AND DIMENSIONALITY REDUCTION"),
h2("Author : Josue AFOUDA"),
tags$a("Josue Afouda",href='https://www.linkedin.com/in/josueafouda'),
sidebarLayout(
sidebarPanel(
textInput('file', "Entrez l'url du fichier CSV de vos donnees :",
value = 'https://raw.githubusercontent.com/JosueAfouda/Mes-Projets-R-Shiny/main/iris_num.csv'),
checkboxInput("header", "Header", TRUE),
helpText("Decochez ce bouton si votre fichier n'a pas de noms de colonnes"),
selectInput('scaled_met',
'Normalisation ou Standardisation des donnees :',
c('None',
'Normalisation',
'Standardisation')),
selectInput('dim_reduction',
'Dimensionnality Reduction:',
c('PCA',
'T-SNE')),
conditionalPanel(
condition = "input.dim_reduction == 'T-SNE'",
checkboxInput("pca_tsne",
"T-SNE with PCA or not:",
FALSE),
numericInput('n_iter',
'Number of iterations:',
1000, min = 1000,
step = 500)
),
helpText("Le nombre de clusters est un entier naturel strictement positif"),
numericInput('n_clusters',
'Selectionnez le nombre de clusters :',
value = 3, min = 1),
helpText("Choisissez les 2 variables a representer dans un nuage de points"),
numericInput('varx', 'Numero de la variable en Axe X :',
value = 1, min = 1),
numericInput('vary', 'Numero de la variable en Axe Y :',
value = 2, min = 1),
helpText("Cliquer sur 'Submit' après chaque changement de paramètre(s)"),
actionButton("go", "Submit"),
),
# Tableaux et Graphiques dans le panneau principal
mainPanel(
tabsetPanel(
tabPanel('Cleaned Data', DTOutput('dataframe'),
downloadButton('download_clean_data',
label = 'Telechargez les donnees nettoyees :')),
tabPanel('Norm/Stand Data', DTOutput('scaled'),
downloadButton('download_stand_data',
label = 'Telechargez les donnees standardisees ou nourmalisees :')),
tabPanel('Dim. Reduction',
conditionalPanel(condition = "input.dim_reduction == 'PCA'",
plotOutput("pca_screeplot"),
plotOutput("pca_biplot"),
numericInput('first_cp',
'How many first components do you want to choose ?',
2, min = 1, step = 1),
downloadButton('save_pca_data',
label = 'Save PCA Data :'),
DTOutput('table_pca')),
conditionalPanel(condition = "input.dim_reduction == 'T-SNE'",
plotOutput("tsne_costs_plot"),
downloadButton('save_tsne_data',
label = 'Save TSNE Data :'),
DTOutput("tsne_data"),
plotOutput('tsne_biplot'))
),
tabPanel('Elbow Method',
plotlyOutput('elbow', height = "550px")),
tabPanel('Average Silhouette',
plotlyOutput('silhouette', height = "550px")),
tabPanel('Clusters Visualization',
plotOutput("scatter_plot", 850, 600))
)
)
)
)
# Serveur (backend)
server <- function(input, output) {
df <- reactive({
df_clean <- read.csv(input$file, header = input$header)
df_clean <- df_clean[, !sapply(df_clean, is.character)]
df_clean <- df_clean[complete.cases(df_clean), ]
df_clean
})
output$dataframe <- renderDT({
input$go
isolate({
df()
})
})
output$download_clean_data <- downloadHandler(
filename <- function() {
paste("clean_data_",
Sys.Date(),
".csv",
sep=",")
},
content <- function(file) {
write.csv(df(), file)
}
)
data <- reactive({
if (input$scaled_met == 'Normalisation') {
normalize(df())
} else if (input$scaled_met == 'Standardisation') {
as.data.frame(scale(df()))
} else if (input$scaled_met == 'None') {
df()
}
})
# PCA Model
model_pca <- reactive({
prcomp(data(),
scale = FALSE,
center = FALSE)
})
# PCA Scree Plot
output$pca_screeplot <- renderPlot({
input$go
isolate({
fviz_screeplot(model_pca(),
ncp = ncol(data()))
})
})
# PCA Biplot
output$pca_biplot <- renderPlot({
input$go
isolate({
plot(model_pca()$x[, 1:2])
})
})
# PCA Data
output$table_pca <- renderDT({
input$go
isolate({
as.data.frame(model_pca()$x[, 1:input$first_cp])
})
})
# Save PCA Data
output$save_pca_data <- downloadHandler(
filename <- function() {
paste("pca_data_",
Sys.Date(),
".csv",
sep=",")
},
content <- function(file) {
write.csv(as.data.frame(model_pca()$x[, 1:input$first_cp]),
file)
}
)
# TSNE model
model_tsne <- reactive({
Rtsne(data(),
pca = input$pca_tsne,
dims = 2,
check_duplicates = FALSE,
max_iter = input$n_iter)
})
# Costs Plot for TSNE
output$tsne_costs_plot <- renderPlot({
input$go
isolate({
plot(model_tsne()$costs,
type = 'l',
ylab = 'Costs')
})
})
# TSNE 2 dim data
output$tsne_data <- renderDT({
input$go
isolate({
data.frame(tsne_x = model_tsne()$Y[, 1],
tsne_y =model_tsne()$Y[, 2])
})
})
# TSNE scatter plot
output$tsne_biplot <- renderPlot({
input$go
isolate({
plot(data.frame(tsne_x = model_tsne()$Y[, 1],
tsne_y =model_tsne()$Y[, 2]))
})
})
# Save TSNE Data
output$save_tsne_data <- downloadHandler(
filename <- function() {
paste("tsne_data_",
Sys.Date(),
".csv",
sep=",")
},
content <- function(file) {
write.csv(data.frame(tsne_x = model_tsne()$Y[, 1],
tsne_y =model_tsne()$Y[, 2]),
file)
}
)
output$scaled <- renderDT({
input$go
isolate({
data()
})
})
output$download_stand_data <- downloadHandler(
filename <- function() {
paste("scaled_or_norm_data_",
Sys.Date(),
".csv",
sep=",")
},
content <- function(file) {
write.csv(data(), file)
}
)
output$elbow <- renderPlotly({
input$go
isolate({
fviz_nbclust(data(),
FUNcluster = kmeans,
method = "wss")
})
})
output$silhouette <- renderPlotly({
input$go
isolate({
fviz_nbclust(data(),
FUNcluster = kmeans,
method = "silhouette")
})
})
# K-Means Model
model <- reactive({
kmeans(data(),
centers = input$n_clusters,
nstart = 20)
})
data_selected <- reactive({
cbind(data()[input$varx],
data()[input$vary])
})
output$scatter_plot <- renderPlot({
input$go
isolate({
plot(data_selected(),
col = as.factor(model()$cluster),
pch = 20, cex = 3)
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
Ce projet est le plus grand parmi les 3 projets de ce livre.
Vous êtes Développeur R Shiny et vous venez de décrocher une mission en Freelance à 1000$ Net la journée auprès d’une société d’investissement en Bourse. Super ! Félicitations à vous :)
Cette société d’investissement vous charge de lui créer une application web pour l’analyse et l’optimisation de portefeuille. Elle opère principalement dans le marché des Actions (Stocks). Grâce à cette application, les Gestionnaires de Portefeuille de cette société pourront analyser efficacement les données des actifs à leur charge et prendre ainsi des décisions éclairées concernant leurs investissements. De plus, avec cette application ils pourront mieux conseiller leurs clients actuels et futurs.
La société d’investissement veut une application performante, dynamique, simple d’utilisation et qui présente toutes les fonctionnalités nécessaires pour la création, l’analyse et l’optimisation de portefeuille.
Vous devez livrer l’application R Shiny ainsi qu’une vidéo démo dans laquelle vous faites une présentation expliquant son utilisation. L’application doit contenir les fonctionnalités ci-dessous :
Possibilité pour l’utilisateur de choisir le nombre d’actifs constituant le portefeuille ainsi que le poids de chaque actif ;
Récupération des prix journaliers de clôture des Actions sur une période donnée et possibilité de les sauvegarder au format CSV ;
Affichage des statistiques (moyenne, médiane, quartiles, etc.) sur les prix de clôture ;
Graphiques de visualisation des prix de clôture (Histogrammes, graphique linéaire de chaque actif) ;
Calcul des Rendements journaliers de chaque Action et possibilité de les sauvegarder au format CSV ;
Affichage des statistiques (moyenne, médiane, quartiles, etc.) des Rendements ;
Visualisation des Rendements (Histogrammes et Graphiques linéaires) ;
Calcul et visualisation des corrélations (corrélation entre chaque paire d’actifs) ;
Graphiques de visualisation de l’évolution des paramètres Beginning of Period et End of Period ;
Agrégation des Rendements journaliers pour obtenir les Rendements moyens annuels, trimestriels, mensuels ou hebdomadaires et possibilité de les sauvegarder au format CSV ;
Calcul des rendements moyens annualisés mobiles, des volatilités annualisées mobiles, des ratio de sharpe annualisés mobiles et visualisation de leur évolution (l’utilisateur doit avoir la possibilité de choisir la taille de la fenêtre mobile. Cette taille sera exprimée en nombre de mois) ;
Calcul et Visualisation des Drawdowns (pertes potentielles) ;
Optimisation de portefeuille par différentes méthodes (Mean-Variance Efficient et Imposing Constraints) ;
Evaluation de l’optimisation.
Etant donné que vous n’êtes pas un spécialiste de l’investissement en Bourse, le Directeur Exécutif de la société vous a expliqué en quelques mots leur process pour analyser les portefeuilles. En gros : Récupération des données sur Yahoo Finance et leur analyse se fait principalement avec les packages PerformanceAnalytics https://www.rdocumentation.org/packages/PerformanceAnalytics et tseries https://www.rdocumentation.org/packages/tseries de R.
N.B : Le package PerformanceAnalytics a été créé par deux célèbres Analystes quantitatifs américains Peter Carl et Brian Peterson.
Puisque les commanditaires de la mission ne vont pas faire votre boulot à votre place, vous êtes donc dans l’obligation contractuelle de faire vos recherches afin de bien comprendre le processus allant de la récupération des données à l’optimisation des portefeuilles. C’est ce processus que vous allez implémenter dans une application web développée avec R Shiny et permettre ainsi aux gestionnaires de portefeuille de la société, avec de simples clics, de prendre des décisions éclairées sur les investissements.
Cette section est capitale pour la création de l’application. En effet, après avoir lu cette section, vous serez capables :
de récupérer des données boursières sur Yahoo Finance (https://fr.finance.yahoo.com) ;
d’analyser ces données (Statistiques et Visualisation) ;
de calculer les rendements, de les analyser (statistiques et visualisation) et de les agréger ;
de réaliser une analyse de performance d’un portefeuille ;
de réaliser une optimisation de portefeuille ;
d’évaluer votre optimisation.
Comme vous l’aurez compris, c’est cette section qui vous aidera à configurer l’interface utilisateur et à implémenter tous les calculs nécessaires au niveau du serveur de l’application dont vos avez la charge de créer. Donc, concentrez-vous et prenez le soin de bien lire chaque étape. Je vous rassure qu’il n’y a rien de compliqué :)
So, let’s go !
Importons d’abord les packages nécessaires :
library(PerformanceAnalytics)
library(quantmod)
library(tseries)
Avant de faire n’importe quelle analyse, il faut forcément importer préalablement les données. Ce paragraphe est basé sur ma vidéo YouTube ci-contre : https://www.youtube.com/watch?v=Kbk5Ivrlh2g
Ci-dessous le code pour récupérer par exemple les prix de clôture de Google, Amazon, Apple, Microsoft et IBM pour la période allant du 1er janvier 2015 au 1er janvier 2020 :
# Importation des données de plusieurs titres
stocks <- new.env()
stocks_names <- c("GOOG", "AMZN", "AAPL", "MSFT", "IBM")
getSymbols(stocks_names,
env = stocks,
from = as.Date('2015-01-01'),
to = as.Date('2020-01-01'))
## [1] "GOOG" "AMZN" "AAPL" "MSFT" "IBM"
# Extraction des prix de clôture de chaque titre pour en former un seul ensemble de données au format xts
close_prices <- do.call(merge, lapply(stocks, Cl))
# Affichage des premières observations
head(close_prices)
## AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 2015-01-02 27.3325 154.9331 26.16865 15.4260 46.76
## 2015-01-05 26.5625 152.4952 25.62315 15.1095 46.33
## 2015-01-06 26.5650 149.2065 25.02928 14.7645 45.65
## 2015-01-07 26.9375 148.2314 24.98640 14.9210 46.23
## 2015-01-08 27.9725 151.4532 25.06518 15.0230 47.59
## 2015-01-09 28.0025 152.1128 24.74058 14.8465 47.19
Vous êtes à présent capables d’importer les données de plusieurs Stocks à partir de Yahoo Finance et de récupérer une table des prix de clôture. SUPER ! Vous avez fait un pas dans la construction de l’application. Bien qu’il reste beaucoup de choses à apprendre avant de commencer le développement de l’application web, vous pouvez être fier d’avoir acquérir cette nouvelle compétence :).
Vous pouvez aussi calculer des statistiques récapitulatives et tracer des graphiques.
# Statistiques des prix de clôture
summary(close_prices)
## Index AAPL.Close IBM.Close GOOG.Close
## Min. :2015-01-02 Min. :22.59 Min. :102.8 Min. :24.56
## 1st Qu.:2016-04-04 1st Qu.:28.88 1st Qu.:133.7 1st Qu.:36.47
## Median :2017-07-01 Median :37.64 Median :142.0 Median :46.47
## Mean :2017-07-01 Mean :38.62 Mean :142.3 Mean :45.68
## 3rd Qu.:2018-09-30 3rd Qu.:46.50 3rd Qu.:151.3 3rd Qu.:55.76
## Max. :2019-12-31 Max. :73.41 Max. :173.9 Max. :68.06
## AMZN.Close MSFT.Close
## Min. : 14.35 Min. : 40.29
## 1st Qu.: 33.24 1st Qu.: 53.52
## Median : 48.39 Median : 71.01
## Mean : 55.75 Mean : 81.07
## 3rd Qu.: 83.85 3rd Qu.:106.25
## Max. :101.98 Max. :158.96
Excellent ! Vous voyez que c’est simple de coder en R :)
Voyons maintenant comment construire les histogrammes des prix de clôture de chaque actif. Vous connaissez certainement plusieurs manières plus ou moins simples pour construire un histogramme dans R. Je vais vous montrer comment utiliser la fonction chart.Histogram pour contruire un histogramme :
# Construction de l'histogramme des prix de clôture de Microsoft
chart.Histogram(close_prices[, 'MSFT.Close'],
xlab = 'Prix de clôture',
main = 'Histogramme des prix de clôture de Microsoft')
Avec une boucle for, construisons les histogrammes des prix de clôture pour tous les stocks.
# Histogrammes des prix de tous les stocks
par(mfrow = c(2, 3))
for (i in 1:ncol(close_prices)) {
chart.Histogram(close_prices[, i],
xlab = 'Prix de clôture')
}
Traçons maintenant un graphique représentant l’évolution des prix de clôture. Vous pouvez le faire simplement en utilisant la fonction plot.zoo :
# Prix de clôture au cours du temps
plot.zoo(close_prices,
main = 'Evolution des prix de clôture',
col = 1:ncol(close_prices))
Il existe plusieurs types de rendements et donc plusieurs façons de les calculer. L’objectif ici n’est pas de vous gaver de toutes les théories relatives au concept de rendement. Pour faire simple, pour calculer le rendement d’un actif entre hier et aujourd’hui, il faut faire le prix d’aujourd’hui moins le prix d’hier divisé par le prix d’hier. La fonction Return.calculate vous permet de calculer facilement les rendements :
# Calcul des rendements journaliers de chaque stock
stocks_daily_returns <- Return.calculate(close_prices)
head(stocks_daily_returns)
## AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 2015-01-02 NA NA NA NA NA
## 2015-01-05 -2.817159e-02 -0.015734865 -0.020845590 -0.020517308 -0.009195809
## 2015-01-06 9.415529e-05 -0.021566098 -0.023177086 -0.022833317 -0.014677314
## 2015-01-07 1.402217e-02 -0.006535526 -0.001713233 0.010599749 0.012705323
## 2015-01-08 3.842227e-02 0.021734956 0.003153035 0.006836003 0.029418127
## 2015-01-09 1.072518e-03 0.004355485 -0.012950553 -0.011748652 -0.008405148
Vous remarquez que la première ligne des données obtenues consiste en des valeurs manquantes (NA). Ceci est tout à fait normal (voir définition du rendement ci-dessus) car pour la première date, il n’y a pas de prix antérieur disponible à comparer avec le prix actuel. Nous pouvons donc supprimer cette première ligne.
# Suppression de la première ligne
stocks_daily_returns <- stocks_daily_returns[-1]
head(stocks_daily_returns)
## AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 2015-01-05 -2.817159e-02 -0.015734865 -0.020845590 -0.020517308 -0.009195809
## 2015-01-06 9.415529e-05 -0.021566098 -0.023177086 -0.022833317 -0.014677314
## 2015-01-07 1.402217e-02 -0.006535526 -0.001713233 0.010599749 0.012705323
## 2015-01-08 3.842227e-02 0.021734956 0.003153035 0.006836003 0.029418127
## 2015-01-09 1.072518e-03 0.004355485 -0.012950553 -0.011748652 -0.008405148
## 2015-01-12 -2.464069e-02 -0.016780849 -0.007295950 -0.018590240 -0.012502670
Supposons qu’on veuille créer un portefeuille à pondération égale
c’est-à-dire que tous les actifs ont le même poids. Sachant qu’il y a 5
actifs (Google, Amazon, Apple, Microsoft et IBM), le poids d’un actif
sera égal à 1/5.
Vous pouvez calculer les rendements journaliers de ce portefeuille en utilisant la fonction Return.portfolio :
# Calcul des rendements du portefeuille à pondération égale
portfolio <- Return.portfolio(stocks_daily_returns,
weights = c(1/5, 1/5, 1/5, 1/5, 1/5),
rebalance_on = NA,
verbose = TRUE)
# Affichage
head(portfolio$returns)
## portfolio.returns
## 2015-01-05 -0.018893032
## 2015-01-06 -0.016458223
## 2015-01-07 0.005854080
## 2015-01-08 0.020063554
## 2015-01-09 -0.005463228
## 2015-01-12 -0.016071806
En mettant verbose = TRUE, cela vous permet d’avoir une
liste portfolio de plusieurs résultats dont les rendements
du portefeuille (portfolio$returns).
L’argument rebalance_on est très important car il permet
de définir à quelle fréquence le portefeuille sera rééquilibré.
Au niveau de l’application, l’utilisateur doit avoir le contrôle
sur cet argument.
Fusionnons les objets stocks_daily_returns et
portfolio$returns pour en former un seul objet
returns :
# Fusion des rendements de stocks et du portefeuille
returns <- merge(stocks_daily_returns, portfolio$returns)
head(returns)
## AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 2015-01-05 -2.817159e-02 -0.015734865 -0.020845590 -0.020517308 -0.009195809
## 2015-01-06 9.415529e-05 -0.021566098 -0.023177086 -0.022833317 -0.014677314
## 2015-01-07 1.402217e-02 -0.006535526 -0.001713233 0.010599749 0.012705323
## 2015-01-08 3.842227e-02 0.021734956 0.003153035 0.006836003 0.029418127
## 2015-01-09 1.072518e-03 0.004355485 -0.012950553 -0.011748652 -0.008405148
## 2015-01-12 -2.464069e-02 -0.016780849 -0.007295950 -0.018590240 -0.012502670
## portfolio.returns
## 2015-01-05 -0.018893032
## 2015-01-06 -0.016458223
## 2015-01-07 0.005854080
## 2015-01-08 0.020063554
## 2015-01-09 -0.005463228
## 2015-01-12 -0.016071806
# Résumé statistique des rendements
summary(returns)
## Index AAPL.Close IBM.Close
## Min. :2015-01-05 Min. :-0.0996074 Min. :-7.628e-02
## 1st Qu.:2016-04-05 1st Qu.:-0.0059374 1st Qu.:-6.267e-03
## Median :2017-07-03 Median : 0.0008550 Median : 4.008e-04
## Mean :2017-07-02 Mean : 0.0009091 Mean :-6.593e-05
## 3rd Qu.:2018-10-01 3rd Qu.: 0.0088787 3rd Qu.: 6.491e-03
## Max. :2019-12-31 Max. : 0.0704216 Max. : 8.864e-02
## GOOG.Close AMZN.Close MSFT.Close
## Min. :-0.0769661 Min. :-0.078197 Min. :-0.0925335
## 1st Qu.:-0.0060294 1st Qu.:-0.006551 1st Qu.:-0.0055195
## Median : 0.0006286 Median : 0.001305 Median : 0.0008427
## Mean : 0.0008596 Mean : 0.001593 Mean : 0.0010753
## 3rd Qu.: 0.0082567 3rd Qu.: 0.009935 3rd Qu.: 0.0080535
## Max. : 0.1605243 Max. : 0.141311 Max. : 0.1045224
## portfolio.returns
## Min. :-0.0541520
## 1st Qu.:-0.0046547
## Median : 0.0012176
## Mean : 0.0009823
## 3rd Qu.: 0.0075758
## Max. : 0.0769380
Avec une boucle for, construisons les histogrammes des rendements des stocks et de ceux du portefeuille :
# Histogramme des rendements des stocks et de ceux du portefeuille
par(mfrow = c(2, 3))
for (i in 1:ncol(returns)) {
chart.Histogram(returns[, i])
}
Construisons un graphique montrant l’évolution des rendements des actifs et ceux du portefeuille :
# Evolution des rendements des stocks et ceux du portefeuille
plot.zoo(returns,
main = 'Rendements des Stocks et du Portefeuille',
col = 1:ncol(returns) + 1)
Une fois encore, l’objectif de ce projet n’est pas de vous former pour devenir un expert de l’analyse quantitative. Toutefois, il est toujours bien de comprendre un peu le domaine dans lequel vous intervenez en tant que Développeur d’applications web et ceci quelque soit la framework que vous utilisez.
Beginning of Period (BOP) : c’est le poids de début de période pour chaque actif. Le poids BOP d’un actif est calculé en utilisant les poids d’entrée (ou les poids supposés) et les paramètres de rééquilibrage donnés. Le poids BOP de la période suivante est soit les poids EOP (voir ci-dessous) de la période précédente, soit les poids d’entrée donnés sur une période de rééquilibrage.
End of Period (EOP) : c’est le poids de fin de période pour chaque actif. La valeur BOP de chaque actif est la valeur EOP de l’actif de la période précédente, sauf en cas de rééquilibrage. En cas d’événement de rééquilibrage, la valeur BOP de l’actif correspond au poids de rééquilibrage multiplié par la valeur EOP du portefeuille. Cela fournit effectivement un changement de coût de transaction nulle aux valeurs de position à compter de cette date pour refléter le rééquilibrage. Notez que la somme des valeurs BOP des actifs est la même que la valeur du portefeuille EOP de la période précédente.
Bon, ne vous inquiétez pas si vous ne comprenez pas très bien ces deux concepts. En tant que Développeur d’application web en Freelance, vous devez seulement implémenter le calcul de ces paramètres au niveau de l’application.
# Evolution des BOP
plot.zoo(portfolio$BOP.Weight,
main = 'BOP.Weight',
col = 1:ncol(stocks_daily_returns))
# Evolution des EOP
plot.zoo(portfolio$EOP.Weight,
main = 'EOP.Weight',
col = 1:ncol(stocks_daily_returns))
Les fonctions apply.yearly, apply.quarterly, apply.monthly et apply.weekly permettent d’agréger les données.
Par exemple, pour calculer les rendements moyens mensuels du portefeuille :
# Rendements moyens mensuels du portefeuille
pf_monthly_returns <- apply.monthly(portfolio$returns, mean)
head(pf_monthly_returns)
## portfolio.returns
## 2015-01-30 0.0006489469
## 2015-02-27 0.0036380739
## 2015-03-31 -0.0013165040
## 2015-04-30 0.0035140462
## 2015-05-29 0.0001575551
## 2015-06-30 -0.0012067055
# Evolution au cours du temps des rendements moyens mensuels
plot(pf_monthly_returns,
main = "Rendements moyens mensuels du portefeuille")
addLegend("topleft", on=1, lty = 1,
legend.names = colnames(pf_monthly_returns))
Vous pouvez de la même manière calculer et visualiser les rendement moyens agrégés mensuellement, trimestriellement et hebdomadaires.
La corrélation entre les actifs est très importante et a des conséquences importantes sur la performance globale du portefeuille.
Vous pouvez calculer et visualiser les corrélations entre actifs en utilisant la fonction chart.Correlation.
# Corrélation entre les rendements des actifs
chart.Correlation(stocks_daily_returns,
histogram = FALSE)
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
## Warning in par(usr): argument 1 does not name a graphical parameter
La plus faible corrélation est celle entre Amazon et IBM.
Toujours dans le cadre de l’analyse de la performance du portefeuille, vous devez calculer la moyenne annualisée mobile des rendements sur une période ainsi que l’écart-type (qui représente la volatilité) et le ratio de sharpe annualisés mobiles des rendements du portefeuille sur cette même période en utilisant la fonction chart.RollingPerformance. Par exemple, pour une fenêtre de 12 mois :
# Rendements moyens annualisés mobiles sur 12 mois
chart.RollingPerformance(R = pf_monthly_returns,
width = 12,
FUN = "Return.annualized")
# Ecart-type des Rendements annualisés mobiles sur 12 mois
chart.RollingPerformance(R = pf_monthly_returns,
width = 12,
FUN = "StdDev.annualized")
# Ratio de sharpe annualisés mobiles sur 12 mois
chart.RollingPerformance(R = pf_monthly_returns,
width = 12,
FUN = "SharpeRatio.annualized")
L’écart-type ou la variance mesure tous les écarts à la moyenne, aussi bien ceux à la hausse que ceux à la baisse. Mais ce qui inquiète les investisseurs, ce sont les pertes (rendements négatifs). Une bonne mesure du risque devrait donc se concentrer sur les pertes potentielles (drawdowns).
Vous pouvez visualiser l’évolution des drawdowns en utilisant la fonction chart.Drawdown :
# Pertes potentielles du portefeuille
chart.Drawdown(pf_monthly_returns,
main = "Evolution des pertes potentielles du portefeuille")
Il existe plusieurs méthodes de détermination des poids optimaux des actifs constituants un portefeuille.
Un portefeuille efficace de moyenne-variance peut être obtenu comme solution de minimisation de la variance du portefeuille sous la contrainte que le rendement attendu du portefeuille est égal à un rendement cible. La fonction portfolio.optim permet de calculer les poids optimaux.
# Portefeuille efficace de moyenne-variance
opt1 <- portfolio.optim(
apply.monthly(stocks_daily_returns, mean)
)
# Poids optimaux du portefeuille de moyenne-variance
w <- opt1$pw
names(w) <- colnames(stocks_daily_returns)
print(w)
## AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 0.1510329 0.1087181 0.3974075 0.0693755 0.2734660
# Diagramme à barre montrant les poids optimaux
barplot(w)
Les investisseurs sont souvent contraints par les valeurs maximales autorisées pour les pondérations du portefeuille. Ces contraintes peuvent en fait être un avantage. L’avantage d’une contrainte de pondération maximale est que le portefeuille ultérieur sera moins concentré sur certains actifs. Il y a cependant un inconvénient à cela. L’inconvénient est que le même rendement cible peut ne plus être possible ou sera obtenu au détriment d’une volatilité plus élevée.
Dans notre cas ici, le portefeuille est constitué de 5 stocks. Le gestionnaire peut décider que le poids d’un stock ne doit pas dépasser 0,3. Voici comment vous pouvez calculer ce portefeuille :
# Vecteur de poids maximum
max_w <- rep(0.3, ncol(stocks_daily_returns))
# Portefeuille à contrainte sur les poids
opt2 <- portfolio.optim(
apply.monthly(stocks_daily_returns, mean),
reshigh = max_w
)
# Récupération des poids
w2 <- opt2$pw
names(w2) <- colnames(stocks_daily_returns)
w2
## AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 0.16840807 0.13652030 0.30000000 0.09507162 0.30000000
# Diagramme à barre montrant les poids optimaux
barplot(w2)
Au niveau de l’application, vous devez donner le contrôle au gestionnaire de choisir la valeur maximale que doit avoir le poids d’un actif dans le portefeuille.
A présent, je vais vous apprendre à utiliser l’analyse d’échantillons fractionnés pour évaluer de manière objective ce que pourraient être les performances futures du portefeuille optimisé. L’analyse par échantillon fractionné consiste à diviser l’échantillon de rendements historiques en deux parties : la première partie s’appelle échantillon d’estimation et la deuxième partie est l’échantillon d’évaluation (comme le train/test split en Machine Learning).
# Echantillon d'estimation
returns_estim <- window(
apply.monthly(stocks_daily_returns, mean),
start = '2015-01-01',
end = '2017-12-31'
)
# Portefeuille calculé avec l'échantillon d'estimation
pf_estim <- portfolio.optim(returns_estim)
# Echantillon d'évaluation
returns_eval <- window(
apply.monthly(stocks_daily_returns, mean),
start = '2018-01-31',
end = '2020-01-01'
)
# Portefeuille calculé avec l'échantillon d'évaluation
pf_eval <- portfolio.optim(returns_eval)
# Visualisation de l'évaluation
plot(pf_estim$pw, pf_eval$pw,
xlab = "estimation portfolio weights",
ylab = "evaluation portfolio weights",
main = 'Evaluation portfolio weights VS Estimation portfolio weights')
abline(a = 0, b = 1, lty = 3)
Si les pondérations des 2 portefeuilles (estimation et évaluation) sont identiques, elles doivent être sur la ligne de 45 degrés.
Précédemment, je vous ai décrit toutes les étapes à implémenter dans l’application que vous allez développer. Je vous conseille de réfléchir et de concevoir cette application selon votre inspiration.
Néanmoins, étant donné que cette formation est à but pédagogique, je vous présente dans la vidéo ci-contre une démo du genre d’application que vous devez réaliser : www.youtube.com/watch?v=YUM9QfYuFiU
Voilà ! Vous avez toutes les armes pour développez cette application web. Réfléchissez et au boulot. Rappelez-vous que c’est quand même une mission de 10 jours c’est-à-dire 10000$ à la clé ! :)
BONNE CHANCE :)
Ci-dessous, le code complet de mon application ( https://afoudajosue.shinyapps.io/portfolio_analysis/) que je vous propose en correction de ce projet :
# Code de mon aplication
# Importation des librairies nécessaires
library(shiny)
library(shinythemes)
library(DT)
library(zoo)
library(xts)
library(quantmod)
library(PerformanceAnalytics)
library(tseries)
# Interface Utilisateur (Frontend)
ui <- shinyUI(fluidPage(
theme = shinytheme("flatly"),
titlePanel("R SHINY WEB APP FOR FINANCIAL PORTFOLIO ANALYSIS"),
h2("Author : Josue AFOUDA"),
tags$a("Founder & Executive Director of J.A DATATECH CONSULTING",
href='https://afouda-datascience.com/'),
sidebarLayout(
sidebarPanel(
numericInput("numInputs",
"Number of Assets in Portfolio",
1, max = 4),
# dynamic inputs
uiOutput("inputGroup"),
uiOutput("inputWeights"),
dateRangeInput('period', 'Date range:',
'2015-01-01', '2020-12-31'),
selectInput("rebalance",
'Rebalance on:',
choices = c("None",
"Annualy" = "years",
"Quartely" = "quarters",
"Monthly" = "months",
"Weekly" = "weeks",
"Daily" = "days")),
actionButton("go", "Submit"),
helpText(' Subsequent figures will be drawn in an nr-by-nc array'),
numericInput('nl', 'Select nr:', 1,
min = 1, step = 1),
numericInput('nc', 'Select nc:',
1, min = 1, step = 1)
),
# show dynamic input values
mainPanel(textOutput("message"),
textOutput("inputValues"),
textOutput("message2"),
textOutput("inputValues2"),
tabsetPanel(
# Création des onglets et sous-onglets
tabPanel(
'Prices',
tabsetPanel(
tabPanel(
'Data of Prices',
DTOutput('df'),
downloadButton(
'save_price_data',
label = 'Save to CSV :'
)
),
tabPanel(
'Prices Statistics',
verbatimTextOutput("prices_stats")
),
tabPanel(
'Histograms of Prices',
plotOutput('prices_hists', 1000, 650)
),
tabPanel(
'Plot of Prices',
plotOutput('plot', 1000, 650)
)
)
),
tabPanel(
'Returns',
tabsetPanel(
tabPanel(
"Data of Returns",
DTOutput('returns'),
downloadButton(
'save_return_data',
label = 'Save to CSV :'
)
),
tabPanel(
'Returns Statistics',
verbatimTextOutput("returns_stats")
),
tabPanel(
'Hists of Returns',
plotOutput('returns_hists', 1000, 650)
),
tabPanel(
'Plot of Returns',
plotOutput('plot_returns', 1000, 650)
),
tabPanel(
'Beginning Of Period ',
plotOutput('bop', 1000, 650)
),
tabPanel(
'End of Period ',
plotOutput('eop', 1000, 650)
)
)
),
tabPanel(
'Aggregated Returns',
tabsetPanel(
tabPanel(
'Mean Aggregated Returns',
selectInput(
'time_per',
'From Daily Returns to:',
choices = c(
'Montly Returns',
'Weekly Returns',
'Quarterly Returns',
'Yearly Returns'
)
),
DTOutput('aggregated_returns'),
downloadButton(
'save_return_agg',
label = 'Save to CSV :'
)
),
tabPanel(
'Aggregated Returns Stats',
verbatimTextOutput("agg_returns_stats")
),
tabPanel(
'Aggregatd Returns Plots',
plotOutput('plot_agg_returns', 1000, 650)
)
)
),
tabPanel(
'Analyzing performance',
tabsetPanel(
tabPanel(
'Correlation',
plotOutput('returns_cor', 1000, 650)
),
tabPanel(
'Rolling annualized mean',
numericInput(
'Width',
'length of the window (in months):',
12, min = 1, step = 1
),
plotOutput('rolling_mean', 1000, 650)
),
tabPanel(
'Rolling annualized Standard Deviation',
plotOutput('rolling_std', 1000, 650)
),
tabPanel(
'Rolling annualized Sharpe Ratio',
plotOutput('rolling_sharpe', 1000, 650)
),
tabPanel(
'Drawdowns',
plotOutput('drawdown', 1000, 650)
)
)
),
####ONGLET PORTOFOLIO OPTIMIZATION##############
tabPanel(
'Portfolio Optimization',
tabsetPanel(
tabPanel(
'Mean-Variance Efficient',
tabsetPanel(
tabPanel(
'Results',
verbatimTextOutput("opt1_print")
),
tabPanel(
'Visualization',
plotOutput('opt1_weights', 1000, 650)
)
)
),
tabPanel(
'Imposing Constraints',
tabsetPanel(
tabPanel(
'Results',
sliderInput(
'max_w', 'Max weigh:', 0.5,
min = 0.05, max = 1.0
),
verbatimTextOutput("opt2_print")
),
tabPanel(
'Visualization',
plotOutput('opt2_weights', 1000, 650)
)
)
),
tabPanel(
'Split-Sample evaluation',
tabsetPanel(
tabPanel(
'Estimation Sample',
dateRangeInput(
'window_estim',
'Date range for Estimation Sample:',
'2015-01-01', '2020-12-31'
),
verbatimTextOutput("opt3_print")
),
tabPanel(
'Evaluation Sample',
dateRangeInput(
'window_eval',
'Date range for Evaluation Sample:',
'2015-01-01', '2020-12-31'
),
verbatimTextOutput("opt4_print")
),
tabPanel(
'Visualization',
plotOutput('opt3_weights', 1000, 650)
)
)
)
)
)
)
)
)
))
######################## SERVER (BACKEND) ############################
server <- shinyServer(function(input, output) {
# observe changes in "numInputs", and create corresponding number of inputs
observeEvent(input$numInputs, {
output$inputGroup = renderUI({
input_list <- lapply(1:input$numInputs, function(i) {
# for each dynamically generated input, give a different name
inputName <- paste("Asset ", i, sep = "")
textInput(inputName, inputName, 'AMZN')
})
do.call(tagList, input_list)
})
})
###################
observeEvent(input$numInputs, {
output$inputWeights = renderUI({
input_list_weight <- lapply(1:input$numInputs, function(i) {
# for each dynamically generated input, give a different name
inputWeight <- paste("Weight ", i, sep = "")
sliderInput(inputWeight, inputWeight, 0.01, min = 0.0, max = 1.0)
})
do.call(tagList, input_list_weight)
})
})
#####################
# Affichages des actifs choisis par l'utilisateur
observeEvent(input$go, {
output$message <- renderText({
print('Your portfolio consists of the following assets:')
})
})
# Variable reactive qui enregistre les symboles
tickers <- reactive({
paste(lapply(1:input$numInputs, function(i) {
inputName <- paste("Asset ", i, sep = "")
input[[inputName]]
}))
})
observeEvent(input$go, {
output$inputValues <- renderText({
tickers()
})
})
########################################################################
observeEvent(input$go, {
output$message2 <- renderText({
print(
'Check that the sum of the weights is exactly equal to 1. The respective weights of these assets are:'
)
})
})
# Variable reactive qui enregistre les poids des actifs
num_weights <- reactive({
paste(lapply(1:input$numInputs, function(i) {
inputWeight <- paste("Weight ", i, sep = "")
#sliderInput(inputWeight, inputWeight, 0.1, min = 0.05, max = 1.0)
input[[inputWeight]]
}))
})
observeEvent(input$go, {
output$inputValues2 <- renderText({
num_weights()
})
})
#######################################################################
# Variable reactive des prix de cloture
close_price_df <- reactive({
stocks <- new.env()
getSymbols(tickers(),
env = stocks,
from = as.Date(input$period[1]),
to = as.Date(input$period[2]))
do.call(merge, lapply(stocks, Cl))
})
observeEvent(input$go, {
output$df <- renderDT({
close_price_df()
})
})
output$save_price_data <- downloadHandler(
filename <- function() {
paste("price_data_", Sys.Date(), ".csv", sep=",")
},
content <- function(file) {
write.csv(close_price_df(), file)
}
)
observeEvent(input$go, {
output$prices_stats <- renderPrint({
summary(close_price_df())
})
})
# Histogrammes des prix de clotures
observeEvent(input$go, {
output$prices_hists <- renderPlot({
par(mfrow = c(input$nl, input$nc))
for (i in 1:input$numInputs) {
chart.Histogram(close_price_df()[, i],
xlab = 'Closing Prices')
}
})
})
observeEvent(input$go, {
output$plot <- renderPlot({
plot.zoo(close_price_df(),
main = 'Closing Stocks Prices',
col = 1:input$numInputs)
})
})
# Rendements journaliers des stocks
stocks_returns <- reactive({
Return.calculate(close_price_df())[-1]
})
output$save_return_data <- downloadHandler(
filename <- function() {
paste("return_data_", Sys.Date(), ".csv", sep=",")
},
content <- function(file) {
write.csv(stocks_returns(), file)
}
)
# Rendements journaliers du Portefeuille
pf <- reactive({
if (input$rebalance == "None") {
Return.portfolio(stocks_returns(),
weights = as.numeric(num_weights()),
rebalance_on = NA,
verbose = TRUE)
} else {
Return.portfolio(stocks_returns(),
weights = as.numeric(num_weights()),
rebalance_on = input$rebalance,
verbose = TRUE)
}
})
# Fusion des rendements des stocks et du portefuille
returns_df <- reactive({
merge(stocks_returns(), pf()$returns)
})
# Rendements des actions et du portefeuille
observeEvent(input$go, {
output$returns <- renderDT({
returns_df()
})
})
# statistiques sur les rendements
observeEvent(input$go, {
output$returns_stats <- renderPrint({
summary(returns_df())
})
})
# Histogrammes des rendements
observeEvent(input$go, {
output$returns_hists <- renderPlot({
par(mfrow = c(input$nl, input$nc))
for (i in 0:input$numInputs + 1) {
chart.Histogram(returns_df()[, i],
methods = c("add.density", "add.normal"))
}
})
})
# Correlation
observeEvent(input$go, {
output$returns_cor <- renderPlot({
chart.Correlation(stocks_returns())
})
})
# Evolution des rendements
observeEvent(input$go, {
output$plot_returns <- renderPlot({
plot.zoo(returns_df(),
main = 'Stocks and Portfolio Returns',
col = 1:input$numInputs + 1)
})
})
# BOP
observeEvent(input$go, {
output$bop <- renderPlot({
plot.zoo(pf()$BOP.Weight,
main = 'BOP.Weight',
col = 1:input$numInputs)
})
})
# EOP
observeEvent(input$go, {
output$eop <- renderPlot({
plot.zoo(pf()$EOP.Weight,
main = 'EOP.Weight',
col = 1:input$numInputs)
})
})
# Agregation des rendements moyens
agg_returns_df <- reactive({
if (input$time_per == 'Montly Returns') {
apply.monthly(returns_df(), mean)
} else if (input$time_per == 'Weekly Returns') {
apply.weekly(returns_df(), mean)
} else if (input$time_per == 'Quarterly Returns') {
apply.quarterly(returns_df(), mean)
} else if (input$time_per == 'Yearly Returns') {
apply.yearly(returns_df(), mean)
}
})
observeEvent(input$go, {
output$aggregated_returns <- renderDT({
agg_returns_df()
})
})
output$save_return_agg <- downloadHandler(
filename <- function() {
paste("returns_aggregated_", Sys.Date(), ".csv", sep=",")
},
content <- function(file) {
write.csv(agg_returns_df(), file)
}
)
# Stats sur les donnees aggregees
observeEvent(input$go, {
output$agg_returns_stats <- renderPrint({
summary(agg_returns_df())
})
})
# Histogrammes
# Plots
observeEvent(input$go, {
output$plot_agg_returns <- renderPlot({
plot(agg_returns_df(),
main = input$time_per)
addLegend("topleft", on=1,
legend.names = colnames(agg_returns_df()),
lty = 1)
})
})
# Monthly mean returns of portfolio
MonthlyReturns <- reactive({
apply.monthly(pf()$returns, mean)
})
# Rendements moyens annualises
observeEvent(input$go, {
output$rolling_mean <- renderPlot({
chart.RollingPerformance(R = MonthlyReturns(),
width = input$Width,
FUN = "Return.annualized")
})
})
# Voaltilites annualisees
observeEvent(input$go, {
output$rolling_std <- renderPlot({
chart.RollingPerformance(R = MonthlyReturns(),
width = input$Width,
FUN = "StdDev.annualized")
})
})
# Ratio de Sharpe annualises
observeEvent(input$go, {
output$rolling_sharpe <- renderPlot({
chart.RollingPerformance(R = MonthlyReturns(),
width = input$Width,
FUN = "SharpeRatio.annualized")
})
})
# Pertes potentielles
observeEvent(input$go, {
output$drawdown <- renderPlot({
chart.Drawdown(MonthlyReturns(),
main = "Evolution of the drawdowns")
})
})
# ONGLET OPTIMISATION DE PORTEFEUILLE##########################################
# Creation d'un portefeuille optimise a partir des actifs
opt <- reactive({
portfolio.optim(apply.monthly(stocks_returns(), mean))
})
# Affichage des resultats de l'optimisation
observeEvent(input$go, {
output$opt1_print <- renderPrint({
opt()
})
})
# Recuperation des poids de ce portefeuille optimise
pf_weights <- reactive({
w <- opt()$pw
names(w) <- colnames(stocks_returns())
w
})
observeEvent(input$go, {
output$opt1_weights <- renderPlot({
barplot(pf_weights())
})
})
# Imposing weigh constraints
max_weights <- reactive({
rep(input$max_w, ncol(stocks_returns()))
})
opt2 <- reactive({
portfolio.optim(apply.monthly(stocks_returns(), mean),
reshigh = max_weights())
})
# Affichage des resultats de l'optimisation
observeEvent(input$go, {
output$opt2_print <- renderPrint({
opt2()
})
})
# Recuperation des poids de ce portefeuille optimise
pf_weights2 <- reactive({
w2 <- opt2()$pw
names(w2) <- colnames(stocks_returns())
w2
})
observeEvent(input$go, {
output$opt2_weights <- renderPlot({
barplot(pf_weights2())
})
})
# Split-sample evaluation
returns_estim <- reactive({
window(apply.monthly(stocks_returns(), mean),
start = input$window_estim[1],
end = input$window_estim[2])
})
returns_eval <- reactive({
window(apply.monthly(stocks_returns(), mean),
start = input$window_eval[1],
end = input$window_eval[2])
})
pf_estim <- reactive({
portfolio.optim(returns_estim())
# On peut aussi imposer une contrainte sur les poids : portfolio.optim(returns_estim(), reshigh = max_weights())
})
pf_eval <- reactive({
portfolio.optim(returns_eval())
})
observeEvent(input$go, {
output$opt3_print <- renderPrint({
pf_estim()
})
})
observeEvent(input$go, {
output$opt4_print <- renderPrint({
pf_eval()
})
})
observeEvent(input$go, {
output$opt3_weights <- renderPlot({
plot(pf_estim()$pw, pf_eval()$pw,
xlab = 'estimation portfolio weights',
ylab = 'evaluation portfolio weights',
main = 'Evaluation portfolio weights VS Estimation portfolio weights')
abline(a = 0, b = 1, lty = 3)
})
})
})
# Run the application
shinyApp(ui = ui, server = server)
Ci-dessous quelques livres qui vous permettront de développer des compétences nécessaires en Data Science :
Statistique et Simulation avec Python : Cours et Exercices corrigés
Broché : 288 pages ISBN-13 : 979-8591390259
La Statistique est présente partout dans notre quotidien. Vous ne pouvez pas y échapper. La Statistique est la fondation de la Data Science.
Ce livre vous donnera beaucoup de plaisir à réaliser des analyses statistiques avec le langage Python. Il n’est pas du tout comme la plupart des livres de Statistique retrouvés sur le marché qui sont remplis de théories et de formules mathématiques tellement complexes que cela ne donne pas envie de les lire. Mon livre à moi est écrit dans un langage très simple et accessible à tout le monde. Nul besoin d’avoir un Master ou un Doctorat en Mathématiques pour comprendre tous les concepts présentés dans ce livre. Chaque notion est présentée sous forme d’activité résolue avec cas pratique. Le code est écrit de manière très simple avec des commentaires. De plus, des exercices sont glissés après chaque concept introduit pour vous aider à pratiquer au fur à mesure ce que vous apprenez. Tous les exercices sont entièrement résolus au dernier chapitre pour vous aider en cas de blocage. Vous pouvez donc utiliser ce livre en toute autonomie pour apprendre la Statistique avec Python.
A travers ce livre, vous apprendrez à :
✅ Calculer des mesures de tendance centrale et des mesures de dispersion afin de décrire les données ;
✅ créer et interpréter des graphiques de visualisation des données en utilisant Python ainsi que les librairies Matplotlib et Seaborn ;
✅ effectuer des analyses multivariées afin d’examiner les relations existant entre plusieurs variables ;
✅ penser de manière probabiliste afin de réaliser des inférences statistiques pour tirer des conclusions à partir d’échantillons de données ;
✅ simuler des données afin d’estimer la probabilité d’un événement ;
✅ rééchantilloner les données à l’aide de techniques comme le Bootstrapping et visualiser les échantillons bootstrap ;
✅ calculer les intervalles de confiance des statistiques récapitulatives d’une population ;
✅ identifier, effectuer et interpréter les tests d’hypothèse appropriés à utiliser pour les ensembles de données ;
✅ appliquer des techniques de modélisation statistique aux données (régression linéaire et régression logistique) ;
✅ interpréter les résultats d’une modélisation statistique et évaluer la qualité des modèles ;
✅ comprendre l’apprentissage automatique ainsi que ses différences avec la modélisation statistique ;- construire et évaluer des modèles de Machine Learning (classification et régression).
Broché : 101 pages ISBN-13 : 979-8664840995
Un livre génial destiné aux personnes désireuses d’apprendre à programmer. Même si vous n’aviez jamais écrit auparavant une seule ligne de code, grâce à sa syntaxe intuitive et très facile à comprendre, Python vous fera entrer dans le monde passionnant de la programmation informatique appliquée à la Science des données (Data Science) qui offre d’immenses opportunités.
Avec plus de 15 ans d’expérience en programmation informatique, je vous guiderai pas à pas à travers mes explications simples, précises et efficaces pour vous permettre d’acquérir les fondamentaux du langage Python. Chaque notion est expliquée par une activité résolue puis il y a un exercice d’application pour vous permettre de pratiquer au fur et à mesure. Tous les exercices d’application sont entièrement corrigés avec les codes complets et les commentaires dans le but de vous aider à apprendre efficacement et en toute autonomie.
A travers ce livre, vous apprendrez à :
✅ configurer votre environnement Python pour un travail efficace ;
✅ écrire du code propre et concis avec Python 3 incluant des structures conditionnelles et des boucles ;
✅ écrire des programmes Python qui interagissent avec les utilisateurs et traite leurs entrées afin de générer les sorties souhaitées ;
✅ automatiser des tâches en écrivant des fonctions ;
✅ utiliser certains outils modernes comme les fonctions lambda, les listes de compréhension, les fonctions map() et filter() ;
✅ stocker l’information dans des structures de données et générer des statistiques ;
✅ effectuer une analyse des données avec des fonctionnalités de Numpy et de Pandas ;
✅ analyser de réels jeux de données.
Broché : 103 pages ISBN-13 : 979-8567677681
Le monde de la Finance en général et le secteur de la Bourse en particulier ont connu une révolution depuis quelques années grâce à l’apport de l’Intelligence Artificielle et à l’utilisation d’outils puissants et performants. Python a été largement adopté aussi bien par les professionnels des marchés boursiers qui l’utilisent dans leurs tâches quotidiennes que par les chercheurs, étudiants ou autres personnes intéressées par la Bourse.
Ce livre est une introduction à l’analyse technique et quantitative avec Python dans le secteur boursier.
A travers ce livre, vous apprendrez à :
✅ Importer automatiquement des données boursières à partir du Web et à les stocker en tant que dataframe ;
✅ Traiter et nettoyer des données financières (Séries Temporelles) ;✅
Créer et analyser des graphiques interactifs avec la librairie Plotly ;✅Calculer les rendements des titres (actions et du marché ;
✅Analyser statistiquement les rendements des actions ;✅
✅ Calculer de diverses manières le Risque d’un investissement financier (Volatilité Standard, VaR, CVaR, Matrice de Covariance, etc.) ;
✅Calculer des rendements ajustés au Risque (Ratio de Sharpe, Ratio de Sortino, etc.) ;✅
Effectuer des simulations Monte-Carlo pour l’estimation du Risque ;
✅Modéliser les facteurs influençant les rendements des actions afin de calculer les paramètres Alpha et Bêta ;
✅Calculer le rendement attendu d’un investissement (Action ou Portefeuille) en utilisant le modèle d’évaluation des actifs financiers (Capital Asset Pricing Model ou CAPM en Anglais) ;
✅Créer et Analyser différents types de Portefeuilles d’Actions ;✅
Générer automatiquement le rapport complet d’analyse de performance d’un portefeuille en utilisant l’outil Pyfolio ;
✅Utiliser la théorie d’Harry Markowitz pour le calcul de Portefeuille optimal ;✅
Générer de milliers de Portefeuilles avec la méthode Monte-Carlo et Sélectionner le Portefeuille à ratio de Sharpe maximum et le Portefeuille à volatilité minimale ;
✅Optimiser un Portefeuille en utilisant l’outil PyPortfolioOpt de la société Quantopian ;✅
Modéliser les cours des actions en vue de la prédiction de futurs prix grâce à de ‘simples techniques’ comme l’estimation par la moyenne, la moyenne mobile, les lissages exponentiels simple, double et triple.Les Chapitres :
✅ CHAPITRE 1 : GENERALITES ET DEFINITIONSDans ce chapitre, je vous explique ce qu’est une série temporelle et pourquoi il est très important de savoir manipuler ce type de données. Ensuite je vous explique quelques notions sur le marché boursier, les tendances en matière d’analyses de données dans ce secteur ainsi que les composantes d’une bonne analyse des données boursières.
✅CHAPITRE 2 : IMPORTATION ET ANALYSE EXPLORATOIRE DES DONNÉESDans ce chapitre, vous apprendrez comment collecter automatiquement de données boursières sur des plateformes comme Yahoo Finance sans quitter un instant votre notebook. Nous ferons le traitement et le nettoyage de ces données pour les mettre dans une forme qui facilitera nos futures analyses. Nous finirons par une analyse exploratoire des données pour mieux les comprendre.
✅CHAPITRE 3 : RENDEMENTS ET RISQUESDans ce chapitre, vous apprendrez des concepts tels les rendements, les risques, le ratio de Sharpe, le ratio de Sortino, CAPM (Capital Asset Price Management), etc. et comment les calculer. Par ailleurs, vous apprendrez à écrire des fonctions afin de mieux structurer votre code.
✅ CHAPITRE 4 : CRÉATION, ANALYSE ET OPTIMISATION D’UN PORTEFEUILLE D’ACTIONS DANS PYTHONIci, Vous apprendrez à créer différents types de portefeuilles. Vous apprendrez aussi comment optimiser un portefeuille en trouvant des pondérations risque-rendement qui sont optimales.
✅ CHAPITRE 5 : MODÈLES SIMPLESIci, vous apprendrez comment modéliser les prix des actions en utilisant l’estimation par la moyenne, les moyennes mobiles et différents types de lissages exponentiels.
Broché : 230 pages ISBN-13 : 979-8671731064
L’apprentissage automatique (Machine Learning en anglais) est un domaine de l’Intelligence artificielle qui se fonde sur des approches mathématiques et statistiques pour donner aux ordinateurs la capacité d’ apprendre à partir de données, c’est-à-dire d’améliorer leurs performances à résoudre des tâches sans être explicitement programmés pour chacune de ces tâches. Plus largement, il concerne la conception, l’analyse, l’optimisation, le développement et l’implémentation de telles méthodes.
Ce livre est purement pratique afin de vous permettre d’acquérir rapidement et efficacement les compétences nécessaires pour créer des systèmes d’apprentissage automatique (Machine Learning) dans son domaine d’intervention. Les projets couvrent plusieurs domaines. Vous apprendrez à modéliser vos données avec des algorithmes de régression, de classification, de clustering, etc. De plus, vous apprendrez à évaluer les performances des modèles créés.
A travers ce livre, vous apprendrez à :
✅ Nettoyer un jeu de données et la rendre prête pour la modélisation (Traitement des valeurs manquantes, Détection et suppression des outliers, Encodage des variables catégorielles, Normalisation des données, etc.) ;
✅ Construire un modèle de classification (LogisticRegression, RandomForestClassifier, DecisionTreeClassifier, KNeighborsClassifier, etc.) et d’un modèle de régression (LinearRegression, RandomForestRegressor, DecisionTreeRegressor, KNeighborsRegressor, etc.) ;
✅ Evaluer la performance d’un modèle (Données d’entraînement et d’évaluation, Choix de la métrique, Validation croisée, Robustesse du modèle, etc.)
✅ effectuer des prédictions ;
✅ modéliser des séries temporelles et effectuer des prévisions ;
✅ rechercher les hyperparamètres optimaux d’un modèle en utilisant les méthodes Grid Search et Random Search ;
✅ automatiser la sélection du meilleur modèle avec l’outil TPOT ;
✅ automatiser le flux de travail de vos projets de Machine Learning ;
✅ effectuer des segmentations avec des algorithmes comme KMeans ;
✅ réduire la dimension de grand ensembles de données en utilisant l’ACP, …etc.
APPRENDRE À PROGRAMMER AVEC R ET RSTUDIO: MANUEL DE COURS ET EXERCICES CORRIGÉS POUR DÉBUTANTS
Broché : 226 pages ISBN-13 : 979-8790793295
R est l’un des langages informatiques les plus utilisés. Plus qu’un langage, R est un environnement intégré et complet pour la conception, la réalisation et la vulgarisation d’un projet concernant l’analyse des données. R peut être utilisé pour des tâches telles que la modélisation statistique, la visualisation des données, l’apprentissage automatique (Machine Learning), l’analyse des séries temporelles, les études économétriques, l’analyse quantitative, le traitement des données textuelles, etc.
A travers ce livre, vous apprendrez à :
✅ nstaller et Configurer votre environnement de travail pour pouvoir écrire du code R ;
✅ écrire votre premier programme (‘Hello World’) et effectuer des opérations basiques (Addition, Soustraction, Multipication, Division, Exponentiel, Modulo, etc.) ;
✅ afficher les résultats d’un code en utilisant de différentes manières les fonctions print(), paste() et cat() ;
✅ créer des variables et à les réutiliser ;
✅ manipuler différents types de données tels que les entiers naturels, les booléens, les chaînes de caractères, les nombres décimaux, les matrices, les vecteurs, les listes, les dataframes, etc.
✅ créer une dataframe et recueillir des informations concernant sa structure et son résumé statistique ;
✅ combiner des booléens, des opérateurs logiques et des opérateurs de comparaison ;
✅ écrire du code propre et concis incluant des structures conditionnelles if, if…else, if…else if…else, des boucles for et while ;
✅ utiliser les fonctions de la famille apply tels que lapply(), sapply() et vapply() ;
✅ créer vos propres fonctions et les optimiser afin d’automatiser certaines tâches et rendre votre code réutilisable ;
✅ créer des listes de compréhension vous permettant d’écrire des boucles for plus ou moins complexes en une seule ligne de code ;
✅ importer différents types de fichiers tels que Excel, CSV, txt, TSV, …;
✅ importer des données provenant du web à partir des API (Application Programing Interface) et du WebScraping ;
✅ manipuler les données à la manière de Tidyverse avec les fonctions filter(), arrange(), mutate(), select(), summarise() et group_by() ;
✅ créer des graphiques tels que les nuages de points (avec droite de régression), les diagrammes à barres, les courbes, les histogrammes, les boîtes à moustache ainsi que des subplots (sous-graphiques) ;
✅ traiter les variables catégorielles en utilisant les fonctionnalités de la librairie forcats ;
✅ effectuer des jointures de tables (jointure interne, à gauche, à droite, complète ainsi qu’une semi-jointure et une anti-jointure) avec la librairie dplyr.
Ce livre est également disponible en version PDF : https://buy.stripe.com/aEU7wu1kW4EG94A6ov
Mes livres sont disponibles en vente sur Amazon aussi en versions papier (broché) et numérique (kindle) : https://www.amazon.fr/Josu%C3%A9-AFOUDA/e/B08F17S1V8/ref=dp_byline_cont_pop_book_1
N’oublier pas lorsque vous acheter un de mes livres de laisser un petit commentaire et aussi 5 étoiles :) sur le site d’achat. Ceci est vraiment encourageant pour continuer cette mission de démocratisation de la connaissance en Science des données. Merci.
1.2 Comment tirer le meilleur parti de ce livre ?
Ce livre est composé de six (06) chapitres. Pour bien comprendre les différentes notions présentées, surtout si vous êtes débutant en développement d’applications web, je vous conseille de parcourir le livre dans l’ordre des chapitres c’est-à-dire du début jusqu’à la fin. Le chapitre 1 présente le contexte de la realization du livre et expose les raisons pour lesquelles vous devez absolument apprendre à developer des applications web en Data Science. A la fin de ce chapitre, vous serez très motive pour poursuivre votre formation dans R Shiny. Les chapitres 2 et 3 constituent la prise en main de Shiny. Il s’agira de comprendre les notions fondamentales (chapitre 2) et avancées (chapitre 3) du développement d’applications web avec R Shiny. A travers ces deux chapitres, vous apprendrez les notions telles que :
✨ la structuration de l’interface utilisateur (panneau latéral, panneau principal, onglets, etc.) ;
✨ les inputs et les outputs ;
✨ les concepts de programmation réactive et de programmation dynamique ;
✨ le déploiement d’une application Shiny.
A la fin de cette première partie, vous maîtriserez toutes les fonctionnalités basiques et avancées de R Shiny pour la construction des 3 applications des projets.
Les chapitres 4, 5 et 6 sont consacrés respectivement aux projets 1 (Construction d’une application web R Shiny pour la création et la visualisation des nuages de mots), 2 (Construction d’une application web R Shiny de Clustering par l’algorithme des K-moyennes et de Réduction de la dimensionnalité) et 3 (Construction d’une application web R Shiny pour la création, l’analyse et l’optimisation de Portefeuille d’actifs financiers). Dans chacun de ces chapitres, vous utiliserez tout ce que vous avez appris dans les chapitres 2 et 3 pour construire 3 applications web R Shiny à forte valeur ajoutée. Chaque projet est constitué :
✨ d’une section présentant le contexte, le scénario et les objectifs ;
✨ d’une ou plusieurs sections présentant le processus à implémenter dans l’application que vous devez créer. Puisqu’il s’agit d’une formation sur Shiny et non sur la programmation avec R, j’ai pris le soin de vous expliquer (code à l’appui) le processus / programme que vous devez transformer en une application web performante. Pour chaque projet je vous explique aussi, dans une vidéo, un exemple du type d’application web que vous devez réaliser.
✨ du code complet de l’application exemple que j’ai moi-même développé. Je vous conseille cependant de réfléchir et d’essayer de concevoir vous-mêmes l’application. Le code proposé en correction du projet pourra être utilisé pour d’éventuels blocages.