{ "cells": [ { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import os\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt \n", "import seaborn as sns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Customer segmentation for targeted marketing campaign\n", "\n", "https://www.kaggle.com/datasets/imakash3011/customer-personality-analysis\n", "\n", "**People**\n", "- ID: Customer's unique identifier\n", "- Year_Birth: Customer's birth year\n", "- Education: Customer's education level\n", "- Marital_Status: Customer's marital status\n", "- Income: Customer's yearly household income\n", "- Kidhome: Number of children in customer's household\n", "- Teenhome: Number of teenagers in customer's household\n", "- Dt_Customer: Date of customer's enrollment with the company\n", "- Recency: Number of days since customer's last purchase\n", "- Complain: 1 if the customer complained in the last 2 years, 0 otherwise\n", "\n", "**Products**\n", "- MntWines: Amount spent on wine in last 2 years\n", "- MntFruits: Amount spent on fruits in last 2 years\n", "- MntMeatProducts: Amount spent on meat in last 2 years\n", "- MntFishProducts: Amount spent on fish in last 2 years\n", "- MntSweetProducts: Amount spent on sweets in last 2 years\n", "- MntGoldProds: Amount spent on gold in last 2 years\n", "\n", "**Promotion**\n", "- NumDealsPurchases: Number of purchases made with a discount\n", "- AcceptedCmp1: 1 if customer accepted the offer in the 1st campaign, 0 otherwise\n", "- AcceptedCmp2: 1 if customer accepted the offer in the 2nd campaign, 0 otherwise\n", "- AcceptedCmp3: 1 if customer accepted the offer in the 3rd campaign, 0 otherwise\n", "- AcceptedCmp4: 1 if customer accepted the offer in the 4th campaign, 0 otherwise\n", "- AcceptedCmp5: 1 if customer accepted the offer in the 5th campaign, 0 otherwise\n", "- Response: 1 if customer accepted the offer in the last campaign, 0 otherwise\n", "\n", "**Place**\n", "- NumWebPurchases: Number of purchases made through the company’s website\n", "- NumCatalogPurchases: Number of purchases made using a catalogue\n", "- NumStorePurchases: Number of purchases made directly in stores\n", "- NumWebVisitsMonth: Number of visits to company’s website in the last month" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Cleaning" ] }, { "cell_type": "code", "execution_count": 1363, "metadata": {}, "outputs": [], "source": [ "# Load dataset\n", "path_data_marketing = r\"C:\\Users\\LaurèneDAVID\\Documents\\Teaching\\Educational_apps\\app-hec-AI-DS\\data\\clustering\\marketing_campaign.csv\"\n", "marketing_data = pd.read_csv(path_data_marketing, sep=\";\")" ] }, { "cell_type": "code", "execution_count": 1364, "metadata": {}, "outputs": [], "source": [ "# Delete columns\n", "marketing_data.drop(columns=['ID','MntGoldProds','Response','Complain','AcceptedCmp3', 'AcceptedCmp4', 'AcceptedCmp5', 'AcceptedCmp1','AcceptedCmp2',\n", " 'Z_CostContact', 'Z_Revenue'], inplace=True)\n", "\n", "#marketing_data = marketing_data.loc[marketing_data[\"Marital_Status\"].isin([\"Single\",\"Married\",\"Divorced\"])]\n", "marketing_data.drop(columns=[\"Marital_Status\"], inplace=True)\n", "\n", "# marketing_data = marketing_data.loc[marketing_data[\"Education\"].isin([\"2n Cycle\",\"Graduation\",\"Master\",\"PhD\"])]\n", "marketing_data.drop(columns=[\"Education\"],inplace=True)\n", "\n", "marketing_data = marketing_data[marketing_data[\"Income\"]>5000]" ] }, { "cell_type": "code", "execution_count": 1365, "metadata": {}, "outputs": [], "source": [ "# Change column names\n", "new_columns = [col.replace(\"Mnt\",\"\").replace(\"Num\",\"\") for col in list(marketing_data.columns)]\n", "new_columns = [col + \"Products\" if col in [\"Wines\",\"Fruits\"] else col for col in new_columns]\n", "marketing_data.columns = new_columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Preprocessing" ] }, { "cell_type": "code", "execution_count": 1366, "metadata": {}, "outputs": [], "source": [ "# Proportion of a customer's income spent on wines, fruits, ...\n", "products_col = [\"WinesProducts\",\"FruitsProducts\", \"MeatProducts\",\"FishProducts\",\"SweetProducts\"]\n", "total_amount_spent = marketing_data[products_col].sum(axis=1)\n", "\n", "for col in products_col:\n", " marketing_data[col] = (100*marketing_data[col] / total_amount_spent).round(1)" ] }, { "cell_type": "code", "execution_count": 1367, "metadata": {}, "outputs": [], "source": [ "# Proportion of web, catalog and store purchases (based on total number of purchases)\n", "purchases_col = [\"WebPurchases\", \"CatalogPurchases\", \"StorePurchases\"]\n", "total_purchases = marketing_data[purchases_col].sum(axis=1)\n", "\n", "for col in purchases_col:\n", " marketing_data[col] = (100*marketing_data[col] / total_purchases).round(1)" ] }, { "cell_type": "code", "execution_count": 1368, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime, date\n", "\n", "def get_number_days(input_date):\n", " date1 = datetime.strptime(input_date, '%d/%m/%Y').date()\n", " date2 = date(2022, 2, 13)\n", " return (date2 - date1).days" ] }, { "cell_type": "code", "execution_count": 1369, "metadata": {}, "outputs": [], "source": [ "# Compute a customer's age, based on year of birth\n", "marketing_data.insert(0, \"Age\", marketing_data[\"Year_Birth\"].apply(lambda x: 2023-x))\n", "\n", "# Compute the number of days a customer has been subscribed \n", "marketing_data.insert(1, \"Days_subscription\", marketing_data[\"Dt_Customer\"].apply(get_number_days))\n", "\n", "# Compute total number of kids (kids + teens)\n", "marketing_data[\"Kids\"] = marketing_data[\"Kidhome\"] + marketing_data[\"Teenhome\"]\n", "marketing_data.drop(columns=[\"Kidhome\",\"Teenhome\"], inplace=True)\n", "\n", "marketing_data.drop(columns=[\"Year_Birth\", \"Dt_Customer\"], inplace=True)\n", "marketing_data.dropna(inplace=True)" ] }, { "cell_type": "code", "execution_count": 1370, "metadata": {}, "outputs": [], "source": [ "path_cleandata = r\"C:\\Users\\LaurèneDAVID\\Documents\\Teaching\\Educational_apps\\app-hec-AI-DS\\data\\clustering\"\n", "marketing_data.to_pickle(os.path.join(path_cleandata,\"clean_marketing.pkl\"))" ] }, { "cell_type": "code", "execution_count": 1371, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AgeDays_subscriptionIncomeRecencyWinesProductsFruitsProductsMeatProductsFishProductsSweetProductsDealsPurchasesWebPurchasesCatalogPurchasesStorePurchasesWebVisitsMonthKids
066344958138.05841.55.835.711.25.8336.445.518.270
169289946344.03852.44.828.69.54.8225.025.050.052
258309871613.02658.06.717.315.12.9140.010.050.040
339292526646.02622.98.341.720.86.2233.30.066.761
442294758293.09442.510.629.011.36.6535.721.442.951
................................................
223556316761223.04664.83.916.63.810.8256.218.825.051
223677280564014.05693.10.06.90.00.0753.313.333.373
223742294156981.09174.63.917.82.61.0111.116.772.260
223867294269245.0854.73.827.410.23.8228.623.847.631
223969340852869.04055.62.040.41.30.7337.512.550.072
\n", "

2208 rows × 15 columns

\n", "
" ], "text/plain": [ " Age Days_subscription Income Recency WinesProducts FruitsProducts \\\n", "0 66 3449 58138.0 58 41.5 5.8 \n", "1 69 2899 46344.0 38 52.4 4.8 \n", "2 58 3098 71613.0 26 58.0 6.7 \n", "3 39 2925 26646.0 26 22.9 8.3 \n", "4 42 2947 58293.0 94 42.5 10.6 \n", "... ... ... ... ... ... ... \n", "2235 56 3167 61223.0 46 64.8 3.9 \n", "2236 77 2805 64014.0 56 93.1 0.0 \n", "2237 42 2941 56981.0 91 74.6 3.9 \n", "2238 67 2942 69245.0 8 54.7 3.8 \n", "2239 69 3408 52869.0 40 55.6 2.0 \n", "\n", " MeatProducts FishProducts SweetProducts DealsPurchases WebPurchases \\\n", "0 35.7 11.2 5.8 3 36.4 \n", "1 28.6 9.5 4.8 2 25.0 \n", "2 17.3 15.1 2.9 1 40.0 \n", "3 41.7 20.8 6.2 2 33.3 \n", "4 29.0 11.3 6.6 5 35.7 \n", "... ... ... ... ... ... \n", "2235 16.6 3.8 10.8 2 56.2 \n", "2236 6.9 0.0 0.0 7 53.3 \n", "2237 17.8 2.6 1.0 1 11.1 \n", "2238 27.4 10.2 3.8 2 28.6 \n", "2239 40.4 1.3 0.7 3 37.5 \n", "\n", " CatalogPurchases StorePurchases WebVisitsMonth Kids \n", "0 45.5 18.2 7 0 \n", "1 25.0 50.0 5 2 \n", "2 10.0 50.0 4 0 \n", "3 0.0 66.7 6 1 \n", "4 21.4 42.9 5 1 \n", "... ... ... ... ... \n", "2235 18.8 25.0 5 1 \n", "2236 13.3 33.3 7 3 \n", "2237 16.7 72.2 6 0 \n", "2238 23.8 47.6 3 1 \n", "2239 12.5 50.0 7 2 \n", "\n", "[2208 rows x 15 columns]" ] }, "execution_count": 1371, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.read_pickle(os.path.join(path_cleandata,\"clean_marketing.pkl\"))" ] }, { "cell_type": "code", "execution_count": 1372, "metadata": {}, "outputs": [], "source": [ "from sklearn.compose import ColumnTransformer\n", "from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler\n", "\n", "num_columns = marketing_data.select_dtypes(include=[\"int64\", \"float64\"]).columns\n", "\n", "# Build data processing pipeline\n", "ct = ColumnTransformer(\n", " [(\"numerical\", RobustScaler(), num_columns)])\n", "\n", "X = ct.fit_transform(marketing_data)" ] }, { "cell_type": "code", "execution_count": 1373, "metadata": {}, "outputs": [], "source": [ "columns_transform = [col.split(\"__\")[1] for col in ct.get_feature_names_out()]\n", "df_clean = pd.DataFrame(X, columns=columns_transform)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clustering" ] }, { "cell_type": "code", "execution_count": 1374, "metadata": {}, "outputs": [], "source": [ "from sklearn.cluster import KMeans\n", "from sklearn.metrics import silhouette_score\n", "\n", "def clustering_model(X, list_nb_clusters):\n", " dict_labels = dict()\n", " list_scores = []\n", "\n", " for n in list_nb_clusters:\n", " kmeans = KMeans(n_clusters=n, n_init=10)\n", " labels = kmeans.fit_predict(X)\n", " score = silhouette_score(X, labels)\n", " dict_labels[f\"{n} clusters\"] = labels\n", " list_scores.append(score)\n", "\n", " return list_scores, dict_labels" ] }, { "cell_type": "code", "execution_count": 1375, "metadata": {}, "outputs": [], "source": [ "list_nb_clusters = np.arange(2,7)\n", "scores_kmeans, labels_kmeans = clustering_model(X, list_nb_clusters)" ] }, { "cell_type": "code", "execution_count": 1376, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "marketing_data_results = pd.DataFrame({\"nb_clusters\":[str(i) for i in np.arange(2,7)], \"scores\":scores_kmeans})\n", "\n", "sns.lineplot(data=marketing_data_results, x=\"nb_clusters\", y=\"scores\", marker=\"o\")\n", "plt.xlabel(\"number of clusters\")\n", "plt.ylabel(\"silhouette score\")\n", "plt.title(\"Silhouette score of Kmeans\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Save results" ] }, { "cell_type": "code", "execution_count": 1377, "metadata": {}, "outputs": [], "source": [ "import os\n", "path_results = r\"C:\\Users\\LaurèneDAVID\\Documents\\Teaching\\Educational_apps\\app-hec-AI-DS\\data\\clustering\\results\"\n", "\n", "for nb_clusters in list_nb_clusters:\n", " labels_ = labels_kmeans[f\"{nb_clusters} clusters\"] # chosen labels\n", " marketing_data_labels = marketing_data.copy()\n", " marketing_data_labels[\"Group\"] = labels_\n", " marketing_data_labels[\"Group\"] = marketing_data_labels[\"Group\"].astype(int)\n", "\n", " df_mean_results = marketing_data_labels.groupby(\"Group\")[num_columns].mean().reset_index()\n", " df_mean_results = df_mean_results.round(1).melt(id_vars=[\"Group\"])\n", " df_mean_results = pd.pivot_table(df_mean_results, values='value', index=['variable'], columns=[\"Group\"])\n", "\n", " df_mean_results.to_pickle(os.path.join(path_results,f\"results_{nb_clusters}_clusters.pkl\"))" ] } ], "metadata": { "kernelspec": { "display_name": "venv", "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.9.0" } }, "nbformat": 4, "nbformat_minor": 2 }