laudavid commited on
Commit
c2522bb
1 Parent(s): 345cd95

Add files to app

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +166 -0
  2. README.md +13 -12
  3. data/classification/credit_score/credit_score_cm_train +0 -0
  4. data/classification/credit_score/credit_score_test_pp.pkl +3 -0
  5. data/classification/credit_score/credit_score_test_raw.pkl +3 -0
  6. data/classification/credit_score/credit_score_train_raw.pkl +3 -0
  7. data/clustering/clean_marketing.pkl +3 -0
  8. data/clustering/results/results_2_clusters.pkl +3 -0
  9. data/clustering/results/results_3_clusters.pkl +3 -0
  10. data/clustering/results/results_4_clusters.pkl +3 -0
  11. data/clustering/results/results_5_clusters.pkl +3 -0
  12. data/clustering/results/results_6_clusters.pkl +3 -0
  13. data/hotels/booking_df.csv +0 -0
  14. data/household/household_power_consumption_clean.pkl +3 -0
  15. data/movies/csr_data_tf.pkl +3 -0
  16. data/movies/movies_dict2.pkl +3 -0
  17. data/movies/vote_info.pkl +3 -0
  18. data/pinterest/image1.jpg +0 -0
  19. data/pinterest/image2.jpg +0 -0
  20. data/pinterest/image3.jpg +0 -0
  21. data/pinterest/image4.jpg +0 -0
  22. data/sa_data/reviews_raw.pkl +3 -0
  23. data/sa_data/reviews_results.pkl +3 -0
  24. images/AI.jpg +0 -0
  25. images/clustering.webp +0 -0
  26. images/credit_score.jpg +0 -0
  27. images/cs.webp +0 -0
  28. images/energy_consumption.jpg +0 -0
  29. images/france.jpeg +0 -0
  30. images/group.png +0 -0
  31. images/hec.png +0 -0
  32. images/hi-paris.png +0 -0
  33. images/models/credit_score/EDA_numeric_credit.png +0 -0
  34. images/object_detection.png +0 -0
  35. images/od_fashion.jpg +0 -0
  36. images/reviews.jpg +0 -0
  37. images/room.jpg +0 -0
  38. images/rs.png +0 -0
  39. images/sentiment_analysis.png +0 -0
  40. images/singapore.jpg +0 -0
  41. images/spain-banner.jpg +0 -0
  42. images/spain.WebP +0 -0
  43. images/supervised_learner.png +0 -0
  44. images/thailand.jpeg +0 -0
  45. images/ts_patterns.png +0 -0
  46. images/unsupervised_learner.webp +0 -0
  47. main_page.py +84 -0
  48. notebooks/Supervised-Unsupervised/credit_score.ipynb +0 -0
  49. notebooks/Supervised-Unsupervised/customer_churn.ipynb +0 -0
  50. notebooks/Supervised-Unsupervised/customer_segmentation.ipynb +632 -0
.gitignore ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Streamlit secrets
7
+ .streamlit/
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Virtual Environment
13
+ venv-app-ai-ds/
14
+
15
+ # Distribution / packaging
16
+ .Python
17
+ build/
18
+ develop-eggs/
19
+ dist/
20
+ downloads/
21
+ eggs/
22
+ .eggs/
23
+ lib/
24
+ lib64/
25
+ parts/
26
+ sdist/
27
+ var/
28
+ wheels/
29
+ share/python-wheels/
30
+ *.egg-info/
31
+ .installed.cfg
32
+ *.egg
33
+ MANIFEST
34
+
35
+ # PyInstaller
36
+ # Usually these files are written by a python script from a template
37
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
38
+ *.manifest
39
+ *.spec
40
+
41
+ # Installer logs
42
+ pip-log.txt
43
+ pip-delete-this-directory.txt
44
+
45
+ # Unit test / coverage reports
46
+ htmlcov/
47
+ .tox/
48
+ .nox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *.cover
55
+ *.py,cover
56
+ .hypothesis/
57
+ .pytest_cache/
58
+ cover/
59
+
60
+ # Translations
61
+ *.mo
62
+ *.pot
63
+
64
+ # Django stuff:
65
+ *.log
66
+ local_settings.py
67
+ db.sqlite3
68
+ db.sqlite3-journal
69
+
70
+ # Flask stuff:
71
+ instance/
72
+ .webassets-cache
73
+
74
+ # Scrapy stuff:
75
+ .scrapy
76
+
77
+ # Sphinx documentation
78
+ docs/_build/
79
+
80
+ # PyBuilder
81
+ .pybuilder/
82
+ target/
83
+
84
+ # Jupyter Notebook
85
+ .ipynb_checkpoints
86
+
87
+ # IPython
88
+ profile_default/
89
+ ipython_config.py
90
+
91
+ # pyenv
92
+ # For a library or package, you might want to ignore these files since the code is
93
+ # intended to run in multiple environments; otherwise, check them in:
94
+ # .python-version
95
+
96
+ # pipenv
97
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
98
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
99
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
100
+ # install all needed dependencies.
101
+ #Pipfile.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/#use-with-ide
116
+ .pdm.toml
117
+
118
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
119
+ __pypackages__/
120
+
121
+ # Celery stuff
122
+ celerybeat-schedule
123
+ celerybeat.pid
124
+
125
+ # SageMath parsed files
126
+ *.sage.py
127
+
128
+ # Environments
129
+ .env
130
+ .venv
131
+ env/
132
+ venv/
133
+ ENV/
134
+ env.bak/
135
+ venv.bak/
136
+
137
+ # Spyder project settings
138
+ .spyderproject
139
+ .spyproject
140
+
141
+ # Rope project settings
142
+ .ropeproject
143
+
144
+ # mkdocs documentation
145
+ /site
146
+
147
+ # mypy
148
+ .mypy_cache/
149
+ .dmypy.json
150
+ dmypy.json
151
+
152
+ # Pyre type checker
153
+ .pyre/
154
+
155
+ # pytype static type analyzer
156
+ .pytype/
157
+
158
+ # Cython debug symbols
159
+ cython_debug/
160
+
161
+ # PyCharm
162
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
163
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
164
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
165
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
166
+ #.idea/
README.md CHANGED
@@ -1,13 +1,14 @@
1
- ---
2
- title: App Ai Ds Hec
3
- emoji: 🐨
4
- colorFrom: indigo
5
- colorTo: purple
6
- sdk: streamlit
7
- sdk_version: 1.31.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI and Data Science examples 🧠
2
+ Space for the Streamlit "AI and Data Science examples" HEC Paris app.
 
 
 
 
 
 
 
 
 
3
 
4
+ The app is structured in 5 pages:
5
+ - Supervised vs Unsupervised
6
+ - Time Series Analysis
7
+ - Sentiment Analysis
8
+ - Object detection
9
+ - Recommendation system
10
+
11
+ Each page contains one or more real-life use cases of AI.
12
+ Some of these use cases include electrical power consumption forecasting or customer segmentation
13
+
14
+ Other pages on image segmentation and topic modeling are currently being developped.
data/classification/credit_score/credit_score_cm_train ADDED
Binary file (779 Bytes). View file
 
data/classification/credit_score/credit_score_test_pp.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e0fbd76a90f5289377d21c2d39f377cb73e13de1c71f3818c7b0ea71f46a29ac
3
+ size 241322
data/classification/credit_score/credit_score_test_raw.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c2659d847aeb751f63a49e15b6bdc501be32eaddfaba9b33ca86f279065559f2
3
+ size 103703
data/classification/credit_score/credit_score_train_raw.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7d218682f6e67a5c9f81d227fd90362976185aa78958ab432d6561b6dfd960a4
3
+ size 725729
data/clustering/clean_marketing.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7bde1e077f04583237c0029abf25f841d9100d9050375fbec00c328f14c5c1b2
3
+ size 284225
data/clustering/results/results_2_clusters.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1cd983411f4d5fa3e5e82db4058183af7d22683d8ce52cc909a9a5edb03a153c
3
+ size 1155
data/clustering/results/results_3_clusters.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4ddb93b8758544c327ec2f3336db7dadb3ce013cbe54e82693c4d5cb2d0d441b
3
+ size 1279
data/clustering/results/results_4_clusters.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e6b483a60584781dc8667241b041c9c1962ea0bbd601dd98c3fbc19259e1be34
3
+ size 1403
data/clustering/results/results_5_clusters.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:853b059260cbdedf4ebb2f61f45c4a44d78195609c58797e5d4a47646b357ae2
3
+ size 1527
data/clustering/results/results_6_clusters.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a6c9dd3f0fcdeb05a15076c1e196d7748b79db981153489b0ac31f73a3b69518
3
+ size 1651
data/hotels/booking_df.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/household/household_power_consumption_clean.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1c6207c16c7301dbd331706eac29c250a04da757a73a070d156c69c9f4e04d4c
3
+ size 81958
data/movies/csr_data_tf.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1740a81957cb480a43c02c956a64d2fb3be9213888279641cdbfea8b5ea9c60a
3
+ size 1632893
data/movies/movies_dict2.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fae593200377c6dbfa1b5bc00883234b5c5986fb8f21997431ef0fdd4a814ac8
3
+ size 1722011
data/movies/vote_info.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0bcea5abd2b4f192b1db3c3dea541aeea36ddea662c22270fa186c3bcbf887cc
3
+ size 114227
data/pinterest/image1.jpg ADDED
data/pinterest/image2.jpg ADDED
data/pinterest/image3.jpg ADDED
data/pinterest/image4.jpg ADDED
data/sa_data/reviews_raw.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:11fa1be19b16bdd6e183991367670e735caf9b974dbbbd651b877786078aa557
3
+ size 19784
data/sa_data/reviews_results.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a304e138d8444653e3288434ac2b0804079a6de1271b1de3d27755bba3b25d07
3
+ size 20455
images/AI.jpg ADDED
images/clustering.webp ADDED
images/credit_score.jpg ADDED
images/cs.webp ADDED
images/energy_consumption.jpg ADDED
images/france.jpeg ADDED
images/group.png ADDED
images/hec.png ADDED
images/hi-paris.png ADDED
images/models/credit_score/EDA_numeric_credit.png ADDED
images/object_detection.png ADDED
images/od_fashion.jpg ADDED
images/reviews.jpg ADDED
images/room.jpg ADDED
images/rs.png ADDED
images/sentiment_analysis.png ADDED
images/singapore.jpg ADDED
images/spain-banner.jpg ADDED
images/spain.WebP ADDED
images/supervised_learner.png ADDED
images/thailand.jpeg ADDED
images/ts_patterns.png ADDED
images/unsupervised_learner.webp ADDED
main_page.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import numpy as np
5
+
6
+ from st_pages import Page, show_pages
7
+ from PIL import Image
8
+ #from utils import authenticate_drive
9
+
10
+
11
+
12
+ ##################################################################################
13
+ # PAGE CONFIGURATION #
14
+ ##################################################################################
15
+
16
+ st.set_page_config(layout="wide")
17
+
18
+
19
+
20
+
21
+ ##################################################################################
22
+ # GOOGLE DRIVE CONNEXION #
23
+ ##################################################################################
24
+
25
+ # if ["drive_oauth"] not in st.session_state:
26
+ # st.session_state["drive_oauth"] = authenticate_drive()
27
+
28
+ # drive_oauth = st.session_state["drive_oauth"]
29
+
30
+
31
+
32
+
33
+ ##################################################################################
34
+ # TITLE #
35
+ ##################################################################################
36
+
37
+ st.image("images/AI.jpg")
38
+ st.title("AI and Data Science Examples")
39
+ st.subheader("HEC Paris, 2023-2024")
40
+ st.markdown("Course provided by **Shirish C. SRIVASTAVA**")
41
+
42
+ st.markdown(" ")
43
+ st.info("""**About the app**: The AI and Data Science Examples app was created to introduce students to the field of Data Science by showcasing real-life applications of AI.
44
+ It includes use cases using traditional Machine Learning algorithms on structured data, as well as Deep Learning models run on unstructured data (text, images,...).""")
45
+
46
+ st.divider()
47
+
48
+
49
+ #Hi! PARIS collaboration mention
50
+ st.markdown(" ")
51
+ image_hiparis = Image.open('images/hi-paris.png')
52
+ st.image(image_hiparis, width=150)
53
+ url = "https://www.hi-paris.fr/"
54
+ st.markdown("**The app was made in collaboration with: [Hi! PARIS Engineering Team](%s)**" % url)
55
+
56
+
57
+
58
+
59
+ ##################################################################################
60
+ # DASHBOARD/SIDEBAR #
61
+ ##################################################################################
62
+
63
+
64
+ # AI use case pages
65
+ show_pages(
66
+ [
67
+ Page("main_page.py", "Home Page", "🏠"),
68
+ Page("pages/supervised_unsupervised_page.py", "Supervised vs Unsupervised", "🔍"),
69
+ Page("pages/timeseries_analysis.py", "Time Series Forecasting", "📈"),
70
+ Page("pages/sentiment_analysis.py", "Sentiment Analysis", "👍"),
71
+ #Page("pages/object_detection.py", "Object Detection", "📹"), #need to reduce RAM costs
72
+ Page("pages/recommendation_system.py", "Recommendation system", "🛒")
73
+ ]
74
+ )
75
+
76
+
77
+
78
+ ##################################################################################
79
+ # PAGE CONTENT #
80
+ ##################################################################################
81
+
82
+
83
+
84
+
notebooks/Supervised-Unsupervised/credit_score.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
notebooks/Supervised-Unsupervised/customer_churn.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
notebooks/Supervised-Unsupervised/customer_segmentation.ipynb ADDED
@@ -0,0 +1,632 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 5,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "import pandas as pd\n",
11
+ "import numpy as np\n",
12
+ "import matplotlib.pyplot as plt \n",
13
+ "import seaborn as sns"
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "markdown",
18
+ "metadata": {},
19
+ "source": [
20
+ "## Customer segmentation for targeted marketing campaign\n",
21
+ "\n",
22
+ "https://www.kaggle.com/datasets/imakash3011/customer-personality-analysis\n",
23
+ "\n",
24
+ "**People**\n",
25
+ "- ID: Customer's unique identifier\n",
26
+ "- Year_Birth: Customer's birth year\n",
27
+ "- Education: Customer's education level\n",
28
+ "- Marital_Status: Customer's marital status\n",
29
+ "- Income: Customer's yearly household income\n",
30
+ "- Kidhome: Number of children in customer's household\n",
31
+ "- Teenhome: Number of teenagers in customer's household\n",
32
+ "- Dt_Customer: Date of customer's enrollment with the company\n",
33
+ "- Recency: Number of days since customer's last purchase\n",
34
+ "- Complain: 1 if the customer complained in the last 2 years, 0 otherwise\n",
35
+ "\n",
36
+ "**Products**\n",
37
+ "- MntWines: Amount spent on wine in last 2 years\n",
38
+ "- MntFruits: Amount spent on fruits in last 2 years\n",
39
+ "- MntMeatProducts: Amount spent on meat in last 2 years\n",
40
+ "- MntFishProducts: Amount spent on fish in last 2 years\n",
41
+ "- MntSweetProducts: Amount spent on sweets in last 2 years\n",
42
+ "- MntGoldProds: Amount spent on gold in last 2 years\n",
43
+ "\n",
44
+ "**Promotion**\n",
45
+ "- NumDealsPurchases: Number of purchases made with a discount\n",
46
+ "- AcceptedCmp1: 1 if customer accepted the offer in the 1st campaign, 0 otherwise\n",
47
+ "- AcceptedCmp2: 1 if customer accepted the offer in the 2nd campaign, 0 otherwise\n",
48
+ "- AcceptedCmp3: 1 if customer accepted the offer in the 3rd campaign, 0 otherwise\n",
49
+ "- AcceptedCmp4: 1 if customer accepted the offer in the 4th campaign, 0 otherwise\n",
50
+ "- AcceptedCmp5: 1 if customer accepted the offer in the 5th campaign, 0 otherwise\n",
51
+ "- Response: 1 if customer accepted the offer in the last campaign, 0 otherwise\n",
52
+ "\n",
53
+ "**Place**\n",
54
+ "- NumWebPurchases: Number of purchases made through the company’s website\n",
55
+ "- NumCatalogPurchases: Number of purchases made using a catalogue\n",
56
+ "- NumStorePurchases: Number of purchases made directly in stores\n",
57
+ "- NumWebVisitsMonth: Number of visits to company’s website in the last month"
58
+ ]
59
+ },
60
+ {
61
+ "cell_type": "markdown",
62
+ "metadata": {},
63
+ "source": [
64
+ "### Data Cleaning"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "code",
69
+ "execution_count": 1363,
70
+ "metadata": {},
71
+ "outputs": [],
72
+ "source": [
73
+ "# Load dataset\n",
74
+ "path_data_marketing = r\"C:\\Users\\LaurèneDAVID\\Documents\\Teaching\\Educational_apps\\app-hec-AI-DS\\data\\clustering\\marketing_campaign.csv\"\n",
75
+ "marketing_data = pd.read_csv(path_data_marketing, sep=\";\")"
76
+ ]
77
+ },
78
+ {
79
+ "cell_type": "code",
80
+ "execution_count": 1364,
81
+ "metadata": {},
82
+ "outputs": [],
83
+ "source": [
84
+ "# Delete columns\n",
85
+ "marketing_data.drop(columns=['ID','MntGoldProds','Response','Complain','AcceptedCmp3', 'AcceptedCmp4', 'AcceptedCmp5', 'AcceptedCmp1','AcceptedCmp2',\n",
86
+ " 'Z_CostContact', 'Z_Revenue'], inplace=True)\n",
87
+ "\n",
88
+ "#marketing_data = marketing_data.loc[marketing_data[\"Marital_Status\"].isin([\"Single\",\"Married\",\"Divorced\"])]\n",
89
+ "marketing_data.drop(columns=[\"Marital_Status\"], inplace=True)\n",
90
+ "\n",
91
+ "# marketing_data = marketing_data.loc[marketing_data[\"Education\"].isin([\"2n Cycle\",\"Graduation\",\"Master\",\"PhD\"])]\n",
92
+ "marketing_data.drop(columns=[\"Education\"],inplace=True)\n",
93
+ "\n",
94
+ "marketing_data = marketing_data[marketing_data[\"Income\"]>5000]"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "code",
99
+ "execution_count": 1365,
100
+ "metadata": {},
101
+ "outputs": [],
102
+ "source": [
103
+ "# Change column names\n",
104
+ "new_columns = [col.replace(\"Mnt\",\"\").replace(\"Num\",\"\") for col in list(marketing_data.columns)]\n",
105
+ "new_columns = [col + \"Products\" if col in [\"Wines\",\"Fruits\"] else col for col in new_columns]\n",
106
+ "marketing_data.columns = new_columns"
107
+ ]
108
+ },
109
+ {
110
+ "cell_type": "markdown",
111
+ "metadata": {},
112
+ "source": [
113
+ "### Data Preprocessing"
114
+ ]
115
+ },
116
+ {
117
+ "cell_type": "code",
118
+ "execution_count": 1366,
119
+ "metadata": {},
120
+ "outputs": [],
121
+ "source": [
122
+ "# Proportion of a customer's income spent on wines, fruits, ...\n",
123
+ "products_col = [\"WinesProducts\",\"FruitsProducts\", \"MeatProducts\",\"FishProducts\",\"SweetProducts\"]\n",
124
+ "total_amount_spent = marketing_data[products_col].sum(axis=1)\n",
125
+ "\n",
126
+ "for col in products_col:\n",
127
+ " marketing_data[col] = (100*marketing_data[col] / total_amount_spent).round(1)"
128
+ ]
129
+ },
130
+ {
131
+ "cell_type": "code",
132
+ "execution_count": 1367,
133
+ "metadata": {},
134
+ "outputs": [],
135
+ "source": [
136
+ "# Proportion of web, catalog and store purchases (based on total number of purchases)\n",
137
+ "purchases_col = [\"WebPurchases\", \"CatalogPurchases\", \"StorePurchases\"]\n",
138
+ "total_purchases = marketing_data[purchases_col].sum(axis=1)\n",
139
+ "\n",
140
+ "for col in purchases_col:\n",
141
+ " marketing_data[col] = (100*marketing_data[col] / total_purchases).round(1)"
142
+ ]
143
+ },
144
+ {
145
+ "cell_type": "code",
146
+ "execution_count": 1368,
147
+ "metadata": {},
148
+ "outputs": [],
149
+ "source": [
150
+ "from datetime import datetime, date\n",
151
+ "\n",
152
+ "def get_number_days(input_date):\n",
153
+ " date1 = datetime.strptime(input_date, '%d/%m/%Y').date()\n",
154
+ " date2 = date(2022, 2, 13)\n",
155
+ " return (date2 - date1).days"
156
+ ]
157
+ },
158
+ {
159
+ "cell_type": "code",
160
+ "execution_count": 1369,
161
+ "metadata": {},
162
+ "outputs": [],
163
+ "source": [
164
+ "# Compute a customer's age, based on year of birth\n",
165
+ "marketing_data.insert(0, \"Age\", marketing_data[\"Year_Birth\"].apply(lambda x: 2023-x))\n",
166
+ "\n",
167
+ "# Compute the number of days a customer has been subscribed \n",
168
+ "marketing_data.insert(1, \"Days_subscription\", marketing_data[\"Dt_Customer\"].apply(get_number_days))\n",
169
+ "\n",
170
+ "# Compute total number of kids (kids + teens)\n",
171
+ "marketing_data[\"Kids\"] = marketing_data[\"Kidhome\"] + marketing_data[\"Teenhome\"]\n",
172
+ "marketing_data.drop(columns=[\"Kidhome\",\"Teenhome\"], inplace=True)\n",
173
+ "\n",
174
+ "marketing_data.drop(columns=[\"Year_Birth\", \"Dt_Customer\"], inplace=True)\n",
175
+ "marketing_data.dropna(inplace=True)"
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "code",
180
+ "execution_count": 1370,
181
+ "metadata": {},
182
+ "outputs": [],
183
+ "source": [
184
+ "path_cleandata = r\"C:\\Users\\LaurèneDAVID\\Documents\\Teaching\\Educational_apps\\app-hec-AI-DS\\data\\clustering\"\n",
185
+ "marketing_data.to_pickle(os.path.join(path_cleandata,\"clean_marketing.pkl\"))"
186
+ ]
187
+ },
188
+ {
189
+ "cell_type": "code",
190
+ "execution_count": 1371,
191
+ "metadata": {},
192
+ "outputs": [
193
+ {
194
+ "data": {
195
+ "text/html": [
196
+ "<div>\n",
197
+ "<style scoped>\n",
198
+ " .dataframe tbody tr th:only-of-type {\n",
199
+ " vertical-align: middle;\n",
200
+ " }\n",
201
+ "\n",
202
+ " .dataframe tbody tr th {\n",
203
+ " vertical-align: top;\n",
204
+ " }\n",
205
+ "\n",
206
+ " .dataframe thead th {\n",
207
+ " text-align: right;\n",
208
+ " }\n",
209
+ "</style>\n",
210
+ "<table border=\"1\" class=\"dataframe\">\n",
211
+ " <thead>\n",
212
+ " <tr style=\"text-align: right;\">\n",
213
+ " <th></th>\n",
214
+ " <th>Age</th>\n",
215
+ " <th>Days_subscription</th>\n",
216
+ " <th>Income</th>\n",
217
+ " <th>Recency</th>\n",
218
+ " <th>WinesProducts</th>\n",
219
+ " <th>FruitsProducts</th>\n",
220
+ " <th>MeatProducts</th>\n",
221
+ " <th>FishProducts</th>\n",
222
+ " <th>SweetProducts</th>\n",
223
+ " <th>DealsPurchases</th>\n",
224
+ " <th>WebPurchases</th>\n",
225
+ " <th>CatalogPurchases</th>\n",
226
+ " <th>StorePurchases</th>\n",
227
+ " <th>WebVisitsMonth</th>\n",
228
+ " <th>Kids</th>\n",
229
+ " </tr>\n",
230
+ " </thead>\n",
231
+ " <tbody>\n",
232
+ " <tr>\n",
233
+ " <th>0</th>\n",
234
+ " <td>66</td>\n",
235
+ " <td>3449</td>\n",
236
+ " <td>58138.0</td>\n",
237
+ " <td>58</td>\n",
238
+ " <td>41.5</td>\n",
239
+ " <td>5.8</td>\n",
240
+ " <td>35.7</td>\n",
241
+ " <td>11.2</td>\n",
242
+ " <td>5.8</td>\n",
243
+ " <td>3</td>\n",
244
+ " <td>36.4</td>\n",
245
+ " <td>45.5</td>\n",
246
+ " <td>18.2</td>\n",
247
+ " <td>7</td>\n",
248
+ " <td>0</td>\n",
249
+ " </tr>\n",
250
+ " <tr>\n",
251
+ " <th>1</th>\n",
252
+ " <td>69</td>\n",
253
+ " <td>2899</td>\n",
254
+ " <td>46344.0</td>\n",
255
+ " <td>38</td>\n",
256
+ " <td>52.4</td>\n",
257
+ " <td>4.8</td>\n",
258
+ " <td>28.6</td>\n",
259
+ " <td>9.5</td>\n",
260
+ " <td>4.8</td>\n",
261
+ " <td>2</td>\n",
262
+ " <td>25.0</td>\n",
263
+ " <td>25.0</td>\n",
264
+ " <td>50.0</td>\n",
265
+ " <td>5</td>\n",
266
+ " <td>2</td>\n",
267
+ " </tr>\n",
268
+ " <tr>\n",
269
+ " <th>2</th>\n",
270
+ " <td>58</td>\n",
271
+ " <td>3098</td>\n",
272
+ " <td>71613.0</td>\n",
273
+ " <td>26</td>\n",
274
+ " <td>58.0</td>\n",
275
+ " <td>6.7</td>\n",
276
+ " <td>17.3</td>\n",
277
+ " <td>15.1</td>\n",
278
+ " <td>2.9</td>\n",
279
+ " <td>1</td>\n",
280
+ " <td>40.0</td>\n",
281
+ " <td>10.0</td>\n",
282
+ " <td>50.0</td>\n",
283
+ " <td>4</td>\n",
284
+ " <td>0</td>\n",
285
+ " </tr>\n",
286
+ " <tr>\n",
287
+ " <th>3</th>\n",
288
+ " <td>39</td>\n",
289
+ " <td>2925</td>\n",
290
+ " <td>26646.0</td>\n",
291
+ " <td>26</td>\n",
292
+ " <td>22.9</td>\n",
293
+ " <td>8.3</td>\n",
294
+ " <td>41.7</td>\n",
295
+ " <td>20.8</td>\n",
296
+ " <td>6.2</td>\n",
297
+ " <td>2</td>\n",
298
+ " <td>33.3</td>\n",
299
+ " <td>0.0</td>\n",
300
+ " <td>66.7</td>\n",
301
+ " <td>6</td>\n",
302
+ " <td>1</td>\n",
303
+ " </tr>\n",
304
+ " <tr>\n",
305
+ " <th>4</th>\n",
306
+ " <td>42</td>\n",
307
+ " <td>2947</td>\n",
308
+ " <td>58293.0</td>\n",
309
+ " <td>94</td>\n",
310
+ " <td>42.5</td>\n",
311
+ " <td>10.6</td>\n",
312
+ " <td>29.0</td>\n",
313
+ " <td>11.3</td>\n",
314
+ " <td>6.6</td>\n",
315
+ " <td>5</td>\n",
316
+ " <td>35.7</td>\n",
317
+ " <td>21.4</td>\n",
318
+ " <td>42.9</td>\n",
319
+ " <td>5</td>\n",
320
+ " <td>1</td>\n",
321
+ " </tr>\n",
322
+ " <tr>\n",
323
+ " <th>...</th>\n",
324
+ " <td>...</td>\n",
325
+ " <td>...</td>\n",
326
+ " <td>...</td>\n",
327
+ " <td>...</td>\n",
328
+ " <td>...</td>\n",
329
+ " <td>...</td>\n",
330
+ " <td>...</td>\n",
331
+ " <td>...</td>\n",
332
+ " <td>...</td>\n",
333
+ " <td>...</td>\n",
334
+ " <td>...</td>\n",
335
+ " <td>...</td>\n",
336
+ " <td>...</td>\n",
337
+ " <td>...</td>\n",
338
+ " <td>...</td>\n",
339
+ " </tr>\n",
340
+ " <tr>\n",
341
+ " <th>2235</th>\n",
342
+ " <td>56</td>\n",
343
+ " <td>3167</td>\n",
344
+ " <td>61223.0</td>\n",
345
+ " <td>46</td>\n",
346
+ " <td>64.8</td>\n",
347
+ " <td>3.9</td>\n",
348
+ " <td>16.6</td>\n",
349
+ " <td>3.8</td>\n",
350
+ " <td>10.8</td>\n",
351
+ " <td>2</td>\n",
352
+ " <td>56.2</td>\n",
353
+ " <td>18.8</td>\n",
354
+ " <td>25.0</td>\n",
355
+ " <td>5</td>\n",
356
+ " <td>1</td>\n",
357
+ " </tr>\n",
358
+ " <tr>\n",
359
+ " <th>2236</th>\n",
360
+ " <td>77</td>\n",
361
+ " <td>2805</td>\n",
362
+ " <td>64014.0</td>\n",
363
+ " <td>56</td>\n",
364
+ " <td>93.1</td>\n",
365
+ " <td>0.0</td>\n",
366
+ " <td>6.9</td>\n",
367
+ " <td>0.0</td>\n",
368
+ " <td>0.0</td>\n",
369
+ " <td>7</td>\n",
370
+ " <td>53.3</td>\n",
371
+ " <td>13.3</td>\n",
372
+ " <td>33.3</td>\n",
373
+ " <td>7</td>\n",
374
+ " <td>3</td>\n",
375
+ " </tr>\n",
376
+ " <tr>\n",
377
+ " <th>2237</th>\n",
378
+ " <td>42</td>\n",
379
+ " <td>2941</td>\n",
380
+ " <td>56981.0</td>\n",
381
+ " <td>91</td>\n",
382
+ " <td>74.6</td>\n",
383
+ " <td>3.9</td>\n",
384
+ " <td>17.8</td>\n",
385
+ " <td>2.6</td>\n",
386
+ " <td>1.0</td>\n",
387
+ " <td>1</td>\n",
388
+ " <td>11.1</td>\n",
389
+ " <td>16.7</td>\n",
390
+ " <td>72.2</td>\n",
391
+ " <td>6</td>\n",
392
+ " <td>0</td>\n",
393
+ " </tr>\n",
394
+ " <tr>\n",
395
+ " <th>2238</th>\n",
396
+ " <td>67</td>\n",
397
+ " <td>2942</td>\n",
398
+ " <td>69245.0</td>\n",
399
+ " <td>8</td>\n",
400
+ " <td>54.7</td>\n",
401
+ " <td>3.8</td>\n",
402
+ " <td>27.4</td>\n",
403
+ " <td>10.2</td>\n",
404
+ " <td>3.8</td>\n",
405
+ " <td>2</td>\n",
406
+ " <td>28.6</td>\n",
407
+ " <td>23.8</td>\n",
408
+ " <td>47.6</td>\n",
409
+ " <td>3</td>\n",
410
+ " <td>1</td>\n",
411
+ " </tr>\n",
412
+ " <tr>\n",
413
+ " <th>2239</th>\n",
414
+ " <td>69</td>\n",
415
+ " <td>3408</td>\n",
416
+ " <td>52869.0</td>\n",
417
+ " <td>40</td>\n",
418
+ " <td>55.6</td>\n",
419
+ " <td>2.0</td>\n",
420
+ " <td>40.4</td>\n",
421
+ " <td>1.3</td>\n",
422
+ " <td>0.7</td>\n",
423
+ " <td>3</td>\n",
424
+ " <td>37.5</td>\n",
425
+ " <td>12.5</td>\n",
426
+ " <td>50.0</td>\n",
427
+ " <td>7</td>\n",
428
+ " <td>2</td>\n",
429
+ " </tr>\n",
430
+ " </tbody>\n",
431
+ "</table>\n",
432
+ "<p>2208 rows × 15 columns</p>\n",
433
+ "</div>"
434
+ ],
435
+ "text/plain": [
436
+ " Age Days_subscription Income Recency WinesProducts FruitsProducts \\\n",
437
+ "0 66 3449 58138.0 58 41.5 5.8 \n",
438
+ "1 69 2899 46344.0 38 52.4 4.8 \n",
439
+ "2 58 3098 71613.0 26 58.0 6.7 \n",
440
+ "3 39 2925 26646.0 26 22.9 8.3 \n",
441
+ "4 42 2947 58293.0 94 42.5 10.6 \n",
442
+ "... ... ... ... ... ... ... \n",
443
+ "2235 56 3167 61223.0 46 64.8 3.9 \n",
444
+ "2236 77 2805 64014.0 56 93.1 0.0 \n",
445
+ "2237 42 2941 56981.0 91 74.6 3.9 \n",
446
+ "2238 67 2942 69245.0 8 54.7 3.8 \n",
447
+ "2239 69 3408 52869.0 40 55.6 2.0 \n",
448
+ "\n",
449
+ " MeatProducts FishProducts SweetProducts DealsPurchases WebPurchases \\\n",
450
+ "0 35.7 11.2 5.8 3 36.4 \n",
451
+ "1 28.6 9.5 4.8 2 25.0 \n",
452
+ "2 17.3 15.1 2.9 1 40.0 \n",
453
+ "3 41.7 20.8 6.2 2 33.3 \n",
454
+ "4 29.0 11.3 6.6 5 35.7 \n",
455
+ "... ... ... ... ... ... \n",
456
+ "2235 16.6 3.8 10.8 2 56.2 \n",
457
+ "2236 6.9 0.0 0.0 7 53.3 \n",
458
+ "2237 17.8 2.6 1.0 1 11.1 \n",
459
+ "2238 27.4 10.2 3.8 2 28.6 \n",
460
+ "2239 40.4 1.3 0.7 3 37.5 \n",
461
+ "\n",
462
+ " CatalogPurchases StorePurchases WebVisitsMonth Kids \n",
463
+ "0 45.5 18.2 7 0 \n",
464
+ "1 25.0 50.0 5 2 \n",
465
+ "2 10.0 50.0 4 0 \n",
466
+ "3 0.0 66.7 6 1 \n",
467
+ "4 21.4 42.9 5 1 \n",
468
+ "... ... ... ... ... \n",
469
+ "2235 18.8 25.0 5 1 \n",
470
+ "2236 13.3 33.3 7 3 \n",
471
+ "2237 16.7 72.2 6 0 \n",
472
+ "2238 23.8 47.6 3 1 \n",
473
+ "2239 12.5 50.0 7 2 \n",
474
+ "\n",
475
+ "[2208 rows x 15 columns]"
476
+ ]
477
+ },
478
+ "execution_count": 1371,
479
+ "metadata": {},
480
+ "output_type": "execute_result"
481
+ }
482
+ ],
483
+ "source": [
484
+ "pd.read_pickle(os.path.join(path_cleandata,\"clean_marketing.pkl\"))"
485
+ ]
486
+ },
487
+ {
488
+ "cell_type": "code",
489
+ "execution_count": 1372,
490
+ "metadata": {},
491
+ "outputs": [],
492
+ "source": [
493
+ "from sklearn.compose import ColumnTransformer\n",
494
+ "from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler\n",
495
+ "\n",
496
+ "num_columns = marketing_data.select_dtypes(include=[\"int64\", \"float64\"]).columns\n",
497
+ "\n",
498
+ "# Build data processing pipeline\n",
499
+ "ct = ColumnTransformer(\n",
500
+ " [(\"numerical\", RobustScaler(), num_columns)])\n",
501
+ "\n",
502
+ "X = ct.fit_transform(marketing_data)"
503
+ ]
504
+ },
505
+ {
506
+ "cell_type": "code",
507
+ "execution_count": 1373,
508
+ "metadata": {},
509
+ "outputs": [],
510
+ "source": [
511
+ "columns_transform = [col.split(\"__\")[1] for col in ct.get_feature_names_out()]\n",
512
+ "df_clean = pd.DataFrame(X, columns=columns_transform)"
513
+ ]
514
+ },
515
+ {
516
+ "cell_type": "markdown",
517
+ "metadata": {},
518
+ "source": [
519
+ "### Clustering"
520
+ ]
521
+ },
522
+ {
523
+ "cell_type": "code",
524
+ "execution_count": 1374,
525
+ "metadata": {},
526
+ "outputs": [],
527
+ "source": [
528
+ "from sklearn.cluster import KMeans\n",
529
+ "from sklearn.metrics import silhouette_score\n",
530
+ "\n",
531
+ "def clustering_model(X, list_nb_clusters):\n",
532
+ " dict_labels = dict()\n",
533
+ " list_scores = []\n",
534
+ "\n",
535
+ " for n in list_nb_clusters:\n",
536
+ " kmeans = KMeans(n_clusters=n, n_init=10)\n",
537
+ " labels = kmeans.fit_predict(X)\n",
538
+ " score = silhouette_score(X, labels)\n",
539
+ " dict_labels[f\"{n} clusters\"] = labels\n",
540
+ " list_scores.append(score)\n",
541
+ "\n",
542
+ " return list_scores, dict_labels"
543
+ ]
544
+ },
545
+ {
546
+ "cell_type": "code",
547
+ "execution_count": 1375,
548
+ "metadata": {},
549
+ "outputs": [],
550
+ "source": [
551
+ "list_nb_clusters = np.arange(2,7)\n",
552
+ "scores_kmeans, labels_kmeans = clustering_model(X, list_nb_clusters)"
553
+ ]
554
+ },
555
+ {
556
+ "cell_type": "code",
557
+ "execution_count": 1376,
558
+ "metadata": {},
559
+ "outputs": [
560
+ {
561
+ "data": {
562
+ "image/png": "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",
563
+ "text/plain": [
564
+ "<Figure size 640x480 with 1 Axes>"
565
+ ]
566
+ },
567
+ "metadata": {},
568
+ "output_type": "display_data"
569
+ }
570
+ ],
571
+ "source": [
572
+ "marketing_data_results = pd.DataFrame({\"nb_clusters\":[str(i) for i in np.arange(2,7)], \"scores\":scores_kmeans})\n",
573
+ "\n",
574
+ "sns.lineplot(data=marketing_data_results, x=\"nb_clusters\", y=\"scores\", marker=\"o\")\n",
575
+ "plt.xlabel(\"number of clusters\")\n",
576
+ "plt.ylabel(\"silhouette score\")\n",
577
+ "plt.title(\"Silhouette score of Kmeans\")\n",
578
+ "plt.show()"
579
+ ]
580
+ },
581
+ {
582
+ "cell_type": "markdown",
583
+ "metadata": {},
584
+ "source": [
585
+ "### Save results"
586
+ ]
587
+ },
588
+ {
589
+ "cell_type": "code",
590
+ "execution_count": 1377,
591
+ "metadata": {},
592
+ "outputs": [],
593
+ "source": [
594
+ "import os\n",
595
+ "path_results = r\"C:\\Users\\LaurèneDAVID\\Documents\\Teaching\\Educational_apps\\app-hec-AI-DS\\data\\clustering\\results\"\n",
596
+ "\n",
597
+ "for nb_clusters in list_nb_clusters:\n",
598
+ " labels_ = labels_kmeans[f\"{nb_clusters} clusters\"] # chosen labels\n",
599
+ " marketing_data_labels = marketing_data.copy()\n",
600
+ " marketing_data_labels[\"Group\"] = labels_\n",
601
+ " marketing_data_labels[\"Group\"] = marketing_data_labels[\"Group\"].astype(int)\n",
602
+ "\n",
603
+ " df_mean_results = marketing_data_labels.groupby(\"Group\")[num_columns].mean().reset_index()\n",
604
+ " df_mean_results = df_mean_results.round(1).melt(id_vars=[\"Group\"])\n",
605
+ " df_mean_results = pd.pivot_table(df_mean_results, values='value', index=['variable'], columns=[\"Group\"])\n",
606
+ "\n",
607
+ " df_mean_results.to_pickle(os.path.join(path_results,f\"results_{nb_clusters}_clusters.pkl\"))"
608
+ ]
609
+ }
610
+ ],
611
+ "metadata": {
612
+ "kernelspec": {
613
+ "display_name": "venv",
614
+ "language": "python",
615
+ "name": "python3"
616
+ },
617
+ "language_info": {
618
+ "codemirror_mode": {
619
+ "name": "ipython",
620
+ "version": 3
621
+ },
622
+ "file_extension": ".py",
623
+ "mimetype": "text/x-python",
624
+ "name": "python",
625
+ "nbconvert_exporter": "python",
626
+ "pygments_lexer": "ipython3",
627
+ "version": "3.9.0"
628
+ }
629
+ },
630
+ "nbformat": 4,
631
+ "nbformat_minor": 2
632
+ }