diff --git a/.Rprofile b/.Rprofile index 6b0e7e17f..36426274a 100644 --- a/.Rprofile +++ b/.Rprofile @@ -3,7 +3,8 @@ if (file.exists("~/.Rprofile")) { } options(blogdown.new_bundle = TRUE) -options(blogdown.hugo.version = "0.64.1") +options(blogdown.hugo.version = "0.83.0") +options(blogdown.method = 'markdown') reminder_jupyter <- function(file = "./content/getting-started/06_rappels_classes.Rmd", @@ -95,3 +96,6 @@ reminder_box <- function(boxtype = "warning", type = c("html","markdown")){ message("For local preview when the pages are built: blogdown::hugo_build(local = TRUE)") + + + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..924430052 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.toml] +max_line_length = 100 + +[*.md] +trim_trailing_whitespace = false + +[layouts/shortcodes/*.html] +insert_final_newline = false \ No newline at end of file diff --git a/.github/workflows/netlify-test.yaml b/.github/workflows/netlify-test.yaml index 7f9a2593d..2c3d6dc3a 100644 --- a/.github/workflows/netlify-test.yaml +++ b/.github/workflows/netlify-test.yaml @@ -22,9 +22,10 @@ jobs: run: | Rscript -e 'install.packages(c("rmarkdown"))' - name: install hugo - run: Rscript -e 'blogdown::install_hugo()' + run: Rscript -e 'blogdown::install_hugo("0.83.0", force = TRUE)' - name: Install Python run: | + Rscript -e 'print(blogdown:::hugo_version())' Rscript -e "install.packages(c('remotes', 'reticulate'))" Rscript -e "install.packages(c('here'))" - shell: bash -l {0} @@ -34,7 +35,6 @@ jobs: - name: Render blog run: | Rscript -e 'source("./build/build.R")' - Rscript -e 'blogdown::hugo_build(local = TRUE)' - name: Install npm if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} uses: actions/setup-node@v2 diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index 13b7b6401..e09adbb84 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -55,7 +55,7 @@ jobs: run: | Rscript -e 'install.packages(c("rmarkdown"))' - name: install hugo - run: Rscript -e 'blogdown::install_hugo()' + run: Rscript -e 'blogdown::install_hugo("0.83.0")' - name: Install Python run: | Rscript -e "install.packages(c('remotes', 'reticulate'))" @@ -67,7 +67,6 @@ jobs: - name: Render blog run: | Rscript -e 'source("./build/build.R")' - Rscript -e 'blogdown::hugo_build(local = TRUE)' - name: Install npm if: ${{ github.repository == 'linogaliana/python-datascientist' }} uses: actions/setup-node@v2 diff --git a/.gitignore b/.gitignore index 6b025c1a4..68e16adc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,15 @@ # Created by https://www.toptal.com/developers/gitignore/api/pycharm,venv # Edit at https://www.toptal.com/developers/gitignore?templates=pycharm,venv +!themes/github.com/ .idea/ content/**/*.html +content/**/*.png +content/**/*.md +content/**/*.json +content/**/data/* + **/.ipynb_checkpoints/ temp/ @@ -15,9 +21,12 @@ Thumbs.db .matplotlib/ __pycache__/ -content/**/.png +# Hugo +resources/ +jsconfig.json + ### PyCharm ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 diff --git a/.gitmodules b/.gitmodules index 3f7ad8da3..18d5a39f6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "themes/hugo-theme-techdoc"] - path = themes/hugo-theme-techdoc - url = https://github.com/linogaliana/hugo-theme-techdoc.git +[submodule "themes/github.com/wowchemy"] + path = themes/github.com/wowchemy + url = https://github.com/linogaliana/wowchemy-template.git diff --git a/assets/images/.gitkeep b/assets/images/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/assets/images/icon-pack/.gitkeep b/assets/images/icon-pack/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/assets/scss/custom.scss b/assets/scss/custom.scss new file mode 100644 index 000000000..40a540544 --- /dev/null +++ b/assets/scss/custom.scss @@ -0,0 +1,118 @@ +.panel-exercise, +.panel-warning, +.panel-caution, +.panel-danger, +.panel-error, +.panel-hint, +.panel-tip, +.panel-important, +.panel-note, +.panel-attention{ + margin:1.5625emauto; + padding:0 .6rem .8rem!important;overflow:hidden; + page-break-inside:avoid; + /*border-left:.2rem solid #dc3545;*/ + border-radius:.1rem; + box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .05rem rgba(0,0,0,.1); + transition:color .25s,background-color .25s,border-color .25s +} +.panel-warning { + border-left:.2rem solid #dc3545; +} +.panel-caution { + border-left:.2rem solid #fd7e14; +} +.panel-danger { + border-left:.2rem solid #dc3545; +} +.panel-error { + border-left:.2rem solid #dc3545; +} +.panel-hint { + border-left:.2rem solid #ffc107; +} +.panel-tip { + border-left:.2rem solid #ffc107; +} +.panel-important { + border-left:.2rem solid #007bff; +} +.panel-note { + border-left:.2rem solid #007bff; +} +.panel-attention { + border-left:.2rem solid #fd7e14; +} +.panel-exercise { + border-left:.2rem solid #008000; +} + +.panel-header-exercise, +.panel-header-warning, +.panel-header-caution, +.panel-header-danger, +.panel-header-error, +.panel-header-hint, +.panel-header-tip, +.panel-header-important, +.panel-header-note, +.panel-header-attention{ + /*background-color:#fdf3f2;*/ + position:relative; + margin:0 -.6rem!important; + padding:.4rem .6rem .4rem 2rem; + font-weight:700; +} + + +.panel-body-exercise, +.panel-body-warning, +.panel-body-caution, +.panel-body-danger, +.panel-body-error, +.panel-body-hint, +.panel-body-tip, +.panel-body-important, +.panel-body-note, +.panel-body-attention{ + padding: 20px 0px; +} + +.panel-header-exercise{ + background-color:#98fb98 +} +.panel-header-warning{ + background-color:#dc3545 +} +.panel-header-caution{ + background-color:#fd7e14 +} +.panel-header-error{ + background-color:#dc3545 +} +.panel-header-hint{ + background-color:#fff6dd +} +.panel-header-tip{ + background-color:#fff6dd +} +.panel-header-important{ + background-color:#e7f2fa +} +.panel-header-note{ + background-color:#e7f2fa +} +.panel-header-attention{ + background-color:#ffedcc +} +.panel-header-danger{ + background-color:#fdf3f2 +} + +.panel h3{ + margin-top: 0rem; +} + +a img{ + display: inline; +} \ No newline at end of file diff --git a/build/build.R b/build/build.R index 516b69b43..fa72db12a 100644 --- a/build/build.R +++ b/build/build.R @@ -1,24 +1,66 @@ +content_rmd <- list.files("./content", recursive = TRUE, pattern = "*.Rmd", full.names = TRUE) file.remove( gsub( - ".Rmd",".html", list.files("./content", recursive = TRUE, pattern = "*.Rmd", full.names = TRUE) + ".Rmd",".html", content_rmd ) ) lapply( - list.files("./content", recursive = TRUE, pattern = "*.Rmd", full.names = TRUE), function(i){ + content_rmd, function(i){ print(sprintf("Rendering %s", i)) - rmarkdown::render(i, envir = new.env()) + knitr::knit(i, envir = new.env(), output = gsub(".Rmd", ".md", i)) }) file.remove( gsub( - ".Rmd",".html", list.files("./content", recursive = TRUE, pattern = "*.Rmd", full.names = TRUE) + ".Rmd",".html", content_rmd ) ) + + + +Sys.setenv(HUGO_IGNOREERRORS = "error-remote-getjson", + HUGO_BASEURL = "/", + #HUGO_BASEURL = "https://linogaliana-teaching.netlify.app/", + HUGO_RELATIVEURLS = "false", + BLOGDOWN_POST_RELREF = "true", + BLOGDOWN_SERVING_DIR = here::here()) + +cmd = blogdown:::find_hugo() +cmd_args = c("--themesDir themes", "-t github.com")#, "--gc")#, "--minify") +system2(cmd, cmd_args) + + +#blogdown::stop_server() + + +# Sys.setenv(HUGO_RELATIVEURLS = "true", +# BLOGDOWN_POST_RELREF = "true") + +# cmd = blogdown:::find_hugo() + +#blogdown:::create_shortcode('postref.html', 'blogdown/postref', TRUE) + +# cmd_args = c("--themesDir themes", "-t github.com")#, "--gc")#, "--minify") +# system2(cmd, cmd_args) + +#blogdowntest::serve_site() + # file.remove( # gsub( # ".Rmd",".md", list.files("./content", recursive = TRUE, pattern = "*.Rmd", full.names = TRUE) # ) # ) + +# file.remove( +# gsub( +# ".Rmd",".ipynb", list.files("./content", recursive = TRUE, pattern = "*.Rmd", full.names = TRUE) +# ) +# ) + + + + + diff --git a/config.toml b/config.toml index 75e4265c9..08d7afd86 100644 --- a/config.toml +++ b/config.toml @@ -1,89 +1,105 @@ -baseurl = "https://linogaliana-teaching.netlify.app/" -DefaultContentLanguage = "fr" -languageCode = "fr-fr" -title = "Python pour un data scientist/economist" -theme="hugo-theme-techdoc" +# Configuration of Hugo +# Guide: https://wowchemy.com/docs/get-started/ +# Hugo Documentation: https://gohugo.io/getting-started/configuration/#all-configuration-settings +# +# This file is formatted using TOML syntax - learn more at https://learnxinyminutes.com/docs/toml/ +# Each configuration section is defined by a name in square brackets (e.g. `[outputs]`). + +# Title of your site +title = "Python pour les data scientists et économistes" + +# The URL of your site. +# End your URL with a `/` trailing slash, e.g. `https://example.com/`. +# baseurl = "https://linogaliana-teaching.netlify.app/" +baseurl = "/" + +# Enter a copyright notice to display in the site footer. +# To display a copyright symbol, type `©`. For current year, type `{year}`. +copyright = "© Lino Galiana" + +############################ +## Advanced options below ## +############################ + +# Get last modified date for content from Git? enableGitInfo = true +# from techdoc: enableInlineShortcodes = true + +# Default language to use (if you setup multilingual support) +defaultContentLanguage = "en" +# from techdoc: languageCode = "fr-fr" +hasCJKLanguage = false # Set `true` for Chinese/Japanese/Korean languages. +defaultContentLanguageInSubdir = false +removePathAccents = true # Workaround for https://github.com/gohugoio/hugo/issues/5687 + +summaryLength = 30 # Listing summary length in words. Also, see `abstract_length` in `params.toml`. +paginate = 10 # Number of items per page in paginated lists. enableEmoji = true -enableInlineShortcodes = true - -ignoreFiles = ["\\.Rmd$", "\\.Rmarkdown$", "_cache$", "\\.knit\\.md$", "\\.utf8\\.md$", "\\.py"]#"index\\.html"] +enableRobotsTXT = true +footnotereturnlinkcontents = "^" +ignoreFiles = ["\\.ipynb$", ".ipynb_checkpoints$", "\\.Rmd$", "\\.Rmarkdown$","\\.R$" ,"_cache$", "\\.knit\\.md$", "\\.utf8\\.md$", "\\.py$","\\.csv$"] +disableAliases = true # Disable aliases when `redirects` is added to the `outputs` below. -disableToc = false +[permalinks] + # Workaround Hugo publishing taxonomy URLs as plurals - consistently use singular across Academic. + authors = "/author/:slug/" + tags = "/tag/:slug/" + categories = "/category/:slug/" + course = "/:slug/" -[markup.goldmark.renderer] -unsafe= true +[outputs] + home = ["HTML", "RSS", "JSON", "WebAppManifest", "headers", "redirects"] + section = ["HTML", "RSS"] +# Configure the Markdown renderer. [markup] + defaultMarkdownHandler = "goldmark" + [markup.goldmark] + [markup.goldmark.renderer] + unsafe = true # Enable user to embed HTML snippets in Markdown content. + [markup.highlight] + codeFences = false # Disable Hugo's code highlighter as it conflicts with Academic's highligher. [markup.tableOfContents] - endLevel = 2 - ordered = false startLevel = 1 + endLevel = 2 + +[imaging] + resampleFilter = "lanczos" + quality = 75 + anchor = "smart" # Anchor for cropping. Options include Smart and Center. + +# Taxonomies. +[taxonomies] + tag = "tags" + category = "categories" + publication_type = "publication_types" + author = "authors" + +# Related content. +[related] + threshold = 80.0 + includeNewer = true + toLower = true + + [[related.indices]] + name = "title" + weight = 60.0 + + [[related.indices]] + name = "summary" + weight = 50.0 + + [[related.indices]] + name = "tags" + weight = 80.0 + + [[related.indices]] + name = "categories" + weight = 70.0 -# Global menu section -# See https://gohugo.io/content-management/menus/ -[menu] - [[menu.main]] - name = "Home" - url = "/" - weight = 1 - - [[menu.main]] - name = "Manipuler des données" - url = "/manipulation" - weight = 2 - - [[menu.main]] - name = "Visualiser des données" - url = "/visualisation" - weight = 3 - - [[menu.main]] - name = "Modéliser" - url = "/modelisation" - weight = 4 - - [[menu.main]] - name = "NLP" - url = "/NLP" - weight = 5 - - [[menu.main]] - name = "Git" - url = "/git" - weight = 6 - - - [[menu.main]] - name = "Evaluation" - url = "/evaluation" - weight = 7 - - [[menu.main]] - name = "Travaux dirigés" - url = "/listeTP" - weight = 8 - - [[menu.main]] - name = "References" - url = "/references" - weight = 9 - - [[menu.main]] - name = "Github" - url = "https://github.com/linogaliana/python-datascientist" - weight = 10 - -[params] - # Source Code repository section - description = "Lino Galiana" - github_repository = "https://github.com/linogaliana/python-datascientist" - # version = "0.9.2" - - # Documentation repository section - # documentation repository (set edit link to documentation repository) - github_doc_repository = "https://github.com/linogaliana/python-datascientist" - - # Documentation Menu section - # Menu style settings - menu_style = "slide-menu" # "open-menu" or "slide-menu" \ No newline at end of file +# Install Wowchemy +[module] + [[module.imports]] + path = "github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms" + [[module.imports]] + path = "github.com/wowchemy/wowchemy-hugo-modules/wowchemy" diff --git a/config/_default/languages.toml b/config/_default/languages.toml new file mode 100644 index 000000000..f7c6da684 --- /dev/null +++ b/config/_default/languages.toml @@ -0,0 +1,20 @@ +# Languages +# Create a `[X]` block for each language you want, where X is the language ID. +# Refer to https://sourcethemes.com/academic/docs/language/ + +# Configure the English version of the site. +[en] + languageCode = "en-us" + # contentDir = "content/en" # Uncomment for multi-lingual sites, and move English content into `en` sub-folder. + +# Uncomment the lines below to configure your website in a second language. +#[zh] +# languageCode = "zh-Hans" +# contentDir = "content/zh" +# title = "Chinese website title..." +# [zh.params] +# description = "Site description in Chinese..." +# [[zh.menu.main]] +# name = "Wo" +# url = "#about" +# weight = 1 diff --git a/config/_default/menus.toml b/config/_default/menus.toml new file mode 100644 index 000000000..9b6316d67 --- /dev/null +++ b/config/_default/menus.toml @@ -0,0 +1,70 @@ +# Navigation Links +# To link a homepage widget, specify the URL as a hash `#` followed by the filename of the +# desired widget in your `content/home/` folder. +# The weight parameter defines the order that the links will appear in. + + +#[[main]] +# name = "Home" +# url = "/" +# weight = 1 + + + +[[main]] + name = "Documentation" + url = "course/" + weight = 11 + +[[main]] + name = "Introduction" + url = "/course/getting-started" + weight = 20 + +[[main]] + name = "Manipuler des données" + url = "/course/manipulation" + weight = 30 + +[[main]] + name = "Visualiser des données" + url = "/course/visualisation" + weight = 40 + +[[main]] + name = "Modéliser" + url = "/course/modelisation" + weight = 50 + +[[main]] + name = "NLP" + url = "/course/NLP" + weight = 60 + +[[main]] + name = "Git" + url = "/course/git" + weight = 70 + + +[[main]] + name = "Evaluation" + url = "/course/evaluation" + weight = 80 + +[[main]] + name = "Travaux dirigés" + url = "/course/listeTP" + weight = 90 + +[[main]] + name = "References" + url = "/course/references" + weight = 100 + +[[main]] + name = "Github" + url = "https://github.com/linogaliana/python-datascientist" + weight = 10 +# icon = "fa-github" +# icon_pack = "fab" \ No newline at end of file diff --git a/config/_default/params.toml b/config/_default/params.toml new file mode 100644 index 000000000..2d60e8636 --- /dev/null +++ b/config/_default/params.toml @@ -0,0 +1,196 @@ +# SITE SETUP +# Guide: https://wowchemy.com/docs/get-started/ +# Documentation: https://wowchemy.com/docs/ +# +# This file is formatted using TOML syntax - learn more at https://learnxinyminutes.com/docs/toml/ +# Each config section after this section is defined by a name in square brackets (e.g. `[search]`). + +############################ +## Theme +############################ + +# Choose a theme. +# Guide to color themes: https://wowchemy.com/docs/customization/#color-themes +# Browse the latest built-in font sets at https://github.com/wowchemy/wowchemy-hugo-modules/tree/master/wowchemy/themes/ +# Browse user installed themes in `data/themes/` +theme = "minimal" + +# Enable users to switch between day and night mode? +day_night = true + +# Override the theme's font set (optional). +# Guide to font sets: https://wowchemy.com/docs/customization/#fonts +# Browse the latest built-in font sets at https://github.com/wowchemy/wowchemy-hugo-modules/tree/master/wowchemy/data/fonts +# Browse user installed font sets in `data/fonts/` +font = "" + +# Choose a font size. +# Sizes: XS (extra small), S (small), M (medium), L (large - DEFAULT), XL (extra large) +font_size = "L" + +############################ +## Basic Info +############################ + +# Website type +# Improve how search engines understand your site. +# For personal sites, choose "Person". +# For organizations and projects, choose from https://schema.org/Organization#subtypes +# E.g. Person, Organization, LocalBusiness, Project, EducationalOrganization +site_type = "Project" + +# Local business type (optional) +# If you entered "LocalBusiness" above, choose the type of business from https://schema.org/LocalBusiness#subtypes +local_business_type = "" + +# Organization name (optional) +# Enter an organization or project name. Defaults to the site title from `config.toml`. +org_name = "" + +# Description for social sharing and search engines. If undefined, superuser role is used in place. +description = "Python pour les data scientists et économistes - Lino Galiana - Cours ENSAE 2e année (M1)" + +############################ +## Site Features +############################ + +# Enable source code highlighting? true/false +# Documentation: https://wowchemy.com/docs/writing-markdown-latex/#highlighting-options +highlight = true +highlight_languages = ["python","r"] # Add support for highlighting additional languages +highlight_style = "github" # For supported styles, see https://cdnjs.com/libraries/highlight.js/ + +# Enable LaTeX math rendering? true/false +# If false, you can enable math on a per page basis as needed. +math = true + +# Enable diagram rendering? true/false +# If false, you can enable diagrams on a per page basis as needed. +diagram = false + +# Privacy pack +# Show a cookie consent message to visitors +# Anonymize IP in Google Analytics (if enabled) +privacy_pack = false + +# Enable visitors to edit pages? +# `repo` defines the repository URL. `editable` defines which page types can be edited. +edit_page = {repo_url = "https://github.com/linogaliana/python-datascientist", content_dir = "content", repo_branch = "master", editable = {book = false}} + +# Show related content at the bottom of pages? +show_related = {book = true} + +############################ +## Social +############################ + +# Default image for social sharing and search engines. Place image in `static/media/` folder and specify image name here. +sharing_image = "" + +# Twitter username (without @). Used when a visitor shares your site on Twitter. +twitter = "linogaliana" + +############################ +## Regional Settings +############################ + +# Date and time format (refer to https://wowchemy.com/docs/customization/#date-format ) +# Examples: "Mon, Jan 2, 2006" or "2006-01-02" +date_format = "Jan 2, 2006" +# Examples: "3:04 pm" or "15:04" +time_format = "3:04 PM" + +############################ +## Advanced +############################ + +# Main menu alignment (l = left, c = center, r = right) and logo options. +main_menu = {enable = true, align = "l", show_logo = true, highlight_active_link = true, show_language = false, show_day_night = true, show_search = true} + +# Show estimated reading time for posts? (true/false) +reading_time = true + +# Display next/previous section pager? (true/false) +section_pager = true +docs_section_pager = true # Display pager in Docs layout (e.g. tutorials)? + +# Enable in-built social sharing buttons? (true/false) +sharing = true + +# Show a copyright license from creativecommons.org in the site footer? +# Page specific copyright licenses are also possible by adding this option to a page's front matter. +copyright_license = {enable = true, allow_derivatives = false, share_alike = true, allow_commercial = false, notice = "This work is licensed under Creative Commons Attribution-NonCommercial 4.0 International License"} + +# Abstract length (characters) in the Compact and Portfolio Card list views. Also, see `summaryLength` in `config.toml`. +abstract_length = 135 + +# Load JS plugins +# E.g. To load `/assets/js/custom.js`, set `plugins_js = ["custom"]`. +plugins_js = [] + +# Breadcrumb navigation +[breadcrumb] + page_types = {book = true} + +############################ +## Comments +############################ +[comments] + # Comment provider: + # "": Disabled + # "disqus": Disqus (https://disqus.com) + # "commento": Commento (https://commento.io) + provider = "" + + # Which page types are commentable? + commentable = {book = true} + + # Configuration of Disqus. + [comments.disqus] + shortname = "" # Paste the shortname from your Disqus dashboard. + show_count = true # Show comment count in page header? (true/false) + + # Configuration of Commento. + [comments.commento] + # If self-hosting Commento, enter its URL here (e.g. "https://commento.?.com"), otherwise leave empty. + url = "" + +############################ +## Search +############################ +[search] + # Search provider: + # "": No search engine + # "wowchemy": Built-in search engine + # "algolia": Algolia (https://www.algolia.com) + provider = "wowchemy" + + # Configuration of Algolia search engine. + # Paste the values from your Algolia dashboard. + [search.algolia] + app_id = "" + api_key = "" + index_name = "" + show_logo = false + +############################ +## Marketing +############################ +[marketing] + google_analytics = "" + google_tag_manager = "" + google_site_verification = "" + +############################ +## Content Management System +############################ +[cms] + branch = "master" + local_backend = false + +############################ +## Icon Pack Extensions +############################ +[icon.pack] + ai = true # Academicons icon pack https://jpswalsh.github.io/academicons/ + diff --git a/content/NLP/01_intro/index.Rmd b/content/course/NLP/01_intro.Rmd similarity index 93% rename from content/NLP/01_intro/index.Rmd rename to content/course/NLP/01_intro.Rmd index 5273f3127..5798cbcf3 100644 --- a/content/NLP/01_intro/index.Rmd +++ b/content/course/NLP/01_intro.Rmd @@ -14,19 +14,29 @@ title: "Quelques éléments pour comprendre les enjeux" date: 2020-10-15T13:00:00Z draft: false weight: 10 -output: - html_document: - keep_md: true - self_contained: true slug: nlpintro +type: book +tags: + - NLP + - nltk + - Littérature + - preprocessing +categories: + - Tutoriel +summary: | + Le NLP est un immense domaine de recherche. Ce chapitre va + explorer quelques méthodes classiques en s'appuyant + sur le Comte de Monte Cristo. --- ```{r setup, include=FALSE} +dir_path <- gsub(here::here(), "..", here::here("course","NLP")) + library(knitr) library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) knitr::opts_chunk$set(fig.path = "") -knitr::opts_chunk$set(eval = TRUE, echo = TRUE, warning = FALSE, message = FALSE) +knitr::opts_chunk$set(eval = TRUE, echo = FALSE, warning = FALSE, message = FALSE) # Hook from Maelle Salmon: https://ropensci.org/technotes/2020/04/23/rmd-learnings/ knitr::knit_hooks$set( @@ -35,7 +45,7 @@ knitr::knit_hooks$set( paste0( "{", "{
}} \ No newline at end of file diff --git a/content/_index.md b/content/course/_index.md similarity index 80% rename from content/_index.md rename to content/course/_index.md index a7b844b63..d9316abe2 100644 --- a/content/_index.md +++ b/content/course/_index.md @@ -1,21 +1,12 @@ --- -title: "Homepage" -date: 2020-07-16T12:00:00Z -draft: false -weight: 10 +title: Python pour les data scientists et économistes +type: book # Do not modify. +toc: true +# Title for the menu link if you wish to use a shorter link title, otherwise remove this option. +linktitle: Homepage --- -## Structuration du site - -Ce site web rend public le contenu du cours de -deuxième année (Master 1) de l'ENSAE: -[*Python pour les data-scientists et économistes*](https://www.ensae.fr/courses/python-pour-le-data-scientist-pour-leconomiste/) -:snake:. - -Le cours est structuré sous la forme du présent site web et de notebooks -jupyter proposant des exercices plus approfondis. L'ensemble -des codes sources est stocké sous -[github à cette adresse](https://github.com/linogaliana/python-datascientist). +## Architecture du site web Sur l'ensemble du site web, il est possible de cliquer sur la petite icone @@ -58,4 +49,6 @@ avec les hypothèses d'un modèle. Les éléments relatifs à l'évaluation du cours sont disponibles dans la Section [Evaluation](evaluation) +## Contenu général +{{< list_children >}} diff --git a/content/evaluation/_index.md b/content/course/evaluation/_index.md similarity index 97% rename from content/evaluation/_index.md rename to content/course/evaluation/_index.md index 0d97139b8..31ea542d0 100644 --- a/content/evaluation/_index.md +++ b/content/course/evaluation/_index.md @@ -4,6 +4,12 @@ date: 2020-09-07T13:00:00Z draft: false weight: 90 slug: evaluation +icon: user-graduate +icon_pack: fas +#linktitle: "Partie 4: Natural Language Processing (NLP)" +summary: | + Résumé des attentes pour les projets de fin d'année +type: book --- Résumé : diff --git a/content/getting-started/.Rprofile b/content/course/getting-started/.Rprofile similarity index 100% rename from content/getting-started/.Rprofile rename to content/course/getting-started/.Rprofile diff --git a/content/getting-started/01_installation.md b/content/course/getting-started/01_installation.md similarity index 99% rename from content/getting-started/01_installation.md rename to content/course/getting-started/01_installation.md index bf2a54fac..e5c0ce373 100644 --- a/content/getting-started/01_installation.md +++ b/content/course/getting-started/01_installation.md @@ -4,6 +4,9 @@ date: 2020-07-16T13:00:00Z draft: false weight: 20 slug: "configuration" +type: book +summary: | + Quelques conseils pour avoir un environnement Python fonctionnel. --- Les exercices sont présentés sous la diff --git a/content/getting-started/02_DS_environment.md b/content/course/getting-started/02_DS_environment.md similarity index 99% rename from content/getting-started/02_DS_environment.md rename to content/course/getting-started/02_DS_environment.md index 953cd7bf9..d1639032b 100644 --- a/content/getting-started/02_DS_environment.md +++ b/content/course/getting-started/02_DS_environment.md @@ -4,6 +4,9 @@ date: 2020-07-22T12:00:00Z draft: false weight: 30 slug: "ecosystemeDS" +type: book +summary: | + Tour d'horizon de l'éco-système python de la *data science* --- ## Les packages python essentiels pour le cours et la vie d'un ENSAE diff --git a/content/getting-started/03_python_practice.md b/content/course/getting-started/03_python_practice.md similarity index 99% rename from content/getting-started/03_python_practice.md rename to content/course/getting-started/03_python_practice.md index d15455176..e5aef8622 100644 --- a/content/getting-started/03_python_practice.md +++ b/content/course/getting-started/03_python_practice.md @@ -4,6 +4,9 @@ date: 2020-07-22T12:00:00Z draft: false weight: 40 slug: bonnespratiques +type: book +summary: | + Un guide des bonnes pratiques pour Python --- Une référence utile à lire est le diff --git a/content/getting-started/04_rappels_types.Rmd b/content/course/getting-started/04_rappels_types.Rmd similarity index 99% rename from content/getting-started/04_rappels_types.Rmd rename to content/course/getting-started/04_rappels_types.Rmd index 9fcf15ace..5f510937f 100644 --- a/content/getting-started/04_rappels_types.Rmd +++ b/content/course/getting-started/04_rappels_types.Rmd @@ -14,11 +14,11 @@ title: "Rappel de ce que vous savez déjà mais avez peut-être oublié" date: 2020-07-09T15:00:00Z draft: false weight: 50 -output: - html_document: - keep_md: true - self_contained: true slug: "rappels2A" +type: book +summary: | + Rappels d'éléments essentiels en Python: les règles syntaxes, les classes, + les méthodes, etc. --- [pandas](http://pandas.pydata.org/) et [numpy](http://www.numpy.org/) sont diff --git a/content/getting-started/05_rappels_fonctions.Rmd b/content/course/getting-started/05_rappels_fonctions.Rmd similarity index 99% rename from content/getting-started/05_rappels_fonctions.Rmd rename to content/course/getting-started/05_rappels_fonctions.Rmd index 3c63fcf7e..3914cc614 100644 --- a/content/getting-started/05_rappels_fonctions.Rmd +++ b/content/course/getting-started/05_rappels_fonctions.Rmd @@ -14,11 +14,10 @@ title: "Modules, tests, boucles, fonctions" date: 2020-07-09T15:00:00Z draft: false weight: 60 -output: - html_document: - keep_md: true - self_contained: true slug: rappelsfonctions +type: book +summary: | + Rappel de principes de bases pour les fonctions --- Les modules sont les éléments qui font la richesse du langage Python. diff --git a/content/getting-started/06_rappels_classes.Rmd b/content/course/getting-started/06_rappels_classes.Rmd similarity index 99% rename from content/getting-started/06_rappels_classes.Rmd rename to content/course/getting-started/06_rappels_classes.Rmd index 0d34e4d47..df7445957 100644 --- a/content/getting-started/06_rappels_classes.Rmd +++ b/content/course/getting-started/06_rappels_classes.Rmd @@ -14,11 +14,10 @@ title: "Les classes en Python" date: 2020-07-09T15:00:00Z draft: false weight: 70 -output: - html_document: - keep_md: true - self_contained: true slug: "rappelsclasses" +type: book +summary: | + Rappels sur la programmation orientée objet en Python --- **Ce TP est optionnel** diff --git a/content/getting-started/07_ci_python.md b/content/course/getting-started/07_ci_python.md similarity index 100% rename from content/getting-started/07_ci_python.md rename to content/course/getting-started/07_ci_python.md diff --git a/content/getting-started/_index.md b/content/course/getting-started/_index.md similarity index 72% rename from content/getting-started/_index.md rename to content/course/getting-started/_index.md index d7b8cccf9..77317385b 100644 --- a/content/getting-started/_index.md +++ b/content/course/getting-started/_index.md @@ -1,7 +1,16 @@ --- -title: "Introduction" -date: 2020-07-16T13:00:00Z -draft: false +date: "2018-09-09T00:00:00Z" +icon: python +icon_pack: fab +linktitle: "Introduction: quelques rappels" +summary: | + Cette introduction propose quelques éléments de + révision des concepts de base en Python et + présente l'écosystème Python que nous allons + découvrir tout au long de ce cours +title: Introduction +slug: introduction +type: book weight: 10 --- @@ -9,24 +18,6 @@ Avant de plonger dans les arcanes de la *data science*, cette partie d'introduction propose des éléments de configuration et des révisions pour mettre le pied à l'étrier. -En premier lieu, des notions générales sur lesquelles il ne fait pas de mal -de revenir de temps en temps: - -* [Les éléments de configuration](configuration) pour avoir un environnement -propice à l'utilisation de l'écosystème python -* [Une présentation de l'écosystème de la data-science](ecosystemeDS) dont -on explorera de nombreux aspects dans ce cours -* [Les règles de bonnes pratiques](bonnespratiques) pour améliorer la qualité -d'un travail s'appuyant sur `python` - -Ensuite, des rappels sur les objets structurants le langage `python`, -nécessaires pour être autonome en `python` - -* [Des rappels généraux sur les objets en python](rappels2A) -* [Des rappels sur les fonctions en python](rappelsfonctions) -* [Un TD (optionnel) sur les classes en python](rappelsclasses) - - Les notebooks d'exercices sont listés [ici](listetp), visualisables via @@ -87,16 +78,6 @@ présentera ainsi régulièrement des analogies avec `R`. ## Structuration de cette partie -Dans un premier temps, cette introduction présente un panorama général -de l'environnement familier du *data scientist* en `Python`: - -* [Configurer Python](configuration) -* [Rapide inventaire de l'écosystème de la *data science*](ecosystemeDS) -* [Présentation des bonnes pratiques pour les projets de *data science* en `Python`](bonnespratiques) +{{< list_children >}} -Ensuite, cette partie propose quelques rappels généraux sur les concepts de base -du langage: -* [Rappels sur les objets du langage de base](rappels2A) -* [Rappels sur la programmation de fonctions](rappelsfonctions) -* [Rappels sur les notions de classes, méthodes, etc.](rappelsclasses) diff --git a/content/course/git/_index.md b/content/course/git/_index.md new file mode 100644 index 000000000..2670fc0a9 --- /dev/null +++ b/content/course/git/_index.md @@ -0,0 +1,23 @@ +--- +title: "Git: un élément essentiel au quotidien" +date: 2020-07-16T13:00:00Z +draft: false +weight: 70 +slug: git +icon: git-alt +icon_pack: fab +#linktitle: "Partie 4: Natural Language Processing (NLP)" +summary: | + Une partie annexe au cours pour découvrir Git, un langage + devenu indispensable pour les data-scientists et économistes + pour stocker et partager des projets Python. +type: book +--- + +Cette partie du site présente un élément qui n'est pas propre à +`Python` mais qui est néanmoins indispensable: la pratique de `Git` + +TO DO + + +{{< list_children >}} diff --git a/content/git/exogit/index.Rmd b/content/course/git/exogit.Rmd similarity index 99% rename from content/git/exogit/index.Rmd rename to content/course/git/exogit.Rmd index c8c6414b5..082781a1b 100644 --- a/content/git/exogit/index.Rmd +++ b/content/course/git/exogit.Rmd @@ -3,11 +3,14 @@ title: "Un cadavre exquis pour découvrir Git" date: 2020-09-30T13:00:00Z draft: false weight: 20 -output: - html_document: - keep_md: true - self_contained: true slug: exogit +tags: + - Git +categories: + - Exercice +type: book +summary: | + Mise en pratique des concepts du langage Git --- @@ -35,11 +42,6 @@ library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) ``` -```{python, eval = FALSE, include = FALSE} -import os -os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = 'C:/Users/W3CRK9/AppData/Local/r-miniconda/envs/r-reticulate/Library/plugins/platforms' -``` - Il est recommandé de régulièrement se référer à la [cheatsheet numpy](https://www.datacamp.com/community/blog/python-numpy-cheat-sheet) et à la diff --git a/content/manipulation/02a_pandas_tutorial/index.Rmd b/content/course/manipulation/02a_pandas_tutorial.Rmd similarity index 94% rename from content/manipulation/02a_pandas_tutorial/index.Rmd rename to content/course/manipulation/02a_pandas_tutorial.Rmd index e50226da3..70a427aef 100644 --- a/content/manipulation/02a_pandas_tutorial/index.Rmd +++ b/content/course/manipulation/02a_pandas_tutorial.Rmd @@ -15,11 +15,22 @@ title: "Introduction à pandas" date: 2020-07-28T13:00:00Z draft: false weight: 20 -output: - html_document: - keep_md: true - self_contained: true +tags: + - pandas + - pollution + - Ademe +categories: + - Tutoriel slug: pandas +type: book +summary: | + pandas est l'élément central de l'écosystème Python pour la data-science. + Le succès de Python tient beaucoup à pandas qui a permis d'importer la + logique SQL dans le langage Python. pandas embarque énormément de + fonctionalités qui permettent d'avoir des pipelines efficaces pour + traiter des données de volumétrie moyenne (jusqu'à quelques Gigas). Au-delà + de cette volumétrie, il faudra se tourner vers d'autres solutions + (PostgresQL, Dask, Spark...). --- Pour visualiser le [TP associé à ce tutoriel](pandasTP) : @@ -30,19 +41,37 @@ Pour visualiser le [TP associé à ce tutoriel](pandasTP) : [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/linogaliana/python-datascientist/master?filepath=content/manipulation/notebooks/02_pandas_tp.ipynb) [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](http://colab.research.google.com/github/linogaliana/python-datascientist/blob/master/content/manipulation/notebooks/02_pandas_tp.ipynb) -```{r setup, include=FALSE} +```{r setup, include=FALSE} +dir_path <- gsub(here::here(), "..", here::here("course","manipulation")) + library(knitr) library(reticulate) -knitr::knit_engines$set(python = reticulate::eng_python) -``` +knitr::knit_engines$set(python = reticulate::eng_python) +knitr::opts_chunk$set(fig.path = "") +knitr::opts_chunk$set(eval = TRUE, warning = FALSE, message = FALSE) + +# Hook from Maelle Salmon: https://ropensci.org/technotes/2020/04/23/rmd-learnings/ +knitr::knit_hooks$set( + plot = function(x, options) { + hugoopts <- options$hugoopts + paste0( + "{", "{
}}\n" + ) + } +) -```{python, eval = FALSE, include = FALSE} -import os -os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = 'C:/Users/W3CRK9/AppData/Local/r-miniconda/envs/r-reticulate/Library/plugins/platforms' ``` - Dans ce tutoriel `pandas`, nous allons utiliser: * Les émissions de gaz à effet de serre estimées au niveau communal par l'ADEME. Le jeu de données est @@ -364,13 +393,13 @@ Cette méthode propose de nombreuses options ([ou depuis github](https://github.com/linogaliana/python-datascientist/blob/master/content/01_data/02_pandas_tp.ipynb)) -^[2]: Il est préférable d'utiliser la fonction `display` (ou tout simplement +[^2]: Il est préférable d'utiliser la fonction `display` (ou tout simplement taper le nom du DataFrame qu'utiliser la fonction `print`). Le `display` des objets `pandas` est assez esthétique, contrairement à `print` qui renvoie du texte brut. -{{< panel status="danger" title="warning" icon="fa fa-exclamation-triangle" >}} +{{% panel status="danger" title="warning" icon="fa fa-exclamation-triangle" %}} Il faut faire attention au `display` et aux commandes qui révèlent des données (`head`, `tail`, etc.) dans un notebook ou un markdown qui exploite @@ -384,7 +413,7 @@ Techniquement, il est possible d'appliquer des filtres avec `git` (voir [ici](http://timstaley.co.uk/posts/making-git-and-jupyter-notebooks-play-nice/)) mais c'est une démarche très complexe -{{< /panel >}} +{{% /panel %}} On pourra alors préférer convertir systématiquement les `.ipynb` en `.py` grâce à `jupytext` (`jupytext --to py nom_du_notebook.ipynb`) et mettre l'extension `*.ipynb` @@ -514,13 +543,35 @@ complexes de maniement de données. En effet, on peut appliquer la méthode `plot()` directement à une `pandas.Series`: -```{python matplotlib} +```{python matplotlib-example, echo = TRUE, eval = FALSE} +df['Déchets'].plot() +df['Déchets'].hist() +df['Déchets'].plot(kind = 'hist', logy = True) +``` + + +```{python matplotlib, include = FALSE} +plt.figure() fig = df['Déchets'].plot() -plt.show() +fig +plt.savefig('plot_base.png', bbox_inches='tight') + +plt.figure() fig = df['Déchets'].hist() -plt.show() +fig +plt.savefig('plot_hist.png', bbox_inches='tight') + +plt.figure() fig = df['Déchets'].plot(kind = 'hist', logy = True) -plt.show() +fig +#plt.show() +plt.savefig('plot_hist_log.png', bbox_inches='tight') +``` + +```{r} +knitr::include_graphics("plot_base.png") +knitr::include_graphics("plot_hist.png") +knitr::include_graphics("plot_hist_log.png") ``` La sortie est un objet `matplotlib`. La *customisation* de ces @@ -589,7 +640,7 @@ data.loc[(data.age >= 12), ['section']] # Principales manipulation de données -L'objectif du [TP pandas](pandasTP) est de se familiariser plus avec ces +L'objectif du [TP pandas](#pandasTP) est de se familiariser plus avec ces commandes à travers l'exemple des données des émissions de C02. Les opérations les plus fréquentes en SQL sont résumées par le tableau suivant. @@ -615,7 +666,7 @@ des opérations. L'opération la plus classique consiste à ajouter ou retirer des variables à la table de données. -{{< panel status="danger" title="warning" icon="fa fa-exclamation-triangle" >}} +{{% panel status="danger" title="warning" icon="fa fa-exclamation-triangle" %}} Attention au comportement de `pandas` lorsqu'on crée une duplication d'un DataFrame. Par défaut, `pandas` effectue une copie par référence. Dans ce cas, les deux objets (la copie et l'objet copié) restent reliés. Les colonnes @@ -635,7 +686,7 @@ df_new = df.copy() Attention toutefois, cela a un coût mémoire. Avec des données volumineuses, c'est une pratique à utiliser avec précaution -{{< /panel >}} +{{% /panel %}} La manière la plus simple d'opérer pour ajouter des colonnes est d'utiliser la réassignation. Par exemple, pour créer une variable diff --git a/content/manipulation/02b_pandas_TP/index.Rmd b/content/course/manipulation/02b_pandas_TP.Rmd similarity index 98% rename from content/manipulation/02b_pandas_TP/index.Rmd rename to content/course/manipulation/02b_pandas_TP.Rmd index 5cc0b5efa..ba098ef4a 100644 --- a/content/manipulation/02b_pandas_TP/index.Rmd +++ b/content/course/manipulation/02b_pandas_TP.Rmd @@ -14,11 +14,19 @@ title: "Pratique de pandas: un exemple complet" date: 2020-07-09T13:00:00Z draft: false weight: 30 -output: - html_document: - keep_md: true - self_contained: true +tags: + - pandas + - pollution + - Ademe +categories: + - Exercice slug: pandasTP +type: book +summary: | + Après avoir présenté la logique de pandas dans le chapitre précédent, + ce chapitre vise à illustrer les fonctionalités du package + à partir de données d'émissions de gaz à effet de serre + de l'Ademe. --- ```{r setup, include=FALSE} @@ -28,11 +36,6 @@ knitr::knit_engines$set(python = reticulate::eng_python) knitr::opts_chunk$set(echo = FALSE) ``` -```{python, eval = FALSE, include = FALSE} -import os -os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = 'C:/Users/W3CRK9/AppData/Local/r-miniconda/envs/r-reticulate/Library/plugins/platforms' -``` - Dans ce tutoriel `pandas`, nous allons utiliser: diff --git a/content/manipulation/03_geopandas_TP/index.Rmd b/content/course/manipulation/03_geopandas_TP.Rmd similarity index 95% rename from content/manipulation/03_geopandas_TP/index.Rmd rename to content/course/manipulation/03_geopandas_TP.Rmd index e587de347..54f310db1 100644 --- a/content/manipulation/03_geopandas_TP/index.Rmd +++ b/content/course/manipulation/03_geopandas_TP.Rmd @@ -14,13 +14,20 @@ title: "Pratique de geopandas: données vélib" date: 2020-07-09T13:00:00Z draft: false weight: 50 -output: - html_document: - keep_md: true - self_contained: true slug: geopandasTP +tags: + - geopandas + - cartes + - velib +categories: + - Exercice +type: book +summary: | + Ce chapitre illustre les fonctionalités de geopandas à partir des + décomptes de vélo fournis par la ville de Paris en opendata. --- + ```{r setup, include=FALSE} library(knitr) library(reticulate) @@ -28,12 +35,6 @@ knitr::knit_engines$set(python = reticulate::eng_python) knitr::opts_chunk$set(eval = FALSE, include = FALSE, echo = FALSE) ``` -```{python, eval = FALSE, include = FALSE} -import os -os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = 'C:/Users/W3CRK9/AppData/Local/r-miniconda/envs/r-reticulate/Library/plugins/platforms' -os.environ["PROJ_LIB"] = r'C:\Users\W3CRK9\AppData\Local\r-miniconda\pkgs\proj4-4.9.3-hfa6e2cd_9\Library\share' -#os.environ['GDAL_DATA'] = "C:/Users/W3CRK9/AppData/Local/gdal-3-1-2/bin/gdal-data" -``` ```{python, echo = TRUE} import geopandas as gpd diff --git a/content/manipulation/03_geopandas_tutorial/index.Rmd b/content/course/manipulation/03_geopandas_tutorial.Rmd similarity index 91% rename from content/manipulation/03_geopandas_tutorial/index.Rmd rename to content/course/manipulation/03_geopandas_tutorial.Rmd index c8c77ab47..8bd14e9e3 100644 --- a/content/manipulation/03_geopandas_tutorial/index.Rmd +++ b/content/course/manipulation/03_geopandas_tutorial.Rmd @@ -14,18 +14,30 @@ title: "Données spatiales: découverte de geopandas" date: 2020-07-09T13:00:00Z draft: false weight: 40 -output: - html_document: - keep_md: true - self_contained: true slug: geopandas +tags: + - geopandas + - cartes + - velib +categories: + - Tutoriel +type: book +summary: | + Les données géolocalisées se sont multiplées depuis quelques années, qu'il + s'agisse de données open-data ou de traces numériques géolocalisées de + type big-data. Pour les données spatiales, le package geopandas + étend les fonctionalités de l'écosystème pandas afin de permettre + de manipuler des données géographiques complexe de manière simple. --- ```{r setup, include=FALSE} +dir_path <- gsub(here::here(), "..", here::here("course","manipulation")) + library(knitr) library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) knitr::opts_chunk$set(fig.path = "") +knitr::opts_chunk$set(eval = TRUE, warning = FALSE, message = FALSE) # Hook from Maelle Salmon: https://ropensci.org/technotes/2020/04/23/rmd-learnings/ knitr::knit_hooks$set( @@ -34,7 +46,7 @@ knitr::knit_hooks$set( paste0( "{", "{
diff --git a/content/manipulation/05a_s3/index.Rmd b/content/course/manipulation/05a_s3.Rmd similarity index 91% rename from content/manipulation/05a_s3/index.Rmd rename to content/course/manipulation/05a_s3.Rmd index 4f3bc9c37..0e81f9d4f 100644 --- a/content/manipulation/05a_s3/index.Rmd +++ b/content/course/manipulation/05a_s3.Rmd @@ -14,11 +14,23 @@ title: "Lire des données depuis s3" date: 2020-07-09T15:00:00Z draft: false weight: 70 -output: - html_document: - keep_md: true - self_contained: true slug: readS3 +type: book +tags: + - S3 + - boto3 +categories: + - Tutoriel +summary: | + Dans les entreprises et administrations, un nombre croissant + d'infrastructure se basent sur des Cloud, qui sont des sessions + non persistentes où les données ne sont pas stockées dans les mêmes + serveurs que les machines qui exécutent du code. L'une des technologies + dominantes dans le domaine est un système de stockage nommé S3, + développé par Amazon. + Python, à travers les packages boto3 et s3fs, + permet d'utiliser ce système de stockage distant comme si on + accédait à des fichiers depuis son poste personnel. --- # Introduction diff --git a/content/manipulation/_index.md b/content/course/manipulation/_index.md similarity index 82% rename from content/manipulation/_index.md rename to content/course/manipulation/_index.md index 102ceced7..2931151e4 100644 --- a/content/manipulation/_index.md +++ b/content/course/manipulation/_index.md @@ -1,9 +1,23 @@ --- title: "Partie 1: manipuler des données" -date: 2020-07-16T13:00:00Z +date: 2020-07-16 draft: false weight: 20 -slug: "manipulation" +#linktitle: manipulation +type: book +summary: | + Python s'est imposé comme une alternative très crédible à R dans + la manipulation de données. L'écosystème pandas a permis de démocratiser + l'utilisation des DataFrames dans Python et faciliter la manipulation + de données structurées grâce à la philosophie SQL. Python reste également + le langage le plus pratique pour récupérer et manipuler + des données moins structurées (webscraping, API). Python tend à devenir, + grâce au développement d'API vers d'autres langages (C, Spark, Postgres, + ElasticSearch...), + le langage *"one to rule them all"* +slug: manipulation +icon: database +icon_pack: fas --- Le *dataframe* est l'outil central du logiciel `R` mais il s'agit d'un objet qui, en `Python`, ne s'est @@ -34,22 +48,10 @@ de nettoyage de données, notamment des chaînes de caractère. ## Structure de la partie -Dans un premier temps, l'apprentissage des principes de la manipulation -des données se fera de la manière suivante: -* [Une introduction à numpy](numpy) pour découvrir et pratiquer -la manipulation de données avec python ; -* [Des éléments sur pandas](pandascours) et -[un exercice complet pour pratiquer pandas](pandastp). - -Ensuite, nous approfondirons différents aspects de la manipulation de données: - -* [Présentation du traitement des données spatiales](geopandas) -et [pratique de geopandas](geopandastp) -* [Pratique du webscraping](webscraping) -* [Pratique du nettoyage de données textuelles](regex) -* [Pratique du requêtage par les API](api) +{{< list_children >}} +## Exercices Les notebooks d'exercices sont listés [ici](listetp), visualisables via @@ -64,6 +66,8 @@ disposition + + ## Pour aller plus loin Ce cours n'aborde pas encore les questions de volumétrie ou de vitesse de diff --git a/content/modelisation/0_preprocessing/index.Rmd b/content/course/modelisation/0_preprocessing.Rmd similarity index 94% rename from content/modelisation/0_preprocessing/index.Rmd rename to content/course/modelisation/0_preprocessing.Rmd index 3c862daae..078dbff73 100644 --- a/content/modelisation/0_preprocessing/index.Rmd +++ b/content/course/modelisation/0_preprocessing.Rmd @@ -19,9 +19,26 @@ output: keep_md: true self_contained: true slug: preprocessing +tags: + - scikit + - machine learning + - US election + - preprocessing +categories: + - Exercice +type: book +summary: | + Afin d'avoir des données cohérentes avec les hypothèses de modélisation, + il est absolument fondamental de prendre le temps de + préparer les données à fournirà un modèle. La qualité de la prédiction + dépend fortement de ce travail préalable de preprocessing. + Beaucoup de méthodes sont disponibles dans scikit, ce qui rend ce travail + moins fastidieux. --- ```{r setup, include=FALSE} +dir_path <- gsub(here::here(), "..", here::here("course","NLP")) + library(knitr) library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) @@ -35,7 +52,7 @@ knitr::knit_hooks$set( paste0( "{", "{
}} -{{< plotly json="/plotly/test.json" height="400px" >}} -------> +{{< chart data="../course/modelisation/people_vote" >}} + ```{r} -knitr::include_graphics("people_vote.png") +#knitr::include_graphics("people_vote.png") ``` ## Explorer la structure des données @@ -266,15 +276,15 @@ import plotly.express as px htmlsnip2 = px.scatter_matrix(df2) htmlsnip2.update_traces(diagonal_visible=False) # Pour inclusion dans le site web -htmlsnip2.write_image("scatter_plotly.png", width = 800, height = 1600) +htmlsnip2.write_json("scatter_matrix.json") ``` Avec `plotly`, le résultat devrait ressembler au graphique suivant: -```{r} -knitr::include_graphics("scatter_plotly.png") -``` +{{< chart data="../course/modelisation/scatter_matrix" >}} + + diff --git a/content/modelisation/1_modelevaluation/index.Rmd b/content/course/modelisation/1_modelevaluation.Rmd similarity index 94% rename from content/modelisation/1_modelevaluation/index.Rmd rename to content/course/modelisation/1_modelevaluation.Rmd index cb600f7ac..a229d38d6 100644 --- a/content/modelisation/1_modelevaluation/index.Rmd +++ b/content/course/modelisation/1_modelevaluation.Rmd @@ -14,14 +14,28 @@ title: "Evaluer la qualité d'un modèle" date: 2020-10-15T13:00:00Z draft: false weight: 20 -output: - html_document: - keep_md: true - self_contained: true slug: performance +tags: + - scikit + - machine learning + - US elections + - model performance +categories: + - Exercice +type: book +summary: | + Faire preuve de méthode pour évaluer la qualité d'un modèle + permet de proposer des prédictions plus robuste, ayant + de meilleures performances out-of-sample. Décomposer + l'échantillon initial en sous-échantillons d'entraînement + et de tests, faire de la validation croisée, utiliser + les bonnes mesures de performances + peut se faire, grâce à scikit, de manière relativement standardisée --- ```{r setup, include=FALSE} +dir_path <- gsub(here::here(), "..", here::here("course","modelisation")) + library(knitr) library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) @@ -35,7 +49,7 @@ knitr::knit_hooks$set( paste0( "{", "{
}} ## Références diff --git a/content/course/modelisation/_index.md b/content/course/modelisation/_index.md new file mode 100644 index 000000000..b81607378 --- /dev/null +++ b/content/course/modelisation/_index.md @@ -0,0 +1,143 @@ +--- +title: "Partie 3: modéliser" +date: 2020-10-14T13:00:00Z +draft: false +weight: 35 +slug: "modelisation" +type: book +summary: | + La facilité à modéliser des processus très diverses a grandement + participé au succès de Python. La librairie scikit offre une + grande variété de modèles et permet ainsi d'avoir un code + fonctionnel en très peu de temps. +icon: square-root-alt +icon_pack: fas +--- + + +## Principes + +Un modèle statistique est une construction mathématique qui formalise une loi +ayant généré les données. La différence principale entre machine learning et économétrie +est dans le degré de structure imposé par le modélisateur. + +Dans le premier cas, +la structure imposée par le *data scientist* est minimale et ce sont plutôt +les algorithmes qui, sur des critères de performance statistique, vont +déterminer une loi mathématique qui correspond aux données. En économétrie, +les hypothèses de structure des lois sont plus fortes (même dans un cadre semi ou non-paramétrique) et sont plus souvent imposées +par le modélisateur. + +L'adoption du Machine Learning dans la littérature économique a été longue car la structuration des données est souvent le pendant empirique d'hypothèses théoriques sur le comportement des acteurs ou des marchés (Athey and Imbens, 2019). + +Pour caricaturer, l’économétrie s’attache à comprendre la causalité des certaines variables sur une autre donc s'attache principalement à l'estimation des paramètres alors que le Machine Learning se focalise sur un simple objectif prédictif en exploitant les relations de corrélations entre les variables. + +## Panorama d'un éco-système vaste + +Grâce aux principaux packages de Machine Learning (`scikit`), Deep Learning (`keras`, `pytorch`, `TensorFlow`...) et économétrie (`statsmodels`), la modélisation est extrêmement simplifiée. Cela ne doit pas faire oublier l'importance de la structuration et de la préparation des données. Souvent, l'étape la plus cruciale est le choix du modèle le plus adapté à la structure du modèle. L'aide suivante, issue de l'aide de `scikit`, concernant les modèles de Machine Learning peut déjà donner de premiers enseignements sur les différentes familles de modèles: + +L'aide-mémoire suivante peut aider à se diriger dans la large gamme des modèles de `scikit-learn`: + +![](https://scikit-learn.org/stable/_static/ml_map.png) + + +On distingue généralement deux types de méthodes, selon qu'on dispose d'information, dans l'échantillon +d'apprentissage, sur les *y* (on utilisera parfois le terme *label*) : + +* apprentissage supervisé: la valeur cible est connue et peut-être utilisée pour évaluer la qualité d'un modèle +* apprentissage non supervisé: la valeur cible est inconnue et ce sont des critères statistiques qui vont amener +à sélectionner la structure de données la plus plausible. + + +## Données + +La plupart des exemples de cette partie s'appuient sur les résultats des +élections US 2020 au niveau comtés. Plusieurs bases sont utilisées pour +cela: + +* Les données électorales sont une reconstruction à partir des données du MIT election lab +proposées sur `Github` par [@tonmcg](https://github.com/tonmcg/US_County_Level_Election_Results_08-20) +ou directement disponibles sur le site du [MIT Election Lab](https://electionlab.mit.edu/data) +* Les données socioéconomiques (population, données de revenu et de pauvreté, +taux de chômage, variables d'éducation) proviennent de l'USDA ([source](https://www.ers.usda.gov/data-products/county-level-data-sets/)) +* Le *shapefile* vient des données du *Census Bureau*. Le fichier peut +être téléchargé directement depuis cet url: + + +Le code pour construire une base unique à partir de ces sources diverses +est disponible ci-dessous : + + +```{python, eval = FALSE} +import os +import zipfile +import urllib.request +from pathlib import Path + +import numpy as np +import pandas as pd +import geopandas as gpd + +def download_url(url, save_path): + with urllib.request.urlopen(url) as dl_file: + with open(save_path, 'wb') as out_file: + out_file.write(dl_file.read()) + +Path("data").mkdir(parents=True, exist_ok=True) + + +download_url("https://www2.census.gov/geo/tiger/GENZ2019/shp/cb_2019_us_county_20m.zip", "data/shapefile") +with zipfile.ZipFile("data/shapefile", 'r') as zip_ref: + zip_ref.extractall("data/counties") + +shp = gpd.read_file("data/counties/cb_2019_us_county_20m.shp") +shp = shp[~shp["STATEFP"].isin(["02", "69", "66", "78", "60", "72", "15"])] +shp + +df_election = pd.read_csv("https://raw.githubusercontent.com/tonmcg/US_County_Level_Election_Results_08-20/master/2020_US_County_Level_Presidential_Results.csv") +df_election.head(2) +population = pd.read_excel("https://www.ers.usda.gov/webdocs/DataFiles/48747/PopulationEstimates.xls?v=290.4", header = 2).rename(columns = {"FIPStxt": "FIPS"}) +education = pd.read_excel("https://www.ers.usda.gov/webdocs/DataFiles/48747/Education.xls?v=290.4", header = 4).rename(columns = {"FIPS Code": "FIPS", "Area name": "Area_Name"}) +unemployment = pd.read_excel("https://www.ers.usda.gov/webdocs/DataFiles/48747/Unemployment.xls?v=290.4", header = 4).rename(columns = {"fips_txt": "FIPS", "area_name": "Area_Name", "Stabr": "State"}) +income = pd.read_excel("https://www.ers.usda.gov/webdocs/DataFiles/48747/PovertyEstimates.xls?v=290.4", header = 4).rename(columns = {"FIPStxt": "FIPS", "Stabr": "State", "Area_name": "Area_Name"}) + + +dfs = [df.set_index(['FIPS', 'State']) for df in [population, education, unemployment, income]] +data_county = pd.concat(dfs, axis=1) +df_election = df_election.merge(data_county.reset_index(), left_on = "county_fips", right_on = "FIPS") +df_election['county_fips'] = df_election['county_fips'].astype(str).str.lstrip('0') +shp['FIPS'] = shp['GEOID'].astype(str).str.lstrip('0') +votes = shp.merge(df_election, left_on = "FIPS", right_on = "county_fips") + + +df_historical = pd.read_csv('https://dataverse.harvard.edu/api/access/datafile/3641280?gbrecs=false', sep = "\t") +df_historical = df_historical.dropna(subset = ["FIPS"]) +df_historical["FIPS"] = df_historical["FIPS"].astype(int) +df_historical['share'] = df_historical['candidatevotes']/df_historical['totalvotes'] +df_historical = df_historical[["year", "FIPS", "party", "candidatevotes", "share"]] +df_historical['party'] = df_historical['party'].fillna("other") + +df_historical_wide = df_historical.pivot_table(index = "FIPS", values=['candidatevotes',"share"], columns = ["year","party"]) +df_historical_wide.columns = ["_".join(map(str, s)) for s in df_historical_wide.columns.values] +df_historical_wide = df_historical_wide.reset_index() +df_historical_wide['FIPS'] = df_historical_wide['FIPS'].astype(str).str.lstrip('0') +votes['FIPS'] = votes['GEOID'].astype(str).str.lstrip('0') +votes = votes.merge(df_historical_wide, on = "FIPS") + +color_dict = {"republican": '#FF0000', 'democrats': '#0000FF'} +votes["winner"] = np.where(votes['votes_gop'] > votes['votes_dem'], 'republican', 'democrats') +``` + +## Plan de la partie + +{{< list_children >}} + +Autres champs: +* maximum vraisemblance +* stats bayésiennes +* semi et non paramétrique: méthodes noyaux, GAM + + +## Références + +Athey, S., & Imbens, G. W. (2019). Machine learning methods economists should know about, arxiv. diff --git a/content/modelisation/get_data.py b/content/course/modelisation/get_data.py similarity index 100% rename from content/modelisation/get_data.py rename to content/course/modelisation/get_data.py diff --git a/content/references/_index.md b/content/course/references/_index.md similarity index 91% rename from content/references/_index.md rename to content/course/references/_index.md index 183e6c30f..7995c5a60 100644 --- a/content/references/_index.md +++ b/content/course/references/_index.md @@ -3,6 +3,9 @@ title: "Références" date: 2020-07-16T13:00:00Z draft: false weight: 100 +summary: | + Quelques références supplémentaires +type: book --- ## Livres généralistes diff --git a/content/visualisation/_index.md b/content/course/visualisation/_index.md similarity index 82% rename from content/visualisation/_index.md rename to content/course/visualisation/_index.md index 6b119d0de..c61bf6e58 100644 --- a/content/visualisation/_index.md +++ b/content/course/visualisation/_index.md @@ -3,9 +3,21 @@ title: "Partie 2: visualiser les données" date: 2020-09-16T13:00:00Z draft: false weight: 30 -slug: "visualisation" +icon: chart-line +icon_pack: fas +#linktitle: Partie 2: visualisation +summary: | + Cette partie présente les outils pour visualiser des + données avec Python, qu'il s'agisse de graphiques + figés (matplotlib, seaborn, geoplot...) ou de + visualisation réactives (plotly, folium, etc.) +slug: visualisation +type: book +weight: 30 --- + + L'écosystème Python de visualisation de données est très riche. Il est possible de consacrer des livres entiers à celui-ci. Dans le domaine de la visualisation, le parti pris est d'explorer quelques diff --git a/content/visualisation/maps/TP/index.Rmd b/content/course/visualisation/maps.Rmd similarity index 93% rename from content/visualisation/maps/TP/index.Rmd rename to content/course/visualisation/maps.Rmd index a9ddf0068..d86adfc17 100644 --- a/content/visualisation/maps/TP/index.Rmd +++ b/content/course/visualisation/maps.Rmd @@ -14,19 +14,31 @@ title: "De belles cartes avec python: mise en pratique" date: 2020-10-06T13:00:00Z draft: false weight: 20 -output: - html_document: - keep_md: true - self_contained: true slug: cartoTP +type: book +tags: + - visualisation + - geopandas + - cartes +categories: + - Exercice +summary: | + Une découverte de la cartographie, à travers + geopandas, geoplot et folium + pour visualiser la fréquentation par les + vélos des routes parisiennes --- ```{r setup, include=FALSE} + +dir_path <- gsub(here::here(), "..", here::here("course","visualisation")) + library(knitr) library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) knitr::opts_chunk$set(fig.path = "") -knitr::opts_chunk$set(eval = TRUE, echo = FALSE) +knitr::opts_chunk$set(eval = TRUE, echo = FALSE, warning = FALSE, message = FALSE) + # Hook from Maelle Salmon: https://ropensci.org/technotes/2020/04/23/rmd-learnings/ knitr::knit_hooks$set( @@ -35,7 +47,7 @@ knitr::knit_hooks$set( paste0( "{", "{
}} -```{python exo3} +```{python exo3, include = FALSE} ax = arrondissements.to_crs("EPSG:3857").plot(edgecolor = 'k', facecolor="none", figsize = (10,10)) compteurs.to_crs("EPSG:3857").plot(ax = ax, alpha = 0.3, color = 'red') ctx.add_basemap(ax, source = ctx.providers.Stamen.Watercolor) ax.set_axis_off() ax -plt.show() +plt.savefig("map_arr2.png", bbox_inches='tight') ``` +```{r} +knitr::include_graphics("map_arr2.png") +``` Pour le moment, la fonction `geoplot.kdeplot` n'incorpore pas toutes les fonctionalités de `seaborn.kdeplot`. Pour être en mesure de construire une `heatmap` avec des données pondérées (cf. [cette issue dans le dépôt seaborn](https://github.com/mwaskom/seaborn/issues/1364)), il y a une astuce. Il faut simuler *k* points de valeur 1 autour de la localisation observée. La fonction ci-dessous, qui m'a été bien utile, est pratique -~~~markdown +```{python, eval = FALSE} def expand_points(shapefile, index_var = "grid_id", weight_var = 'prop', @@ -210,7 +225,7 @@ def expand_points(shapefile, crs = crs) return gdf -~~~ +``` {{% panel status="exercise" title="Exercice 4: Data cleaning avant de pouvoir faire une heatmap" @@ -304,7 +319,8 @@ Représenter, pour ces deux moments de la journée, la `heatmap` du trafic de v {{< /panel >}} -```{python heatmap} +```{python heatmap, include = FALSE} +fig = plt.figure() ax = geoplot.kdeplot(df1_exploded, figsize=(10, 10), shade=True, shade_lowest=True, @@ -316,6 +332,11 @@ ax = geoplot.kdeplot(df1_exploded, # truc bizarre: bandwidth doit etre beaucoup plus fort sur ma machine windows que sur un notebook tournant sur linux # pour produire résultat équivalent geoplot.polyplot(arrondissements, ax = ax, zorder = 1) +plt.savefig("map_arr3.png", bbox_inches='tight') +``` + +```{r} +knitr::include_graphics("map_arr3.png") ``` @@ -334,18 +355,18 @@ Un objet folium se construit par couche. La première est l'initialisation de la Le bout de code suivant permet de calculer le centre de la carte -~~~python +```{python, eval = FALSE} df['lon'] = df.geometry.x df['lat'] = df.geometry.y center = compteurs[['lat', 'lon']].mean().values.tolist() -~~~ +``` Alors que le code suivant permet de calculer les coins: -~~~python +```{python, eval = FALSE} sw = compteurs[['lat', 'lon']].min().values.tolist() ne = compteurs[['lat', 'lon']].max().values.tolist() -~~~ +``` {{% panel status="hint" title="Hint" icon="fa fa-lightbulb" %}} @@ -363,11 +384,11 @@ A partir des données `compteurs`, représenter la localisation des stations. Le * un zoom optimal -{{< /panel >}} +{{% /panel %}} ```{python folium1, include = FALSE} from pathlib import Path -Path("static/leaflet").mkdir(parents=True, exist_ok=True) +Path("leaflet").mkdir(parents=True, exist_ok=True) compteurs['lon'] = compteurs.geometry.x compteurs['lat'] = compteurs.geometry.y @@ -383,25 +404,18 @@ for i in range(0,len(compteurs)): m.fit_bounds([sw, ne]) - -#m.save("static/leaflet/folium1.html") +m.save("leaflet/folium1.html") ``` +```{python, include = FALSE} +map = m._repr_html_() +``` La carte obtenue doit ressembler à la suivante: - - -{{< rawhtml >}} -```{python} -iframe = m._repr_html_() +```{r, results='asis'} +cat(py$map) ``` -{{< /rawhtml >}} - {{% panel status="exercise" title="Exercice 7: Représenter les stations" icon="fas fa-pencil-alt" %}} @@ -448,17 +462,16 @@ for i in range(0,len(df1)): m.fit_bounds([sw, ne]) -#m.save("static/leaflet/folium2.html") +m.save("static/leaflet/folium2.html") ``` - -{{< rawhtml >}} -```{python} -iframe = m._repr_html_() +```{python, include = FALSE} +map2 = m._repr_html_() +``` + +La carte obtenue doit ressembler à la suivante: + +```{r, results='asis'} +cat(py$map2) ``` -{{< /rawhtml >}} diff --git a/content/visualisation/matplotlib/TP/index.Rmd b/content/course/visualisation/matplotlib.Rmd similarity index 79% rename from content/visualisation/matplotlib/TP/index.Rmd rename to content/course/visualisation/matplotlib.Rmd index 7744d34a4..1151fe2fc 100644 --- a/content/visualisation/matplotlib/TP/index.Rmd +++ b/content/course/visualisation/matplotlib.Rmd @@ -14,19 +14,30 @@ title: "De beaux graphiques avec python: mise en pratique" date: 2020-09-24T13:00:00Z draft: false weight: 10 -output: - html_document: - keep_md: true - self_contained: true slug: matplotlibTP +type: book +tags: + - visualisation + - matplotlib + - seaborn +categories: + - Exercice +summary: | + Une découverte des fonctionalités graphiques de matplotlib, + seaborn et plotly pour représenter des statistiques + sur les décomptes de vélo à Paris --- ```{r setup, include=FALSE} + +dir_path <- gsub(here::here(), "..", here::here("course","visualisation")) + library(knitr) library(reticulate) knitr::knit_engines$set(python = reticulate::eng_python) knitr::opts_chunk$set(fig.path = "") -knitr::opts_chunk$set(eval = FALSE, echo = FALSE) +knitr::opts_chunk$set(eval = TRUE, echo = FALSE, warning = FALSE, message = FALSE) + # Hook from Maelle Salmon: https://ropensci.org/technotes/2020/04/23/rmd-learnings/ knitr::knit_hooks$set( @@ -35,7 +46,7 @@ knitr::knit_hooks$set( paste0( "{", "{
}} +```{r, include=FALSE} +path_data <- here::here("data","bike.csv") +``` -```{python} +```{python, include = FALSE} import pandas as pd -df = pd.read_csv('./data/bike.csv', compression = 'gzip') +df = pd.read_csv(r.path_data, compression = 'gzip') df1 = df.groupby('Nom du compteur').agg({'Comptage horaire': "mean"}).sort_values('Comptage horaire', ascending = False).head(10) df2 = df.groupby('Nom du compteur').agg({'Comptage horaire': "sum"}).sort_values('Comptage horaire', ascending = False).head(10) ``` -```{python} -df1.sort_values('Comptage horaire').plot(kind = "barh", figsize = (25,5), color = 'red') +```{python, include = FALSE} +p = df1.sort_values('Comptage horaire').plot(kind = "barh", figsize = (25,5), color = 'red') +p +plt.savefig('compte.png', bbox_inches='tight') ``` -```{python} -df2.sort_values('Comptage horaire').plot(kind = "barh", figsize = (25,5), color = 'green') +```{r} +knitr::include_graphics("compte.png") +``` + +```{python, include = FALSE} +p2 = df2.sort_values('Comptage horaire').plot(kind = "barh", figsize = (25,5), color = 'green') +p2 +plt.savefig('compte2.png', bbox_inches='tight') +``` + +```{r} +knitr::include_graphics("compte2.png") ``` On peut remarquer plusieurs éléments problématiques (par exemple les labels) mais @@ -151,42 +171,57 @@ icon="fas fa-pencil-alt" %}} Il y a plusieurs manières de faire un *bar* plot en `seaborn`. La plus flexible, c'est-à-dire celle qui permet le mieux d'interagir avec `matplotlib` est `catplot` - + 1. Refaire le graphique précédent avec la fonction adéquate de `seaborn`. Pour contrôler la taille du graphique vous pouvez utiliser les arguments `height` et `aspect` 2. Ajouter les titres des axes et le titre du graphique pour le premier graphique -{{< /panel >}} +{{% /panel %}} -```{python} +```{python, include = FALSE} # Q1 + Q2 g = sns.catplot(x='Comptage horaire', y='Nom du compteur', data=df1, kind = "bar", height = 5, aspect = 4, color = "red") g.set_axis_labels('Moyenne du comptage par heure sur la période sélectionnée', 'Nom du compteur') plt.title('Les 10 compteurs avec la moyenne horaire la plus élevée') -plt.show() +g +plt.savefig('top10.png', bbox_inches='tight') ``` +```{r} +knitr::include_graphics("top10.png") +``` -```{python, eval = FALSE} + +```{python, eval = TRUE, include = FALSE} # ALTERNATIVE Q1 + Q2 plt.figure(figsize=(20,5)) sns.barplot(x='Comptage horaire', y='Nom du compteur', data=df1, color = "red") plt.xlabel('Moyenne du comptage par heure sur la période sélectionnée', size = 24) plt.xlabel('Nom du compteur', size = 24) plt.title('Les 10 compteurs avec la moyenne horaire la plus élevée', size=24) -plt.show() +plt.savefig("compte1_sns.png", bbox_inches='tight') ``` +```{r} +knitr::include_graphics("compte1_sns.png") +``` + + Si vous désirez colorer en rouge l'axe des `x`, vous pouvez pré-définir un style avec `sns.set_style("ticks", {"xtick.color": "red"})` -```{python} +```{python, include = FALSE} sns.set_style("ticks", {"xtick.color": "red"}) g = sns.catplot(x='Comptage horaire', y='Nom du compteur', data=df1, kind = "bar", height = 10, aspect = 2, color = "red") g.set_axis_labels('Moyenne du comptage par heure sur la période sélectionnée', 'Nom du compteur') plt.title('Les 10 compteurs avec la moyenne horaire la plus élevée') -plt.show() + +plt.savefig('top10_sns.png', bbox_inches='tight') +``` + +```{r} +knitr::include_graphics("top10_sns.png") ``` @@ -194,35 +229,42 @@ plt.show() icon="fas fa-pencil-alt" %}} Certaines opérations vont nécessiter un peu d'agilité dans la gestion des dates. -Avant cela, il faut créer une variable temporelle (`datetime`). Pour cela, vous -pouvez faire: +Avant cela, il faut créer une variable temporelle (vous pouvez la nommer +`datetime`) et la transformer en variable mensuelle (grâce à +`dt.to_period('M')`). Vous pouvez essayer de le faire vous même ou cliquer +ci-dessous pour la solution : -```{python} -df['timestamp'] = pd.to_datetime(df['Date et heure de comptage'], format='%Y-%m-%dT%H:%M:%SZ', errors='coerce') +{{< spoiler text="Click to view the spoiler" >}} +```{python, echo = TRUE} +df['timestamp'] = pd.to_datetime(df['Date et heure de comptage'], format='%Y-%m-%dT%H:%M:%SZ', errors='coerce').dt.to_period('M') ``` -.to_period('M') +{{< /spoiler >}} + 1. Refaire le graphique *Les 10 compteurs ayant comptabilisés le plus de vélos * 2. Refaire le graphique *Moyenne mensuelle des comptages vélos *. Pour cela, -vous pouvez utiliser `.dt.to_period('M')` pour transformer un timestamp -en variable de mois +n'oubliez pas de créer la variable mensuelle. 3. Refaire le graphique *Moyenne journalière des comptages vélos* (créer d'abord une variable de jour avec `.dt.day`) 4. Refaire le graphique *Comptages vélo au cours des 7 derniers jours * (de l'échantillon) -{{< /panel >}} +{{% /panel %}} -```{python} +```{python, include = FALSE} # Q1 sns.set_style("ticks", {"xtick.color": "green"}) g = sns.catplot(x='Comptage horaire', y='Nom du compteur', data=df2, kind = "bar", height = 5, aspect = 4, color = "green") g.set_axis_labels('La somme des vélos comptabilisés sur la période sélectionnée', 'Nom du compteur') plt.title('Les 10 compteurs ayant comptabilisés le plus de vélos') -plt.show() +plt.savefig('top10_bike.png', bbox_inches='tight') ``` +```{r} +knitr::include_graphics("top10_bike.png") +``` -```{python} + +```{python, include = FALSE} # Q2 df['month'] = df.timestamp.dt.to_period('M') sns.set_style("whitegrid") @@ -230,30 +272,45 @@ df3 = df.groupby('month').agg({'Comptage horaire':'mean'}).reset_index() g = sns.catplot(x='month', y='Comptage horaire', data=df3, kind = "bar", height = 5, aspect = 4, color = "yellow") g.set_axis_labels('Date et heure de comptage', 'Moyenne mensuelle du comptage par heure sur la période sélectionnée') plt.title('Moyenne mensuelle des comptages vélos') -plt.show() +plt.savefig('top10_bike_sns.png', bbox_inches='tight') +``` + +```{r} +knitr::include_graphics("top10_bike_sns.png") ``` -```{python} +```{python, include = FALSE} # Q3 df['day'] = df.timestamp.dt.date df4 = df.groupby('day').agg({'Comptage horaire':'mean'}).reset_index() sns.lineplot(x='day', y='Comptage horaire', data=df4, color = "magenta") +plt.savefig("lineplot_seaborn.png", bbox_inches='tight') # TO DO: fill sous la courbe ``` -```{python, eval = FALSE} +```{r} +knitr::include_graphics("lineplot_seaborn.png") +``` + +```{python, include = FALSE} # Q4 df['Date'] = pd.to_datetime(df['day']) df['NewDate'] = pd.to_datetime(df.Date) - pd.to_timedelta(7, unit="D") df5 = df[df.day >= (max(df['NewDate']))] df5 = df5.groupby('Date').agg({'Comptage horaire': 'sum'}) g = sns.catplot(y='Comptage horaire', x='Date', data=df5, kind = "bar", height = 10, aspect = 2, color = "lightblue") +g +plt.savefig("barplot_seaborn.png", bbox_inches='tight') ``` +```{r} +knitr::include_graphics("barplot_seaborn.png") +``` + ## Des graphiques dynamiques avec `Plotly` Le package `Plotly` est une surcouche à la librairie Javascript @@ -316,46 +373,42 @@ groupe stockant les trois plus fortes valeurs puis les autres. ```{python, include = FALSE} -fig = px.bar(df1.sort_values('Comptage horaire', ascending = True), orientation = 'h', x='Comptage horaire', y='Nom du compteur', color_discrete_sequence=["red"], template = "plotly_white") +fig = px.bar(df1.sort_values('Comptage horaire', ascending=True), orientation='h', x='Comptage horaire', + y='Nom du compteur', color_discrete_sequence=["red"], template="plotly_white") + fig.update_layout( title='Les 10 compteurs avec la moyenne horaire la plus élevée', xaxis_title='Moyenne du comptage par heure sur la période sélectionnée') fig.update_xaxes(title_font=dict(color='red')) # Pour inclusion dans le site web -htmlsnip = plotly.io.to_html(fig, include_plotlyjs=False) +fig.write_json("plotly1.json") ``` - - + + ```{python, include = FALSE} -df1['top'] = df1['Comptage horaire'] > df1.sort_values('Comptage horaire', ascending = False)['Comptage horaire'][3] -fig2 = px.bar(df1.sort_values('Comptage horaire', ascending = True), orientation = 'h', x='Comptage horaire', y='Nom du compteur', template = "plotly_dark", color = 'top') +df1['top'] = df1['Comptage horaire'] > df1.sort_values('Comptage horaire', ascending=False)['Comptage horaire'][3] +fig2 = px.bar(df1.sort_values('Comptage horaire', ascending=True), orientation='h', x='Comptage horaire', + y='Nom du compteur', template="plotly_dark", color='top') fig2.update_layout( title='Les 10 compteurs avec la moyenne horaire la plus élevée', xaxis_title='Moyenne du comptage par heure sur la période sélectionnée') # Pour inclusion dans le site web -htmlsnip2 = plotly.io.to_html(fig2, include_plotlyjs=False) +fig.write_json("plotly2.json") ``` + + +Le résultat devrait ressembler aux deux graphiques suivants: +{{< chart data="../course/visualisation/plotly" >}} -Le résultat devrait ressembler aux deux graphiques suivants: +{{< chart data="../course/visualisation/plotly2" >}} -{{< rawhtml >}} - -```{r} -tablelight::print_html(py$htmlsnip) -``` -{{< /rawhtml >}} -{{< rawhtml >}} - -```{r} -tablelight::print_html(py$htmlsnip2) -``` -{{< /rawhtml >}} # Exercices supplémentaires https://plotly.com/python/v3/3d-network-graph/ - + + \ No newline at end of file diff --git a/content/git/_index.md b/content/git/_index.md deleted file mode 100644 index 5d8c1397b..000000000 --- a/content/git/_index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Git: un élément essentiel au quotidien" -date: 2020-07-16T13:00:00Z -draft: false -weight: 80 -slug: git ---- - -Cette partie du site présente un élément qui n'est pas propre à -`Python` mais qui est néanmoins indispensable: la pratique de `Git` - -TO DO \ No newline at end of file diff --git a/content/home/features.md b/content/home/features.md new file mode 100644 index 000000000..069556320 --- /dev/null +++ b/content/home/features.md @@ -0,0 +1,21 @@ +--- +widget: featurette +headless: true +weight: 20 +title: +subtitle: Un contenu riche, entièrement ouvert ✨ +feature: + - icon: python + icon_pack: fab + name: Documentation + description: Une documentation complète sur Python + - icon: github + icon_pack: fab + name: Open-source + description: Tout est disponible sur Github + - icon: docker + icon_pack: fab + name: Entièrement reproductible + description: Un dépôt reposant sur les dernières innovations de la conteneurisation pour assurer un contenu reproductible +--- + diff --git a/content/home/hero.md b/content/home/hero.md new file mode 100644 index 000000000..eb82ac6a8 --- /dev/null +++ b/content/home/hero.md @@ -0,0 +1,48 @@ +--- +widget: hero +headless: true +weight: 10 +title: Python pour les data-scientists et économistes +hero_media: python.svg +design: + background: + gradient_start: '#4bb4e3' + gradient_end: '#2b94c3' + text_color_light: true +cta: + url: course/ + label: Get Started + icon_pack: fas + icon: download +cta_alt: + url: course/ + label: View Documentation +# cta_note: +# label: >- +# +# Show your product version here: +# +--- + + + +Star this website on Github + +
+ +Ce site web rend public le contenu du cours de +deuxième année (Master 1) de l'ENSAE: +[*Python pour les data-scientists et économistes*](https://www.ensae.fr/courses/python-pour-le-data-scientist-pour-leconomiste/) +:snake:. + +Le cours est structuré sous la forme du présent site web et de notebooks +jupyter proposant des exercices plus approfondis. L'ensemble +des codes sources est stocké sur [Github](https://github.com/linogaliana/python-datascientist) + + + + diff --git a/content/home/index.md b/content/home/index.md new file mode 100644 index 000000000..327a7cfa7 --- /dev/null +++ b/content/home/index.md @@ -0,0 +1,8 @@ +--- +# Homepage +type: "widget_page" + +# Homepage is headless, other widget pages are not. +headless: true +--- + diff --git a/content/home/pythonDS.bib b/content/home/pythonDS.bib new file mode 100644 index 000000000..38e6bbe7a --- /dev/null +++ b/content/home/pythonDS.bib @@ -0,0 +1,5 @@ +@book{galianapythonDS, + title={Python pour les data-scientists et économistes}, + author={Lino Galiana}, + year={2021} +} diff --git a/layouts/shortcodes/panel.html b/layouts/shortcodes/panel.html new file mode 100644 index 000000000..1cda22a96 --- /dev/null +++ b/layouts/shortcodes/panel.html @@ -0,0 +1,23 @@ +{{ if .IsNamedParams }} +
+{{- with .Get "title" -}} +
+

{{ if $.Get "icon" }} {{ end }}{{- htmlUnescape . | markdownify -}}

+
+{{- end -}} +
+{{.Inner}} +
+
+{{ else }} +
+{{- with .Get 1 -}} +
+

{{ if $.Get 2 }} {{ end }}{{- htmlUnescape . | markdownify -}}

+
+{{- end -}} +
+{{.Inner}} +
+
+{{ end }} \ No newline at end of file diff --git a/netlify.toml b/netlify.toml index 0981a6f02..0330494dd 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,8 +1,10 @@ [build] -command = "hugo" +command = "hugo --gc --minify -b $URL" publish = "public" + [build.environment] -HUGO_VERSION = "0.68.3" +HUGO_VERSION = "0.83.0" +HUGO_ENABLEGITINFO = "true" # [context] # [context.branch-deploy] @@ -12,3 +14,8 @@ HUGO_VERSION = "0.68.3" # [context.production] # [context.production.environment] # HUGO_ENV = "production" + +[[plugins]] + package = "netlify-plugin-hugo-cache-resources" + [plugins.inputs] + debug = true diff --git a/static/media/python.svg b/static/media/python.svg new file mode 100644 index 000000000..23bd5a23c --- /dev/null +++ b/static/media/python.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + \ No newline at end of file diff --git a/view.sh b/view.sh new file mode 100644 index 000000000..99d15ee36 --- /dev/null +++ b/view.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +hugo server --disableFastRender --i18n-warnings -p 1316 \ No newline at end of file