Spaces:
Running
Running
Add files to app
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitignore +166 -0
- README.md +13 -12
- data/classification/credit_score/credit_score_cm_train +0 -0
- data/classification/credit_score/credit_score_test_pp.pkl +3 -0
- data/classification/credit_score/credit_score_test_raw.pkl +3 -0
- data/classification/credit_score/credit_score_train_raw.pkl +3 -0
- data/clustering/clean_marketing.pkl +3 -0
- data/clustering/results/results_2_clusters.pkl +3 -0
- data/clustering/results/results_3_clusters.pkl +3 -0
- data/clustering/results/results_4_clusters.pkl +3 -0
- data/clustering/results/results_5_clusters.pkl +3 -0
- data/clustering/results/results_6_clusters.pkl +3 -0
- data/hotels/booking_df.csv +0 -0
- data/household/household_power_consumption_clean.pkl +3 -0
- data/movies/csr_data_tf.pkl +3 -0
- data/movies/movies_dict2.pkl +3 -0
- data/movies/vote_info.pkl +3 -0
- data/pinterest/image1.jpg +0 -0
- data/pinterest/image2.jpg +0 -0
- data/pinterest/image3.jpg +0 -0
- data/pinterest/image4.jpg +0 -0
- data/sa_data/reviews_raw.pkl +3 -0
- data/sa_data/reviews_results.pkl +3 -0
- images/AI.jpg +0 -0
- images/clustering.webp +0 -0
- images/credit_score.jpg +0 -0
- images/cs.webp +0 -0
- images/energy_consumption.jpg +0 -0
- images/france.jpeg +0 -0
- images/group.png +0 -0
- images/hec.png +0 -0
- images/hi-paris.png +0 -0
- images/models/credit_score/EDA_numeric_credit.png +0 -0
- images/object_detection.png +0 -0
- images/od_fashion.jpg +0 -0
- images/reviews.jpg +0 -0
- images/room.jpg +0 -0
- images/rs.png +0 -0
- images/sentiment_analysis.png +0 -0
- images/singapore.jpg +0 -0
- images/spain-banner.jpg +0 -0
- images/spain.WebP +0 -0
- images/supervised_learner.png +0 -0
- images/thailand.jpeg +0 -0
- images/ts_patterns.png +0 -0
- images/unsupervised_learner.webp +0 -0
- main_page.py +84 -0
- notebooks/Supervised-Unsupervised/credit_score.ipynb +0 -0
- notebooks/Supervised-Unsupervised/customer_churn.ipynb +0 -0
- 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 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|