#!/usr/bin/env python
# coding: utf-8

# In[1]:


import numpy as np


# In[2]:


import pandas as pd


# In[3]:


import matplotlib.pyplot as plt


# In[4]:


import seaborn as sns


# In[5]:


import datetime as dt


# In[6]:


import sklearn


# In[7]:


from sklearn.preprocessing import StandardScaler


# In[8]:


from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import dendrogram
from scipy.cluster.hierarchy import cut_tree


# In[9]:


retail = pd.read_csv("online_retail.csv", sep=",", encoding="ISO-8859-1", header=0)
retail.head()


# In[10]:


retail.shape


# In[11]:


retail.info()


# In[12]:


retail.describe()


# In[13]:


df_null = round(100*(retail.isnull().sum())/len(retail), 2)


# In[14]:


df_null


# In[15]:


retail = retail.dropna()


# In[16]:


retail.shape


# In[19]:


max_date = max(retail['InvoiceDate'])
max_date


# In[25]:


retail['Customer ID'] = retail['Customer ID'].astype(str)


# In[28]:


retail['Amount'] = retail['Quantity']*retail['Price']
rfm_m = retail.groupby('Customer ID')['Amount'].sum()
rfm_m = rfm_m.reset_index()
rfm_m.head()


# In[30]:


rfm_f = retail.groupby('Customer ID')['Invoice'].count()
rfm_f = rfm_f.reset_index()
rfm_f.columns = ['Customer ID', 'Frequency']
rfm_f.head()


# In[32]:


rfm = pd.merge(rfm_m, rfm_f, on='Customer ID', how='inner')
rfm.head()


# In[39]:


retail['InvoiceDate'] = pd.to_datetime(retail['InvoiceDate'],format='%Y-%m-%d %H:%M')


# In[40]:


max_date = max(retail['InvoiceDate'])
max_date


# In[41]:


retail['Diff'] = max_date - retail['InvoiceDate']
retail.head()


# In[43]:


rfm_p = retail.groupby('Customer ID')['Diff'].min()
rfm_p = rfm_p.reset_index()
rfm_p.head()


# In[44]:


rfm_p['Diff'] = rfm_p['Diff'].dt.days
rfm_p.head()


# In[45]:


rfm = pd.merge(rfm, rfm_p, on='Customer ID', how='inner')
rfm.columns = ['Customer ID', 'Amount', 'Frequency', 'Recency']
rfm.head()


# In[46]:


attributes = ['Amount','Frequency','Recency']
plt.rcParams['figure.figsize'] = [10,8]
sns.boxplot(data = rfm[attributes], orient="v", palette="Set2" ,whis=1.5,saturation=1, width=0.7)
plt.title("Outliers Variable Distribution", fontsize = 14, fontweight = 'bold')
plt.ylabel("Range", fontweight = 'bold')
plt.xlabel("Attributes", fontweight = 'bold')


# In[47]:


Q1 = rfm.Amount.quantile(0.05)
Q3 = rfm.Amount.quantile(0.95)
IQR = Q3 - Q1
rfm = rfm[(rfm.Amount >= Q1 - 1.5*IQR) & (rfm.Amount <= Q3 + 1.5*IQR)]

# Removing (statistical) outliers for Recency
Q1 = rfm.Recency.quantile(0.05)
Q3 = rfm.Recency.quantile(0.95)
IQR = Q3 - Q1
rfm = rfm[(rfm.Recency >= Q1 - 1.5*IQR) & (rfm.Recency <= Q3 + 1.5*IQR)]

# Removing (statistical) outliers for Frequency
Q1 = rfm.Frequency.quantile(0.05)
Q3 = rfm.Frequency.quantile(0.95)
IQR = Q3 - Q1
rfm = rfm[(rfm.Frequency >= Q1 - 1.5*IQR) & (rfm.Frequency <= Q3 + 1.5*IQR)]


# In[48]:


rfm_df = rfm[['Amount', 'Frequency', 'Recency']]


# In[49]:


scaler = StandardScaler()


# In[50]:


rfm_df_scaled = scaler.fit_transform(rfm_df)
rfm_df_scaled.shape


# In[51]:


rfm_df_scaled = pd.DataFrame(rfm_df_scaled)
rfm_df_scaled.columns = ['Amount', 'Frequency', 'Recency']
rfm_df_scaled.head()


# In[52]:


kmeans = KMeans(n_clusters=4, max_iter=50)
kmeans.fit(rfm_df_scaled)


# In[53]:


kmeans.labels_


# In[54]:


ssd = []
range_n_clusters = [2, 3, 4, 5, 6, 7, 8]
for num_clusters in range_n_clusters:
    kmeans = KMeans(n_clusters=num_clusters, max_iter=50)
    kmeans.fit(rfm_df_scaled)
    
    ssd.append(kmeans.inertia_)


# In[55]:


plt.plot(ssd)


# In[58]:


kmeans = KMeans(n_clusters=num_clusters, max_iter=50)
    kmeans.fit(rfm_df_scaled)
    
    cluster_labels = kmeans.labels_
    
    # silhouette score
    silhouette_avg = silhouette_score(rfm_df_scaled, cluster_labels)
    print("For n_clusters={0}, the silhouette score is {1}".format(num_clusters, silhouette_avg))


# In[57]:


range_n_clusters = [2, 3, 4, 5, 6, 7, 8]


# In[65]:


kmeans = KMeans(n_clusters=num_clusters, max_iter=50)
    


# In[67]:


kmeans.fit(rfm_df_scaled)
    
    


# In[69]:


cluster_labels =  kmeans.labels_
    
  


# In[70]:



    silhouette_avg = silhouette_score(rfm_df_scaled, cluster_labels)
    print("For n_clusters={0}, the silhouette score is {1}".format(num_clusters, silhouette_avg))


# In[71]:


kmeans = KMeans(n_clusters=3, max_iter=50)
kmeans.fit(rfm_df_scaled)


# In[72]:


kmeans.labels_


# In[73]:


rfm['Cluster_Id'] = kmeans.labels_
rfm.head()


# In[74]:


sns.boxplot(x='Cluster_Id', y='Amount', data=rfm)


# In[75]:


sns.boxplot(x='Cluster_Id', y='Frequency', data=rfm)


# In[ ]:




