In [ ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
In [ ]:
df = pd.read_csv('sephora_customers.csv')
df.head()
Out[ ]:
| in_store_spending | online_spending | VIP_status | age | |
|---|---|---|---|---|
| 0 | 102.24 | 138.06 | Insider | 56 |
| 1 | 171.18 | 59.15 | Insider | 69 |
| 2 | 459.74 | 167.40 | VIB | 46 |
| 3 | 470.12 | 281.83 | VIB | 32 |
| 4 | 370.24 | 394.74 | VIB | 60 |
In [ ]:
df['VIP_status'].value_counts()
Out[ ]:
| count | |
|---|---|
| VIP_status | |
| VIB | 299 |
| Insider | 151 |
| Rough | 50 |
In [ ]:
df['VIP_encoded'] = df['VIP_status'].replace({'Rough': 3, 'VIB': 2, 'Insider': 1})
df.head()
/tmp/ipython-input-1141706186.py:1: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
df['VIP_encoded'] = df['VIP_status'].replace({'Rough': 3, 'VIB': 2, 'Insider': 1})
Out[ ]:
| in_store_spending | online_spending | VIP_status | age | VIP_encoded | |
|---|---|---|---|---|---|
| 0 | 102.24 | 138.06 | Insider | 56 | 1 |
| 1 | 171.18 | 59.15 | Insider | 69 | 1 |
| 2 | 459.74 | 167.40 | VIB | 46 | 2 |
| 3 | 470.12 | 281.83 | VIB | 32 | 2 |
| 4 | 370.24 | 394.74 | VIB | 60 | 2 |
In [ ]:
#rescale data
features =df[['in_store_spending', 'online_spending', 'age', 'VIP_encoded']]
features.head()
Out[ ]:
| in_store_spending | online_spending | age | VIP_encoded | |
|---|---|---|---|---|
| 0 | 102.24 | 138.06 | 56 | 1 |
| 1 | 171.18 | 59.15 | 69 | 1 |
| 2 | 459.74 | 167.40 | 46 | 2 |
| 3 | 470.12 | 281.83 | 32 | 2 |
| 4 | 370.24 | 394.74 | 60 | 2 |
In [ ]:
#normalize data
scaler = StandardScaler()
nor_features = scaler.fit_transform(features)
nor_features_df = pd.DataFrame(nor_features, columns=features.columns)
nor_features_df.head()
Out[ ]:
| in_store_spending | online_spending | age | VIP_encoded | |
|---|---|---|---|---|
| 0 | -1.208583 | -0.630679 | 0.784233 | -1.327796 |
| 1 | -0.904988 | -1.124943 | 1.649686 | -1.327796 |
| 2 | 0.365758 | -0.446904 | 0.118500 | 0.336109 |
| 3 | 0.411469 | 0.269844 | -0.813526 | 0.336109 |
| 4 | -0.028378 | 0.977072 | 1.050527 | 0.336109 |
In [ ]:
# apply k-means
kmeans = KMeans(n_clusters=3, random_state=42)
nor_features_df['cluster'] = kmeans.fit_predict(nor_features_df)
nor_features_df.head()
Out[ ]:
| in_store_spending | online_spending | age | VIP_encoded | cluster | |
|---|---|---|---|---|---|
| 0 | -1.208583 | -0.630679 | 0.784233 | -1.327796 | 1 |
| 1 | -0.904988 | -1.124943 | 1.649686 | -1.327796 | 1 |
| 2 | 0.365758 | -0.446904 | 0.118500 | 0.336109 | 0 |
| 3 | 0.411469 | 0.269844 | -0.813526 | 0.336109 | 0 |
| 4 | -0.028378 | 0.977072 | 1.050527 | 0.336109 | 0 |
In [ ]:
fig=plt.figure(figsize=(5,5))
ax= fig.add_subplot(projection='3d')
scatter = ax.scatter(nor_features_df['in_store_spending'], nor_features_df['online_spending'],
nor_features_df['VIP_encoded'], c=nor_features_df['cluster'],
cmap='jet')
legend = ax.legend(*scatter.legend_elements(), title='clusters')
ax.add_artist(legend)
ax.set_xlabel('in_store_spending')
ax.set_ylabel('online_spending')
ax.set_zlabel('VIP_encoded')
#plt.colorbar(scatter)
plt.show()
In [ ]: