투빅스 11기&12기 4주차 Clustering - 12기 신윤종

by yj posted Aug 17, 2019
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

+ - Up Down Comment Print
※ HTML파일 링크 : http://www.datamarket.kr/xe/?module=file&act=procFileDownload&file_srl=59999&sid=b29a647f6d3a1e3134d03642826c86b6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/env python
# coding: utf-8
 
# In[67]:
 
 
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import metrics
import warnings
warnings.filterwarnings("ignore", category=RuntimeWarning) 
 
 
# In[2]:
 
 
data = pd.read_csv('Mall_Customers.csv')
data.head()
 
 
# In[3]:
 
 
data.info()
 
 
# In[4]:
 
 
data.describe()
 
 
# * 감사히도 결측치는 없고 성별, 나이, 소득, 지출 점수를 가지고 클러스터링을 할 수 있을 것 같아요
 
# In[5]:
 
 
data = data.drop(columns=['CustomerID'])
sns.pairplot(data, hue="Gender")
plt.show()
 
 
# * ID는 필요없으므로 삭제했고 성별에 따라 분포를 보았는데 큰 차이는 없어보입니다.
 
# In[6]:
 
 
data['Gender'].replace(['Male','Female'],[0,1],inplace=True)
sns.heatmap(data.corr(),annot=True,linewidths=0.2
fig=plt.gcf()
plt.show()
 
 
# * ID는 빼는게 맞아보입니다.
# * 나이가 많을 수록 지출이 많을 줄 알았는데 그 것은 또 아니네요
 
# ## Hierarchical agglomerative clustering 
 
# In[7]:
 
 
= data[['Annual Income (k$)','Spending Score (1-100)']]
X.head()
 
 
# In[8]:
 
 
import scipy.cluster.hierarchy as sch
dendrogram = sch.dendrogram(sch.linkage(X, method = 'ward'))
plt.title('ward method')
plt.xlabel('고객')
plt.ylabel('유클리디안 거리')
plt.show()
 
 
# In[9]:
 
 
dendrogram = sch.dendrogram(sch.linkage(X, method = 'centroid'))
plt.title('centroid method')
plt.xlabel('고객')
plt.ylabel('유클리디안 거리')
plt.show()
 
 
# * centroid 방식이 더 복잡해보입니다.
 
# ## 평가
# * Davies_bouldin_score: 높은 클러스터 내 유사도를 가지고 낮은 클러스터간 유사도를 가지는 클러스터들을 생성하는 클러스터링 알고리즘은 낮은 index 값을 가지게 된다. 따라서, 이 지표가 낮은 클러스터링 알고리즘이 좋은 클러스터링 알고리즘으로 평가된다.
# * Silhouette Coefficient: 1에 가까울 수록 데이터 데이터 i 는 올바른 클러스터에 분류된 것이며, -1에 가까울 수록 잘못된 클러스터에 분류되었음을 나타낸다.
 
# ## Agglomerative clustering
 
# In[59]:
 
 
from sklearn import metrics
from sklearn.cluster import AgglomerativeClustering
 
li = [2,5,8]
for i in li:
    agg = AgglomerativeClustering(n_clusters=i, affinity='euclidean', linkage='ward').fit(X)
    labels = agg.labels_
    plt.scatter(X['Annual Income (k$)'],X['Spending Score (1-100)'], c=labels, cmap='rainbow')
    plt.show()
    
    print('Silhouette Coefficient: ', metrics.silhouette_score(X, labels, metric='euclidean'))
    print('Davies_bouldin_score: ', metrics .davies_bouldin_score(X, labels))
 
 
# * 클러스터 개수를 하이퍼 파라미터로 지정해줄 수 있습니다. 5가 가장 평가지표가 좋네요
 
# ## K-Means
 
# In[12]:
 
 
from sklearn.cluster import KMeans
inertias = []
for i in range(120):
    kmeans = KMeans(n_clusters = i, init = 'k-means++')
    kmeans.fit(X)
    inertias.append(kmeans.inertia_)
plt.plot(range(120), inertias)
plt.xlabel('cluster number')
plt.ylabel('inertias')
plt.show()
 
 
# * 5가 elbow point로 가장 이상적인 개수로 보입니다.
 
# In[61]:
 
 
kmeans = KMeans(n_clusters = 5, init = 'k-means++', random_state = 42)
kmeans.fit(X)
label = kmeans.labels_
y_kmeans = kmeans.predict(X)
centers = kmeans.cluster_centers_
plt.scatter(X['Annual Income (k$)'],X['Spending Score (1-100)'], c=y_kmeans, s=50, cmap='viridis')
plt.scatter(centers[:, 0], centers[:, 1], c='black', s=200, alpha=0.5)
 
 
print('Silhouette Coefficient: ', metrics.silhouette_score(X, label, metric='euclidean'))
print('Davies_bouldin_score: ', metrics .davies_bouldin_score(X, label))
 
 
# ## Mean-Shift
 
# In[62]:
 
 
from sklearn.cluster import MeanShift, estimate_bandwidth
li = [10,100,500]
for i in li:
    bandwidth = estimate_bandwidth(X, quantile=0.2, n_samples=i)
    ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
    ms.fit(X)
    labels = ms.labels_
    cluster_centers = ms.cluster_centers_
 
    plt.scatter(X['Annual Income (k$)'],X['Spending Score (1-100)'], c=labels, s=50, cmap='viridis')
    plt.scatter(cluster_centers[:, 0], cluster_centers[:, 1], c='black', s=200, alpha=0.5);
    plt.show()
    
    print('Silhouette Coefficient: ', metrics.silhouette_score(X, labels, metric='euclidean'))
    print('Davies_bouldin_score: ', metrics .davies_bouldin_score(X, labels))
 
 
# * Mean Shift는 어떤 데이터 분포의 peak 또는 무게중심을 찾는 한 방법으로서, 현재 자신의 주변에서 가장 데이터가 밀집된 방향으로 이동한다. 그러다 보면 언젠가는 분포 중심을 찾을 수 있을 거라는 방법이다. 
# * bandwidth = distance/size scale of the kernel function
# * estimate_bandwith로 파라미터에 따라 클러스터 수를 결정해주고 있습니다. 
 
# ## DBSCAN
 
# In[68]:
 
 
from sklearn.cluster import DBSCAN
li = [2,5,10,15]
for i in li:
    db = DBSCAN(eps=i, min_samples=5).fit(X)
    cluster = db.fit_predict(X)
    label = db.labels_
    plt.scatter(x = X['Annual Income (k$)'],y = X['Spending Score (1-100)'], c=cluster)
    plt.xlabel("Annual Income")
    plt.ylabel("Spending Score")
    plt.show()
    
    print('Silhouette Coefficient: ', metrics.silhouette_score(X, label, metric='euclidean'))
    print('Davies_bouldin_score: ', metrics .davies_bouldin_score(X, label))
 
 
# * eps를 어떻게 정하느냐에 따라 상당히 다른 모습을 보이고 있습니다.
 
cs

Articles

2 3 4 5 6 7 8 9 10 11

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5