1927 lines
104 KiB
Plaintext
1927 lines
104 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "5bf5c226",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Business Data Challenge - Team 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"id": "b1a5b9d3",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import pandas as pd\n",
|
||
"import numpy as np\n",
|
||
"import os\n",
|
||
"import s3fs\n",
|
||
"import re\n",
|
||
"import warnings\n",
|
||
"import io\n",
|
||
"import matplotlib.pyplot as plt\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ecfa2219",
|
||
"metadata": {},
|
||
"source": [
|
||
"Configuration de l'accès aux données"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "1a094277",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Create filesystem object\n",
|
||
"S3_ENDPOINT_URL = \"https://\" + os.environ[\"AWS_S3_ENDPOINT\"]\n",
|
||
"fs = s3fs.S3FileSystem(client_kwargs={'endpoint_url': S3_ENDPOINT_URL})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"id": "30d77451-2df6-4c07-8b15-66e0e990ff03",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Import cleaning and merge functions\n",
|
||
"\n",
|
||
"exec(open('0_Cleaning_and_merge_functions.py').read())\n",
|
||
"\n",
|
||
"exec(open('0_KPI_functions.py').read())\n",
|
||
"\n",
|
||
"# Ignore warning\n",
|
||
"warnings.filterwarnings('ignore')\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "f1b44d3e-76bb-4860-b9db-a2840db7cf39",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def load_dataset_2(directory_path, file_name):\n",
|
||
" \"\"\"\n",
|
||
" This function loads csv file\n",
|
||
" \"\"\"\n",
|
||
" file_path = \"bdc2324-data\" + \"/\" + directory_path + \"/\" + directory_path + file_name + \".csv\"\n",
|
||
" with fs.open(file_path, mode=\"rb\") as file_in:\n",
|
||
" df = pd.read_csv(file_in, sep=\",\")\n",
|
||
"\n",
|
||
" # drop na :\n",
|
||
" #df = df.dropna(axis=1, thresh=len(df))\n",
|
||
" # if identifier in table : delete it\n",
|
||
" if 'identifier' in df.columns:\n",
|
||
" df = df.drop(columns = 'identifier')\n",
|
||
" return df"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"id": "31ab76f0-fbb1-46f6-b359-97228620c207",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def export_in_temporary(df, output_name):\n",
|
||
" print('Export of dataset :', output_name)\n",
|
||
" FILE_PATH_OUT_S3 = \"ajoubrel-ensae/Temporary\" + \"/\" + output_name + '.csv'\n",
|
||
" with fs.open(FILE_PATH_OUT_S3, 'w') as file_out:\n",
|
||
" df.to_csv(file_out, index = False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"id": "108fc5ef-c56a-4f03-a867-943d9d6492fd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def save_file_s3(File_name, type_of_activity):\n",
|
||
" image_buffer = io.BytesIO()\n",
|
||
" plt.savefig(image_buffer, format='png')\n",
|
||
" image_buffer.seek(0)\n",
|
||
" FILE_PATH = f\"projet-bdc2324-team1/stat_desc/{type_of_activity}/\"\n",
|
||
" FILE_PATH_OUT_S3 = FILE_PATH + File_name + type_of_activity + '.png'\n",
|
||
" with fs.open(FILE_PATH_OUT_S3, 'wb') as s3_file:\n",
|
||
" s3_file.write(image_buffer.read())\n",
|
||
" plt.close()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ccf597b0-b459-4ea5-baf0-5ba8c90915e4",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Cleaning target area and tags"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"id": "fd88e294-e038-4cec-ad94-2bbbc10a4059",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def concatenate_names(names):\n",
|
||
" return ', '.join(names)\n",
|
||
"\n",
|
||
"def targets_KPI(df_target = None):\n",
|
||
" \n",
|
||
" df_target['target_name'] = df_target['target_name'].fillna('').str.lower()\n",
|
||
"\n",
|
||
" # Target name cotegory musees / \n",
|
||
" df_target['target_jeune'] = df_target['target_name'].str.contains('|'.join(['jeune', 'pass_culture', 'etudiant', '12-25 ans', 'student', 'jeunesse']), case=False).astype(int)\n",
|
||
" df_target['target_optin'] = df_target['target_name'].str.contains('|'.join(['optin' ,'opt-in']), case=False).astype(int)\n",
|
||
" df_target['target_optout'] = df_target['target_name'].str.contains('|'.join(['optout', 'unsubscribed']), case=False).astype(int)\n",
|
||
" df_target['target_scolaire'] = df_target['target_name'].str.contains('|'.join(['scolaire' , 'enseignant', 'chercheur', 'schulen', 'école']), case=False).astype(int)\n",
|
||
" df_target['target_entreprise'] = df_target['target_name'].str.contains('|'.join(['b2b', 'btob', 'cse']), case=False).astype(int)\n",
|
||
" df_target['target_famille'] = df_target['target_name'].str.contains('|'.join(['famille', 'enfants', 'family']), case=False).astype(int)\n",
|
||
" df_target['target_newsletter'] = df_target['target_name'].str.contains('|'.join(['nl', 'newsletter']), case=False).astype(int)\n",
|
||
" \n",
|
||
" # Target name category for sport compagnies\n",
|
||
" df_target['target_abonne'] = ((\n",
|
||
" df_target['target_name']\n",
|
||
" .str.contains('|'.join(['abo', 'adh']), case=False)\n",
|
||
" & ~df_target['target_name'].str.contains('|'.join(['hors abo', 'anciens abo']), case=False)\n",
|
||
" ).astype(int))\n",
|
||
" \n",
|
||
" df_target_categorie = df_target.groupby('customer_id')[['target_jeune', 'target_optin', 'target_optout', 'target_scolaire', 'target_entreprise', 'target_famille', 'target_newsletter', 'target_abonne']].max()\n",
|
||
" \n",
|
||
" target_agg = df_target.groupby('customer_id').agg(\n",
|
||
" nb_targets=('target_name', 'nunique') # Utilisation de tuples pour spécifier les noms de colonnes\n",
|
||
" # all_targets=('target_name', concatenate_names),\n",
|
||
" # all_target_types=('target_type_name', concatenate_names)\n",
|
||
" ).reset_index()\n",
|
||
"\n",
|
||
" target_agg['nb_targets'] = (target_agg['nb_targets'] - (target_agg['nb_targets'].mean())) / (target_agg['nb_targets'].std())\n",
|
||
" \n",
|
||
" target_agg = pd.merge(target_agg, df_target_categorie, how='left', on='customer_id')\n",
|
||
" \n",
|
||
" return target_agg"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"id": "1b124018-9637-463e-b512-15743ec9480b",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"File path : projet-bdc2324-team1/0_Input/Company_5/target_information.csv\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<div>\n",
|
||
"<style scoped>\n",
|
||
" .dataframe tbody tr th:only-of-type {\n",
|
||
" vertical-align: middle;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe tbody tr th {\n",
|
||
" vertical-align: top;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe thead th {\n",
|
||
" text-align: right;\n",
|
||
" }\n",
|
||
"</style>\n",
|
||
"<table border=\"1\" class=\"dataframe\">\n",
|
||
" <thead>\n",
|
||
" <tr style=\"text-align: right;\">\n",
|
||
" <th></th>\n",
|
||
" <th>customer_id</th>\n",
|
||
" <th>nb_targets</th>\n",
|
||
" <th>target_jeune</th>\n",
|
||
" <th>target_optin</th>\n",
|
||
" <th>target_optout</th>\n",
|
||
" <th>target_scolaire</th>\n",
|
||
" <th>target_entreprise</th>\n",
|
||
" <th>target_famille</th>\n",
|
||
" <th>target_newsletter</th>\n",
|
||
" <th>target_abonne</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>160516</td>\n",
|
||
" <td>6.938264</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>160517</td>\n",
|
||
" <td>10.357387</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>160518</td>\n",
|
||
" <td>5.228703</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>160519</td>\n",
|
||
" <td>6.083483</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>160520</td>\n",
|
||
" <td>2.949288</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>471205</th>\n",
|
||
" <td>6405875</td>\n",
|
||
" <td>-0.754762</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>471206</th>\n",
|
||
" <td>6405905</td>\n",
|
||
" <td>-0.469835</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>471207</th>\n",
|
||
" <td>6405909</td>\n",
|
||
" <td>-0.754762</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>471208</th>\n",
|
||
" <td>6405917</td>\n",
|
||
" <td>-0.754762</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>471209</th>\n",
|
||
" <td>6405963</td>\n",
|
||
" <td>-0.754762</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>1</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>471210 rows × 10 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" customer_id nb_targets target_jeune target_optin target_optout \\\n",
|
||
"0 160516 6.938264 0 1 0 \n",
|
||
"1 160517 10.357387 0 1 1 \n",
|
||
"2 160518 5.228703 0 1 1 \n",
|
||
"3 160519 6.083483 0 1 1 \n",
|
||
"4 160520 2.949288 0 1 0 \n",
|
||
"... ... ... ... ... ... \n",
|
||
"471205 6405875 -0.754762 0 0 1 \n",
|
||
"471206 6405905 -0.469835 0 0 1 \n",
|
||
"471207 6405909 -0.754762 0 0 1 \n",
|
||
"471208 6405917 -0.754762 0 0 1 \n",
|
||
"471209 6405963 -0.754762 0 0 1 \n",
|
||
"\n",
|
||
" target_scolaire target_entreprise target_famille target_newsletter \\\n",
|
||
"0 0 1 0 0 \n",
|
||
"1 0 0 0 0 \n",
|
||
"2 0 0 0 0 \n",
|
||
"3 0 0 1 0 \n",
|
||
"4 0 0 0 0 \n",
|
||
"... ... ... ... ... \n",
|
||
"471205 0 0 0 0 \n",
|
||
"471206 0 0 0 0 \n",
|
||
"471207 0 0 0 0 \n",
|
||
"471208 0 0 0 0 \n",
|
||
"471209 0 0 0 0 \n",
|
||
"\n",
|
||
" target_abonne \n",
|
||
"0 1 \n",
|
||
"1 1 \n",
|
||
"2 1 \n",
|
||
"3 1 \n",
|
||
"4 1 \n",
|
||
"... ... \n",
|
||
"471205 0 \n",
|
||
"471206 0 \n",
|
||
"471207 0 \n",
|
||
"471208 0 \n",
|
||
"471209 0 \n",
|
||
"\n",
|
||
"[471210 rows x 10 columns]"
|
||
]
|
||
},
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"targets_KPI(display_input_databases('5', file_name = \"target_information\"))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 35,
|
||
"id": "7bbca184-1ec1-43b5-ba50-c5e8343d52e7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def targets_name_category(df_target=None):\n",
|
||
" if df_target is None:\n",
|
||
" return None\n",
|
||
" \n",
|
||
" df_target['target_name'] = df_target['target_name'].fillna('').str.lower()\n",
|
||
"\n",
|
||
" # Target name category for museums\n",
|
||
" df_target['target_jeune'] = df_target['target_name'].str.contains('|'.join(['jeune', 'pass_culture', 'etudiant', '12-25 ans', 'student', 'jeunesse']), case=False).astype(int)\n",
|
||
" df_target['target_optin'] = df_target['target_name'].str.contains('|'.join(['optin', 'opt-in']), case=False).astype(int)\n",
|
||
" df_target['target_optout'] = df_target['target_name'].str.contains('|'.join(['optout', 'unsubscribed']), case=False).astype(int)\n",
|
||
" df_target['target_scolaire'] = df_target['target_name'].str.contains('|'.join(['scolaire', 'enseignant', 'chercheur', 'schulen', 'école']), case=False).astype(int)\n",
|
||
" df_target['target_entreprise'] = df_target['target_name'].str.contains('|'.join(['b2b', 'btob', 'cse']), case=False).astype(int)\n",
|
||
" df_target['target_famille'] = df_target['target_name'].str.contains('|'.join(['famille', 'enfants', 'family']), case=False).astype(int)\n",
|
||
" df_target['target_newsletter'] = df_target['target_name'].str.contains('|'.join(['nl', 'newsletter']), case=False).astype(int)\n",
|
||
" \n",
|
||
" # Target name category for sport companies\n",
|
||
" df_target['target_abonne'] = ((df_target['target_name']\n",
|
||
" .str.contains('|'.join(['abo', 'adh']), case=False)\n",
|
||
" & ~df_target['target_name'].str.contains('|'.join(['hors abo', 'anciens abo']), case=False))\n",
|
||
" .astype(int))\n",
|
||
"\n",
|
||
" list_target_jeune = df_target[df_target['target_jeune'] == 1]['target_name'].unique()\n",
|
||
" list_target_optin = df_target[df_target['target_optin'] == 1]['target_name'].unique()\n",
|
||
" list_target_optout = df_target[df_target['target_optout'] == 1]['target_name'].unique()\n",
|
||
" list_target_scolaire = df_target[df_target['target_scolaire'] == 1]['target_name'].unique()\n",
|
||
" list_target_entreprise = df_target[df_target['target_entreprise'] == 1]['target_name'].unique()\n",
|
||
" list_target_famille = df_target[df_target['target_famille'] == 1]['target_name'].unique()\n",
|
||
" list_target_newsletter = df_target[df_target['target_newsletter'] == 1]['target_name'].unique()\n",
|
||
" list_target_abonne = df_target[df_target['target_abonne'] == 1]['target_name'].unique()\n",
|
||
"\n",
|
||
" list_all = [list_target_jeune, list_target_optin, list_target_optout, list_target_scolaire,\n",
|
||
" list_target_entreprise, list_target_famille, list_target_newsletter, list_target_abonne]\n",
|
||
"\n",
|
||
" category_name = ['target_jeune', 'target_optin', 'target_optout', 'target_scolaire',\n",
|
||
" 'target_entreprise', 'target_famille', 'target_newsletter', 'target_abonne']\n",
|
||
" \n",
|
||
" liste_category = pd.DataFrame({'category_name': category_name,\n",
|
||
" 'list_target_name': list_all})\n",
|
||
" \n",
|
||
" return liste_category\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 36,
|
||
"id": "fbabcf4d-3ee6-4441-b231-d7ef24b7f160",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"File path : projet-bdc2324-team1/0_Input/Company_7/target_information.csv\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<div>\n",
|
||
"<style scoped>\n",
|
||
" .dataframe tbody tr th:only-of-type {\n",
|
||
" vertical-align: middle;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe tbody tr th {\n",
|
||
" vertical-align: top;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe thead th {\n",
|
||
" text-align: right;\n",
|
||
" }\n",
|
||
"</style>\n",
|
||
"<table border=\"1\" class=\"dataframe\">\n",
|
||
" <thead>\n",
|
||
" <tr style=\"text-align: right;\">\n",
|
||
" <th></th>\n",
|
||
" <th>category_name</th>\n",
|
||
" <th>list_target_name</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>target_jeune</td>\n",
|
||
" <td>[jeunesses vaudoises, etudiant hors ssc 22-23, student supporter club, etudiants hors epfl, student supporter club ehl, etudiants]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>target_optin</td>\n",
|
||
" <td>[]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>target_optout</td>\n",
|
||
" <td>[]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>target_scolaire</td>\n",
|
||
" <td>[]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>target_entreprise</td>\n",
|
||
" <td>[prospects b2b, prospects survey b2b, b2b à enlever, prospect b2b fc 06.10, prospect b2b rk 06.10]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>5</th>\n",
|
||
" <td>target_famille</td>\n",
|
||
" <td>[family corner - 20.11.22, family corner - saison 19-20]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>6</th>\n",
|
||
" <td>target_newsletter</td>\n",
|
||
" <td>[consentements nl lhc, newsletter 2022, b2b à enlever, abonnés newsletter - saison 21-22]</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>7</th>\n",
|
||
" <td>target_abonne</td>\n",
|
||
" <td>[abonnés 23/24, non renouvellement abo 23-24 debout (23.06), résas abos debout - 29.06, abonnés - assis, sondage reconduction abos, sondage nouveaux abos, abonnés b2c - relance 1, abonnés b2c - relance 2, relance abos assis, non renouvellement abo 23-24 assis (23.06), résas abos assis - 29.06, abonnés - playoffs, abonnés - debout, abonnés non vip - saison 22-23, avantage abonné - ticket, paiements abos, campagneabosconcours - abonnés 21-22 en attente, campagneabosconcours - abonnés 22-23, nouveaux abonnés - saison 22-23, abonnements - relance 15.04, abonnements - relance 13.04, abonnements - relance 11.04, abonnements - relance 07.04, abonnés newsletter - saison 21-22, abonnés 1-3 ans, abonnés 1-3 ans - relance, abonnés - non-renouvellement 22-23, abonnés - renoncement playoffs 22, abonnés 5 ans - relance, abonnés - version finale]</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" category_name \\\n",
|
||
"0 target_jeune \n",
|
||
"1 target_optin \n",
|
||
"2 target_optout \n",
|
||
"3 target_scolaire \n",
|
||
"4 target_entreprise \n",
|
||
"5 target_famille \n",
|
||
"6 target_newsletter \n",
|
||
"7 target_abonne \n",
|
||
"\n",
|
||
" list_target_name \n",
|
||
"0 [jeunesses vaudoises, etudiant hors ssc 22-23, student supporter club, etudiants hors epfl, student supporter club ehl, etudiants] \n",
|
||
"1 [] \n",
|
||
"2 [] \n",
|
||
"3 [] \n",
|
||
"4 [prospects b2b, prospects survey b2b, b2b à enlever, prospect b2b fc 06.10, prospect b2b rk 06.10] \n",
|
||
"5 [family corner - 20.11.22, family corner - saison 19-20] \n",
|
||
"6 [consentements nl lhc, newsletter 2022, b2b à enlever, abonnés newsletter - saison 21-22] \n",
|
||
"7 [abonnés 23/24, non renouvellement abo 23-24 debout (23.06), résas abos debout - 29.06, abonnés - assis, sondage reconduction abos, sondage nouveaux abos, abonnés b2c - relance 1, abonnés b2c - relance 2, relance abos assis, non renouvellement abo 23-24 assis (23.06), résas abos assis - 29.06, abonnés - playoffs, abonnés - debout, abonnés non vip - saison 22-23, avantage abonné - ticket, paiements abos, campagneabosconcours - abonnés 21-22 en attente, campagneabosconcours - abonnés 22-23, nouveaux abonnés - saison 22-23, abonnements - relance 15.04, abonnements - relance 13.04, abonnements - relance 11.04, abonnements - relance 07.04, abonnés newsletter - saison 21-22, abonnés 1-3 ans, abonnés 1-3 ans - relance, abonnés - non-renouvellement 22-23, abonnés - renoncement playoffs 22, abonnés 5 ans - relance, abonnés - version finale] "
|
||
]
|
||
},
|
||
"execution_count": 36,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"pd.set_option('display.max_colwidth', None)\n",
|
||
"targets_name_category(display_input_databases('7', file_name = \"target_information\"))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c75efea3-b5e8-4a7a-bed4-dd64ae9ff9f2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"#export_inv_temporary(target_agg, 'Target_kpi_concatenate')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "9d224485-3472-4cc7-9825-1a643bc94fef",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"File path : projet-bdc2324-team1/0_Input/Company_5/customerplus_cleaned.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_5/target_information.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_6/customerplus_cleaned.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_6/target_information.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_7/customerplus_cleaned.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_7/target_information.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_8/customerplus_cleaned.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_8/target_information.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_9/customerplus_cleaned.csv\n",
|
||
"File path : projet-bdc2324-team1/0_Input/Company_9/target_information.csv\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"companies = {'musee' : ['1', '2', '3', '4'], # , '101'\n",
|
||
" 'sport': ['5', '6', '7', '8', '9'],\n",
|
||
" 'musique' : ['10', '11', '12', '13', '14']}\n",
|
||
"\n",
|
||
"nb_compagnie = companies['mu']\n",
|
||
"\n",
|
||
"def load_files(nb_compagnie):\n",
|
||
" targets = pd.DataFrame()\n",
|
||
" \n",
|
||
" # début de la boucle permettant de générer des datasets agrégés pour les 5 compagnies de spectacle\n",
|
||
" for directory_path in nb_compagnie:\n",
|
||
" df_customerplus_clean_0 = display_input_databases(directory_path, file_name = \"customerplus_cleaned\")\n",
|
||
" df_target_information = display_input_databases(directory_path, file_name = \"target_information\")\n",
|
||
" \n",
|
||
" df_target_KPI = targets_KPI(df_target = df_target_information)\n",
|
||
" df_target_KPI = pd.merge(df_customerplus_clean_0[['customer_id']], df_target_KPI, how = 'left', on = 'customer_id')\n",
|
||
"\n",
|
||
" targets_columns = list(df_target_KPI.columns)\n",
|
||
" targets_columns.remove('customer_id')\n",
|
||
" df_target_KPI[targets_columns] = df_target_KPI[targets_columns].fillna(0)\n",
|
||
" \n",
|
||
" # creation de la colonne Number compagnie, qui permettra d'agréger les résultats\n",
|
||
" df_target_KPI[\"number_company\"]=int(directory_path)\n",
|
||
" \n",
|
||
" # Traitement des index\n",
|
||
" df_target_KPI[\"customer_id\"]= directory_path + '_' + df_target_KPI['customer_id'].astype('str')\n",
|
||
" \n",
|
||
" # Concaténation\n",
|
||
" targets = pd.concat([targets, df_target_KPI], ignore_index=True)\n",
|
||
" \n",
|
||
" return targets\n",
|
||
"\n",
|
||
"targets = load_files(nb_compagnie)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"id": "3c911274-0ebd-49af-9487-26524ba20e74",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"\n",
|
||
"def target_description(targets, type_of_activity):\n",
|
||
"\n",
|
||
" describe_target = targets.groupby('number_company').agg(\n",
|
||
" prop_target_jeune=('target_jeune', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_scolaire=('target_scolaire', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_entreprise=('target_entreprise', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_famille=('target_famille', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_optin=('target_optin', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_optout=('target_optout', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_newsletter=('target_newsletter', lambda x: (x.sum() / x.count())*100),\n",
|
||
" prop_target_abonne=('target_abonne', lambda x: (x.sum() / x.count())*100))\n",
|
||
"\n",
|
||
" plot = describe_target.plot.bar()\n",
|
||
" \n",
|
||
" # Adding a title\n",
|
||
" plot.set_title(\"Distribution of Targets by Category\")\n",
|
||
" \n",
|
||
" # Adding labels for x and y axes\n",
|
||
" plot.set_xlabel(\"Company Number\")\n",
|
||
" plot.set_ylabel(\"Target Proportion\")\n",
|
||
"\n",
|
||
" plot.set_xticklabels(plot.get_xticklabels(), rotation=0, horizontalalignment='center')\n",
|
||
"\n",
|
||
" \n",
|
||
" # Adding a legend\n",
|
||
" plot.legend([\"Youth\", \"School\", \"Enterprise\", \"Family\", \"Optin\", \"Optout\", \"Newsletter\", \"Subscriber\"], title=\"Target Category\")\n",
|
||
"\n",
|
||
" # save_file_s3(\"target_category_proportion_\", type_of_activity)\n",
|
||
" return plot"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 28,
|
||
"id": "af62ecef-9120-4107-af3e-512588a96800",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<Axes: title={'center': 'Distribution of Targets by Category'}, xlabel='Company Number', ylabel='Target Proportion'>"
|
||
]
|
||
},
|
||
"execution_count": 28,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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i08nrlSpEiIjIwEAr169QmpqatFGR0RERPSVCp3sDBo0CG/evEGzZs0QFBQEAOjZsyfGjh2LIUOGoE+fPmjVqlWxBUpERET0JQo9jBUYGAhfX1+sWbMGaWlpAN4/r0ZNTQ0XL15Et27dMHPmzGILlIiIiOhLFDrZEQQBwPthrFwqKiqYPHkyJk+eXPSRERERERUBuebsKOJt50RERERfQ667sezs7D6b8CQlJX1VQERERERFSa5kZ86cOTAwMCiuWIiIiIiKnFzJTu/evWFiYlJcsRAREREVuULP2eF8HSIiIiqLCp3s5N6NRURERFSWFHoYKycnpzjjICIiIioWcr8ugoiIiKgsYbJDRERESo3JDhERESk1JjtERESk1JjsEBERkVJjskNERERKjckOERERKTUmO0RERKTUmOwQERGRUmOyQ0REREqNyQ4REREpNSY7REREpNSY7BAREZFSY7JDRERESo3JDhERESk1JjtERESk1JjsEBERkVJjskNERERKjckOERERKTUmO0RERKTUmOwQERGRUmOyQ0REREqNyQ4REREptXKKDoCIPk0qlX7RNiIieo89O0RERKTUmOwQERGRUmOyQ0REREqNyQ4REREpNSY7REREpNSY7BAREZFSY7JDRERESo3JDhERESk1JjtERESk1PgEZSXz2/Czig6BiIioVGHPDhERESk1JjtERESk1JjsEBERkVJjskNERERKjckOERERKTUmO0RERKTUmOwQERGRUmOyQ0REREqNyQ4REREpNSY7REREpNSY7BAREZFSY7JDRERESo3JDhERESk1JjtERESk1Ep1suPj44OGDRtCT08PJiYm8PT0RExMjEwdQRAglUphYWEBLS0ttGjRAlFRUQqKmIiIiEqbUp3shISEYOTIkbh8+TKCgoKQlZWFNm3aICUlRayzePFiLF++HGvWrEF4eDjMzMzg7u6ON2/eKDByIiIiKi3KKTqATzlx4oTMur+/P0xMTHDt2jU0b94cgiDAz88PM2bMQLdu3QAAgYGBMDU1xc6dOzFs2DBFhE1ERESlSKnu2fnY69evAQDly5cHAMTGxiIhIQFt2rQR62hoaMDV1RVhYWEFHic9PR3JyckyCxERESmnMpPsCIKA8ePH4/vvv4eDgwMAICEhAQBgamoqU9fU1FTclh8fHx8YGBiIi6WlZfEF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",
|
||
"text/plain": [
|
||
"<Figure size 640x480 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"target_description(targets, 'sport')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "5d91263e-8a97-4cb1-8d94-db8ab0b77cdf",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"# Brouillon"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c5e864b1-adad-4267-b956-3f7ef371d677",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"\n",
|
||
"def display_covering_time(df, company, datecover):\n",
|
||
" \"\"\"\n",
|
||
" This function draws the time coverage of each company\n",
|
||
" \"\"\"\n",
|
||
" min_date = df['purchase_date'].min().strftime(\"%Y-%m-%d\")\n",
|
||
" max_date = df['purchase_date'].max().strftime(\"%Y-%m-%d\")\n",
|
||
" datecover[company] = [datetime.strptime(min_date, \"%Y-%m-%d\") + timedelta(days=x) for x in range((datetime.strptime(max_date, \"%Y-%m-%d\") - datetime.strptime(min_date, \"%Y-%m-%d\")).days)]\n",
|
||
" print(f'Couverture Company {company} : {min_date} - {max_date}')\n",
|
||
" return datecover\n",
|
||
"\n",
|
||
"\n",
|
||
"def compute_time_intersection(datecover):\n",
|
||
" \"\"\"\n",
|
||
" This function returns the time coverage for all companies\n",
|
||
" \"\"\"\n",
|
||
" timestamps_sets = [set(timestamps) for timestamps in datecover.values()]\n",
|
||
" intersection = set.intersection(*timestamps_sets)\n",
|
||
" intersection_list = list(intersection)\n",
|
||
" formated_dates = [dt.strftime(\"%Y-%m-%d\") for dt in intersection_list]\n",
|
||
" return sorted(formated_dates)\n",
|
||
"\n",
|
||
"\n",
|
||
"def df_coverage_modelization(sport, coverage_features = 0.7):\n",
|
||
" \"\"\"\n",
|
||
" This function returns start_date, end_of_features and final dates\n",
|
||
" that help to construct train and test datasets\n",
|
||
" \"\"\"\n",
|
||
" datecover = {}\n",
|
||
" for company in sport:\n",
|
||
" df_products_purchased_reduced = display_input_databases(company, file_name = \"products_purchased_reduced\",\n",
|
||
" datetime_col = ['purchase_date'])\n",
|
||
" datecover = display_covering_time(df_products_purchased_reduced, company, datecover)\n",
|
||
" #print(datecover.keys())\n",
|
||
" dt_coverage = compute_time_intersection(datecover)\n",
|
||
" start_date = dt_coverage[0]\n",
|
||
" end_of_features = dt_coverage[int(0.7 * len(dt_coverage))]\n",
|
||
" final_date = dt_coverage[-1]\n",
|
||
" return start_date, end_of_features, final_date\n",
|
||
" "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "2435097a-95a5-43e1-84d0-7f6b701441ba",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"# Bases non communes : mise à plat"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f8f988fb-5aab-4b57-80d1-e242f7e5b384",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"companies = {'musee' : ['1', '2', '3', '4'],\n",
|
||
" 'sport': ['5', '6', '7', '8', '9'],\n",
|
||
" 'musique' : ['10', '11', '12', '13', '14']}\n",
|
||
"\n",
|
||
"all_companies = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14']"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "35ac004f-c191-4f45-a4b1-6d993d9ec38c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"companies_databases = pd.DataFrame()\n",
|
||
"\n",
|
||
"for i in all_companies:\n",
|
||
" company_databases = pd.DataFrame({'company_number' : [i]})\n",
|
||
"\n",
|
||
" BUCKET = \"bdc2324-data/\"+i\n",
|
||
" for base in fs.ls(BUCKET):\n",
|
||
" match = re.search(r'\\/(\\d+)\\/(\\d+)([a-zA-Z_]+)\\.csv$', base)\n",
|
||
" if match:\n",
|
||
" nom_base = match.group(3)\n",
|
||
" company_databases[nom_base] = 1\n",
|
||
"\n",
|
||
" companies_databases = pd.concat([companies_databases, company_databases])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "8986e477-e6c5-4d6c-83b2-2c90c134b599",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.set_option(\"display.max_columns\", None)\n",
|
||
"companies_databases\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "8fecc3bb-4c03-4144-97c5-615224d9729e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.reset_option(\"display.max_columns\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0294ce71-840e-458b-8ffa-cadabbc6da21",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Debut Travail 25/02"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ca2c8b6a-4965-422e-ba7c-66423a464fc1",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Base communes au types Musée"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "5080f66e-f779-410a-876d-b4fe2795e17e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"for i in companies['musique']:\n",
|
||
" BUCKET = \"bdc2324-data/\"+i\n",
|
||
" liste_base = []\n",
|
||
" for base in fs.ls(BUCKET):\n",
|
||
" match = re.search(r'\\/(\\d+)\\/(\\d+)([a-zA-Z_]+)\\.csv$', base)\n",
|
||
" if match:\n",
|
||
" nom_base = match.group(3)\n",
|
||
" liste_base.append(nom_base)\n",
|
||
" globals()['base_'+i] = liste_base\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "abd477e1-7479-4c88-a5aa-f987af3f5b79",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Trouver l'intersection entre les cinq listes\n",
|
||
"intersection = set(base_1).intersection(base_2, base_3, base_4, base_101)\n",
|
||
"\n",
|
||
"# Convertir le résultat en liste si nécessaire\n",
|
||
"intersection_liste = list(intersection)\n",
|
||
"\n",
|
||
"print(intersection_liste)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "8d93888f-a511-4ee5-8bc3-d5173a7f119e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Trouver l'intersection entre les cinq listes\n",
|
||
"intersection = set(base_10).intersection(base_12, base_13, base_14, base_11)\n",
|
||
"\n",
|
||
"# Convertir le résultat en liste si nécessaire\n",
|
||
"intersection_liste = list(intersection)\n",
|
||
"\n",
|
||
"print(intersection_liste)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "10e89669-42bb-4652-a4bc-1a3d1caf4d1a",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"len(intersection_liste)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7d058b21-a538-4f59-aefb-ef7966f73fdc",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_tags = load_dataset_2(\"1\", \"tags\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "aa441f99-733c-4675-8676-bed4682d3324",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_structure_tag_mappings = load_dataset_2(\"1\", 'structure_tag_mappings')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6767a750-14a4-4c05-903e-d2f07170825b",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_customersplus = load_dataset_2(\"1\", \"customersplus\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "125e9145-a815-46fd-bdf4-07589508b259",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_customersplus.groupby('structure_id')['id'].count().reset_index().sort_values('id', ascending=False).head(20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c17a6976-792f-474d-bcff-c89396eddb3f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_customersplus['structure_id'].isna().sum() / len(df1_customersplus['structure_id'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "ecfc155a-cb42-46ec-8da5-33fdcd087355",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"len(df1_structure_tag_mappings)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "071410b8-950d-4fcc-b2b9-57415253c286",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_structure_tag_mappings.groupby('tag_id')['structure_id'].count().reset_index().sort_values('structure_id', ascending=False).head(20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f48d27a9-14e4-4bb9-a60a-73e9438b58fc",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"?np.sort_values()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "14eaa0ea-02cc-430b-ab9b-38e6637810c3",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def info_colonnes_dataframe(df):\n",
|
||
" # Créer une liste pour stocker les informations sur chaque colonne\n",
|
||
" infos_colonnes = []\n",
|
||
"\n",
|
||
" # Parcourir les colonnes du DataFrame\n",
|
||
" for nom_colonne, serie in df.items(): # Utiliser items() au lieu de iteritems()\n",
|
||
" # Calculer le taux de valeurs manquantes\n",
|
||
" taux_na = serie.isna().mean() * 100\n",
|
||
"\n",
|
||
" # Ajouter les informations à la liste\n",
|
||
" infos_colonnes.append({\n",
|
||
" 'Nom_colonne': nom_colonne,\n",
|
||
" 'Type_colonne': str(serie.dtype),\n",
|
||
" 'Taux_NA': taux_na\n",
|
||
" })\n",
|
||
"\n",
|
||
" # Créer une nouvelle DataFrame à partir de la liste d'informations\n",
|
||
" df_infos_colonnes = pd.DataFrame(infos_colonnes)\n",
|
||
"\n",
|
||
" return df_infos_colonnes"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6b031c32-d4c8-42a5-9a71-a7810f9bf8d8",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"info_colonnes_dataframe(df1_tags)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e1a87f27-c4d4-4832-ac20-0c3c54aa4980",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"info_colonnes_dataframe(df1_structure_tag_mappings)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "fa5c65a8-2f74-4f3f-85fc-9ac91e0bb361",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.set_option('display.max_colwidth', None)\n",
|
||
"\n",
|
||
"print(df1_tags['name'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a59bf932-5b54-4600-81f5-c55ac93ae510",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.set_option('display.max_rows', None)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a4ab298e-2cae-4865-9f00-4caff5f75ea1",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(df1_tags['name'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "76bffba1-5f7e-4308-9224-437ca66148f8",
|
||
"metadata": {},
|
||
"source": [
|
||
"## KPI sur target_type"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f6daf22e-6583-4431-a467-660a1dd4e5a4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d91d5895",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.set_option('display.max_colwidth', None)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c58b17d3",
|
||
"metadata": {},
|
||
"source": [
|
||
"Raisonnement : on prends les target_type qui représente 90% des clients et on fait des catégories dessus."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6930bff5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def print_main_target(tenant_id, nb_print = 40):\n",
|
||
" df_target = display_input_databases(tenant_id, \"target_information\")\n",
|
||
"\n",
|
||
" print('Nombre de ciblage : ', len(df_target))\n",
|
||
" nb_customers = df_target['customer_id'].nunique()\n",
|
||
" print('Nombre de client avec étiquette target : ', nb_customers) \n",
|
||
"\n",
|
||
" nb_custumers_per_target = df_target.groupby(\"target_name\")['customer_id'].count().reset_index().sort_values('customer_id', ascending=False)\n",
|
||
" nb_custumers_per_target['cumulative_customers'] = nb_custumers_per_target['customer_id'].cumsum()/len(df_target)\n",
|
||
" nb_custumers_per_target['customer_id'] = nb_custumers_per_target['customer_id']/nb_customers\n",
|
||
"\n",
|
||
" return nb_custumers_per_target.head(nb_print)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "1e7ee1a0",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.set_option(\"max_colwidth\", None)\n",
|
||
"print_main_target('1', 60)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "19f3a2dd-ba3d-4dec-8e10-fed544ab6a53",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.reset_option('display.max_rows')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "b57a28ac",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('2', 25)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9a65991f",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('3', 70)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "5f34b8bf",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('4', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "52b24d66-92ad-4421-a62b-5cba837f1893",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pd.set_option('display.max_rows', None)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "40fe3676",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"\n",
|
||
"\n",
|
||
"print_main_target('5', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "820d3600-379b-4245-a977-f1f1fa1f1839",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('6', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "86f64a1b-763a-4e43-9601-a38c80392d47",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('7', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "fbf2ea42-515a-4cdf-a4c1-50f99c379ed9",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('8', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9684045c-4e25-4952-b099-a559baa5d749",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('9', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "cf8f7816-e7f3-4b7a-a987-8350a76eb140",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('10', 100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "76c818a5-3c52-4d97-ac81-b7f3f89092bd",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('11', 100)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "603b11e4-5d76-4699-a1b2-e795929edc04",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('12', 100)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "fa93aecd-d117-481e-8507-15e49937ce14",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('13', 100)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a115ebcf-4488-47f3-9d7e-75a1fca52f0f",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_main_target('14', 100)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "605cced5-052f-4a99-ac26-020c5d2ab633",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"## KPI sur tags"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "916c3e2b-04d3-4877-b894-8f26f10d926e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"customersplus = load_dataset_2(\"4\", \"customersplus\")[['id', 'structure_id']]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "46847b24-15a4-464e-969f-f16ed3653f1f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"structure_tag_mappings = load_dataset_2('4', \"structure_tag_mappings\")[['structure_id', 'tag_id']]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3c10c69d-735f-453e-96bf-750697d965d0",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"customersplus[customersplus['structure_id'].notna()]['structure_id'].nunique()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9b0e77b3-5f16-4484-9564-7d3826583418",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"len(customersplus[customersplus['structure_id'].notna()])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "dfa27722-37f9-435a-8221-8aa6f9a4a107",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"structure_tag_mappings['structure_id'].nunique()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "2daabdd5-31e3-4918-9856-9bbc30cde602",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def tags_information(tenant_id, first_tags):\n",
|
||
"\n",
|
||
" customersplus = load_dataset_2(tenant_id, \"customersplus\")[['id', 'structure_id']]\n",
|
||
" customersplus.rename(columns = {'id' : 'customer_id'}, inplace = True)\n",
|
||
" tags = load_dataset_2(tenant_id, \"tags\")[['id', 'name']]\n",
|
||
" tags.rename(columns = {'id' : 'tag_id', 'name' : 'tag_name'}, inplace = True)\n",
|
||
" structure_tag_mappings = load_dataset_2(tenant_id, \"structure_tag_mappings\")[['structure_id', 'tag_id']]\n",
|
||
" \n",
|
||
" customer_tags = pd.merge(customersplus, structure_tag_mappings, on = 'structure_id', how = 'left')\n",
|
||
" customer_tags = pd.merge(customer_tags, tags, on = 'tag_id', how = 'inner')\n",
|
||
" \n",
|
||
" nb_customers_with_tag = customer_tags['customer_id'].nunique()\n",
|
||
" \n",
|
||
" print('Nombre de client avec tag : ', nb_customers_with_tag)\n",
|
||
" print('Proportion de clients avec tags : ', nb_customers_with_tag/len(customersplus))\n",
|
||
" print('Moyenne de tags par client : ', len(customer_tags)/nb_customers_with_tag)\n",
|
||
" \n",
|
||
" info = customer_tags.groupby(['tag_id', 'tag_name'])['customer_id'].count().reset_index().sort_values('customer_id', ascending = False).head(first_tags)\n",
|
||
"\n",
|
||
" return info"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "0b9f5f71-a927-4cc8-bb0c-9538e28d3553",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tags_information(\"1\", 20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "bd5bef41-1774-4601-86b5-b7c1aea8f1d2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tags_information(\"2\", 20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7c2dc3e6-1418-44db-a8c0-4a9d59ec5232",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"load_dataset_2(\"2\", \"tags\")[['id', 'name']]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c7b2c670-7122-4f67-b1aa-8c80a10f16d8",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tags_information(\"3\", 20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "76639995-252d-4a58-83d8-c0c00900c3a9",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tags_information(\"4\", 20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "07e91791-d4d4-42b1-ac18-22d3b0b9f7bd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tags_information(\"101\", 20)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "87d131cd-ead0-4ef4-a8ee-b09022d08ffa",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"## KPI product"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "26582be9-cfd1-48ea-a0a7-31101fdeb9d1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tenant_id = \"1\"\n",
|
||
"\n",
|
||
"df_product = display_databases(tenant_id, file_name = \"products_purchased_reduced\", datetime_col = ['purchase_date'])\n",
|
||
"\n",
|
||
"df_product.head()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "533bf499-dd56-4d29-b261-ca1e4928c9c7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"nb_tickets_per_events = df_product.groupby(['name_event_types', 'name_events'])['ticket_id'].count().reset_index().sort_values('ticket_id', ascending = False)\n",
|
||
"nb_tickets_per_events['prop_tickets'] = round(nb_tickets_per_events['ticket_id']/len(df_product), 3)\n",
|
||
"nb_tickets_per_events"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "1ede9eaa-7f0a-4856-9349-b2747d6a4901",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"# Fin travail 25/02"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c437eaec",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Exemple sur Company 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e855f403",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"## customersplus.csv"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "91a8f8c4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = pd.DataFrame(df1_customersplus.info())"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "2fda171d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def info_colonnes_dataframe(df):\n",
|
||
" # Créer une liste pour stocker les informations sur chaque colonne\n",
|
||
" infos_colonnes = []\n",
|
||
"\n",
|
||
" # Parcourir les colonnes du DataFrame\n",
|
||
" for nom_colonne, serie in df.items(): # Utiliser items() au lieu de iteritems()\n",
|
||
" # Calculer le taux de valeurs manquantes\n",
|
||
" taux_na = serie.isna().mean() * 100\n",
|
||
"\n",
|
||
" # Ajouter les informations à la liste\n",
|
||
" infos_colonnes.append({\n",
|
||
" 'Nom_colonne': nom_colonne,\n",
|
||
" 'Type_colonne': str(serie.dtype),\n",
|
||
" 'Taux_NA': taux_na\n",
|
||
" })\n",
|
||
"\n",
|
||
" # Créer une nouvelle DataFrame à partir de la liste d'informations\n",
|
||
" df_infos_colonnes = pd.DataFrame(infos_colonnes)\n",
|
||
"\n",
|
||
" return df_infos_colonnes"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "205eeeab",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def cleaning_date(df, column_name):\n",
|
||
" \"\"\"\n",
|
||
" Nettoie la colonne spécifiée du DataFrame en convertissant les valeurs en datetime avec le format ISO8601.\n",
|
||
"\n",
|
||
" Parameters:\n",
|
||
" - df: DataFrame\n",
|
||
" Le DataFrame contenant la colonne à nettoyer.\n",
|
||
" - column_name: str\n",
|
||
" Le nom de la colonne à nettoyer.\n",
|
||
"\n",
|
||
" Returns:\n",
|
||
" - DataFrame\n",
|
||
" Le DataFrame modifié avec la colonne nettoyée.\n",
|
||
" \"\"\"\n",
|
||
" df[column_name] = pd.to_datetime(df[column_name], utc = True, format = 'ISO8601')\n",
|
||
" return df"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "634282c5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = info_colonnes_dataframe(df1_customersplus)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "0e8d4133",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "1268ad5a",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = pd.DataFrame(df1_customersplus.isna().sum()/len(df1_customersplus)*100)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "bd41dc80",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Selection des variables\n",
|
||
"df1_customersplus_clean = df1_customersplus.copy()\n",
|
||
"\n",
|
||
"cleaning_date(df1_customersplus_clean, 'first_buying_date')\n",
|
||
"cleaning_date(df1_customersplus_clean, 'last_visiting_date')\n",
|
||
"\n",
|
||
"df1_customersplus_clean.drop(['lastname', 'firstname', 'email', 'civility', 'note', 'created_at', 'updated_at', 'deleted_at', 'extra', 'reference', 'extra_field', 'identifier', 'need_reload', 'preferred_category', 'preferred_supplier', 'preferred_formula', 'zipcode', 'last_visiting_date'], axis = 1, inplace=True)\n",
|
||
"df1_customersplus_clean.rename(columns = {'id' : 'customer_id'}, inplace = True)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "2455d2e1",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_purchases"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "5f9a159d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_purchases.info()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "db201bf7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Nettoyage purchase_date\n",
|
||
"df1_purchases['purchase_date'] = pd.to_datetime(df1_purchases['purchase_date'], utc = True)\n",
|
||
"df1_purchases['purchase_date'] = pd.to_datetime(df1_purchases['purchase_date'], format = 'ISO8601')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "bd436fca",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_purchases.info()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "83435862",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Selection des variables\n",
|
||
"df1_purchases_clean = df1_purchases[['id', 'purchase_date', 'customer_id']]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "637bdb72",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Customer information"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "14c52894",
|
||
"metadata": {
|
||
"jp-MarkdownHeadingCollapsed": true
|
||
},
|
||
"source": [
|
||
"## Target area - NLP"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d83abfbf",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Target.csv cleaning\n",
|
||
"df1_targets_clean = df1_targets[[\"id\", \"target_type_id\", \"name\"]]\n",
|
||
"df1_targets_clean.rename(columns = {'id' : 'target_id' , 'name' : 'target_name'}, inplace = True)\n",
|
||
"\n",
|
||
"# target_type cleaning\n",
|
||
"df1_target_types_clean = df1_target_types[[\"id\",\"is_import\",\"name\"]].add_prefix(\"target_type_\")\n",
|
||
"\n",
|
||
"#customer_target_mappings cleaning\n",
|
||
"df1_customer_target_mappings_clean = df1_customer_target_mappings[[\"id\", \"customer_id\", \"target_id\"]]\n",
|
||
"\n",
|
||
"# Merge target et target_type\n",
|
||
"df1_targets_full = pd.merge(df1_targets_clean, df1_target_types_clean, left_on='target_type_id', right_on='target_type_id', how='inner')\n",
|
||
"df1_targets_full.drop(['target_type_id'], axis = 1, inplace=True)\n",
|
||
"\n",
|
||
"# Merge\n",
|
||
"df1_targets_full = pd.merge(df1_customer_target_mappings_clean, df1_targets_full, left_on='target_id', right_on='target_id', how='inner')\n",
|
||
"df1_targets_full.drop(['target_id'], axis = 1, inplace=True)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "90d71b2c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_targets_test = df1_targets_full[['id', 'customer_id']].groupby(['customer_id']).count()\n",
|
||
"len(df1_targets_test[df1_targets_test['id'] > 1]) / len(df1_targets_test)\n",
|
||
"\n",
|
||
"# 99,6% des 151 000 client visés sont catégorisés plusieurs fois et en moyenne 5 fois... \n",
|
||
"df1_targets_test.mean()\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "2301de1e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"df1_targets_full.head()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "75fbc2f7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Catégorisation des target_name\n",
|
||
"import pandas as pd\n",
|
||
"import nltk\n",
|
||
"from nltk.tokenize import word_tokenize\n",
|
||
"from nltk.corpus import stopwords\n",
|
||
"from nltk.stem import WordNetLemmatizer\n",
|
||
"from nltk.probability import FreqDist\n",
|
||
"\n",
|
||
"# Téléchargement des ressources nécessaires\n",
|
||
"nltk.download('punkt')\n",
|
||
"nltk.download('stopwords')\n",
|
||
"nltk.download('wordnet')\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "55cddf92",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Définition des fonctions de tokenisation, suppression des mots vides et lemmatisation\n",
|
||
"def preprocess_text(texte):\n",
|
||
" # Concaténation des éléments de la liste en une seule chaîne de caractères\n",
|
||
" texte_concat = ' '.join(texte)\n",
|
||
" \n",
|
||
" # Tokenisation des mots\n",
|
||
" tokens = word_tokenize(texte_concat.lower())\n",
|
||
" \n",
|
||
" # Suppression des mots vides (stopwords)\n",
|
||
" stop_words = set(stopwords.words('french'))\n",
|
||
" filtered_tokens = [word for word in tokens if word not in stop_words]\n",
|
||
" \n",
|
||
" # Lemmatisation des mots\n",
|
||
" lemmatizer = WordNetLemmatizer()\n",
|
||
" lemmatized_tokens = [lemmatizer.lemmatize(word) for word in filtered_tokens]\n",
|
||
" \n",
|
||
" return lemmatized_tokens\n",
|
||
"\n",
|
||
"\n",
|
||
"# Appliquer le prétraitement à la colonne de texte\n",
|
||
"df1_targets_full['target_name_tokened'] = df1_targets_full['target_name'].apply(preprocess_text)\n",
|
||
"\n",
|
||
"# Concaténer les listes de mots pour obtenir une liste de tous les mots dans le corpus\n",
|
||
"all_words = [word for tokens in df1_targets_full['target_name_tokened'] for word in tokens]\n",
|
||
"\n",
|
||
"# Calculer la fréquence des mots\n",
|
||
"freq_dist = FreqDist(all_words)\n",
|
||
"\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7fd98a85",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Affichage des mots les plus fréquents\n",
|
||
"print(\"Mots les plus fréquents:\")\n",
|
||
"for mot, freq in freq_dist.most_common(15):\n",
|
||
" print(f\"{mot}: {freq}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "cf94bb1d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import pandas as pd\n",
|
||
"import nltk\n",
|
||
"from nltk.tokenize import word_tokenize\n",
|
||
"from nltk.corpus import stopwords\n",
|
||
"from nltk.stem import WordNetLemmatizer\n",
|
||
"\n",
|
||
"# Téléchargement des ressources nécessaires\n",
|
||
"nltk.download('punkt')\n",
|
||
"nltk.download('stopwords')\n",
|
||
"nltk.download('wordnet')\n",
|
||
"\n",
|
||
"# Création de la DataFrame d'exemple\n",
|
||
"data = {'texte': [\"Le chat noir mange une souris.\", \"Le chien blanc aboie.\"]}\n",
|
||
"df = pd.DataFrame(data)\n",
|
||
"\n",
|
||
"# Fonction pour prétraiter le texte\n",
|
||
"def preprocess_text(texte):\n",
|
||
" # Concaténation des éléments de la liste en une seule chaîne de caractères\n",
|
||
" texte_concat = ' '.join(texte)\n",
|
||
" \n",
|
||
" # Tokenisation des mots\n",
|
||
" tokens = word_tokenize(texte_concat.lower())\n",
|
||
" \n",
|
||
" # Suppression des mots vides (stopwords)\n",
|
||
" stop_words = set(stopwords.words('french'))\n",
|
||
" filtered_tokens = [word for word in tokens if word not in stop_words]\n",
|
||
" \n",
|
||
" # Lemmatisation des mots\n",
|
||
" lemmatizer = WordNetLemmatizer()\n",
|
||
" lemmatized_tokens = [lemmatizer.lemmatize(word) for word in filtered_tokens]\n",
|
||
" \n",
|
||
" return lemmatized_tokens\n",
|
||
"\n",
|
||
"# Appliquer la fonction de prétraitement à la colonne de texte\n",
|
||
"df['texte_preprocessed'] = df['texte'].apply(preprocess_text)\n",
|
||
"\n",
|
||
"# Afficher le résultat\n",
|
||
"print(df)\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.11.6"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|