# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly as py

import plotly.graph_objs as go
from sklearn.cluster import KMeans

from scipy.cluster.hierarchy import linkage, dendrogram
from sklearn.cluster import AgglomerativeClustering

import warnings
import os
#çalışma dizinimiz.
print(os.listdir("../input"))
# We read the data.
data = pd.read_csv('../input/customer-segmentation-tutorial-in-python/Mall_Customers.csv')
data.head()
data.shape
data.info()
data.describe()
data.dtypes
print(pd.isnull(data).sum())
data.corr()
plt.figure(figsize=(4,4))
sns.heatmap(data.corr(),annot=True)
plt.show()
sns.pairplot(data)
plt.show()
labels=['Male','Female']
sizes=[data.query('Gender=="Male"').Gender.count(),data.query('Gender=="Female"').Gender.count()]
explode = [0, 0.1]
colors = ['#12b3ff','#ffaaB9']
plt.pie(sizes,labels=labels,colors=colors,explode=explode,shadow = False, autopct = '%.2f%%')
plt.show()
plt.figure(figsize=(15,4))
sns.countplot(data.Age)
plt.xlabel('Age')
plt.ylabel('Number of People')
plt.show()
plt.figure(1 , figsize = (15 , 6))
for gender in ['Male' , 'Female']:
    plt.scatter(x = 'Age' , y = 'Annual Income (k$)' , data = data[data['Gender'] == gender] ,
                s = 200 , alpha = 0.5 , label = gender)
plt.xlabel('Age'),
plt.ylabel('Annual Income') 
plt.title('Age vs Annual Income')
plt.legend()
plt.show()
plt.figure(figsize=(20,7))
gender = ['Male', 'Female']
for i in gender:
    plt.scatter(x='Age',y='Spending Score (1-100)', data=data[data['Gender']==i],s = 200 , alpha = 0.5 , label = i)
plt.legend()
plt.xlabel("Age")
plt.ylabel("Spending Score (1-100)")
plt.title("Spending Score According to Age")
plt.show()
plt.figure(1 , figsize = (15 , 7))
n = 0 
for cols in ['Age' , 'Annual Income (k$)' , 'Spending Score (1-100)']:
    n += 1 
    plt.subplot(1 , 3 , n)
    plt.subplots_adjust(hspace = 0.5 , wspace = 0.5)
    sns.violinplot(x = cols , y = 'Gender' , data = data, palette = 'vlag')
    sns.swarmplot(x = cols , y = 'Gender' , data = data)
    plt.ylabel('Gender' if n == 1 else '')
    plt.title('Boxplots & Swarmplots' if n == 2 else '')
plt.show()
#We have determined that we will use the attributes in columns 2 through 4.
X=data.iloc[:, [2,4]].values
"""
**Elbow Method**
"""
# We use the bracket method to find the number of clusters.
#For this, we must first find WCSS(the within​-cluster sum of squares).
#We will calculate the variation of WCSS with the number of clusters.
#WCSS(the sum of the squares of the distances of each data point in all clusters from their respective center pointsı)


# We create an empty list.
wcss = []
#For the number of clusters, we create an increasing list from 1 to 10 with the range() function.
for i in range(1,11):
    #K-means sınıfından bir nesne üretiyoruz.
    kmeans = KMeans(n_clusters= i, max_iter = 300, init='k-means++', n_init = 10, random_state=0)
    #Kümeleme işlemi yap
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)
#While creating an object we are sending some parameters to the constructor function (__init__).
#The first of these is n_clusters, which is the number of clusters.
#The for loop gives the number of clusters as a parameter to n_clusters, increasing by one each time it returns with the variable i. 
#The init parameter specifies the ideal cluster centers to select the starting points.
#The kmeans++ parameter saves us from the random initialization trap, it allows us to choose good starting points.
#The next parameter max_iter determines the maximum number of iterations the algorithm can take to reach its final state, the default is 300.
#n_init determines how many different points the cluster center starting point can start from.
#The last parameter, random_state, ensures that anyone who executes these operations will get the same results. 
#After the object is created, we perform the data fit with the object with the fit() method.
#We give the X that we created earlier as a parameter.
#We add the inerita_ property of the kmeans object to the wcss list we created before the for loop.  
plt.figure(figsize=(10,3))
plt.plot(range(1,11),wcss)
plt.xlabel("number of k (cluster) value")
plt.ylabel("wcss")
plt.show()
"""
**K-Means**
"""

#We see from the chart that the ideal number of clusters would be 4. Now we repeat the working line for the set number 5 in the for loop.
#We are creating an object of class K-means.
kmeansmodel = KMeans(n_clusters= 4, init='k-means++', max_iter = 300, n_init = 10, random_state=0)


#Cluster and predict
y_kmeans= kmeansmodel.fit_predict(X)


# We have determined the cluster center points.
centroids1 = kmeansmodel.cluster_centers_

# Shows clusters on graph
plt.scatter(X[y_kmeans == 0, 0], X[y_kmeans == 0, 1], s = 100, label = 'Cluster 1')
plt.scatter(X[y_kmeans == 1, 0], X[y_kmeans == 1, 1], s = 100, c = 'blue', label = 'Cluster 2')
plt.scatter(X[y_kmeans == 2, 0], X[y_kmeans == 2, 1], s = 100, label = 'Cluster 3')
plt.scatter(X[y_kmeans == 3, 0], X[y_kmeans == 3, 1], s = 100, label = 'Cluster 4')

plt.scatter(x = centroids1[: , 0] , y =  centroids1[: , 1] , s = 300 , c = 'yellow' , alpha = 0.8)
plt.title('Clusters of Customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')

plt.legend()
plt.show()
x = data[['Age', 'Spending Score (1-100)', 'Annual Income (k$)']].values
km = KMeans(n_clusters = 5, init = 'k-means++', max_iter = 300, n_init = 10, random_state = 0)
km.fit(x)
labels = km.labels_
centroids = km.cluster_centers_
import plotly.offline as py
from plotly.offline import init_notebook_mode, iplot

data['labels'] =  labels
trace1 = go.Scatter3d(
    x= data['Age'],
    y= data['Spending Score (1-100)'],
    z= data['Annual Income (k$)'],
    mode='markers',
     marker=dict(
        color = data['labels'], 
        size= 10,
        line=dict(
            color= data['labels'],
            width= 12
        ),
        opacity=0.8
     )
)
df = [trace1]

layout = go.Layout(
    title = 'Character vs Gender vs Alive or not',
    margin=dict(
        l=0,
        r=0,
        b=0,
        t=0  
    ),
    scene = dict(
            xaxis = dict(title  = 'Age'),
            yaxis = dict(title  = 'Spending Score'),
            zaxis = dict(title  = 'Annual Income')
        )
)

fig = go.Figure(data = df, layout = layout)
py.iplot(fig)
# We imported the AgglomerativeClustering class
from sklearn.cluster import AgglomerativeClustering
# We generated an object from AgglomerativeClustering class
# n_clusters = Number of clusters we will allocate
# linkage and affinity = distance measurement methods
# Changing the linkage and affinity parameters affects the success rate.
ag=AgglomerativeClustering(n_clusters=4,affinity='euclidean',linkage='ward')

#Make clustering and prediction
predict=ag.fit_predict(x)
# Dendogram graph display
import scipy.cluster.hierarchy as sch
# x = our data
# method = We give the same parameter as the linkage parameter of AgglomerativeClustering. ( 'ward' )
dendrogram=sch.dendrogram(sch.linkage(x,method='ward'))
plt.show()