본문 바로가기
IT, Software/Python

Python 데이터 분석 콘텐츠 추천 - KMeans Clustering

by 기타마을이장 2020. 10. 14.

첫단계에서 json을 파싱해서 내가 필요한 데이터를 찾아서 쌓을 수있는 준비가 되었고,

두번째 단계로 Pandas로 1차 가공 데이터를 만들었으니 이제 Clustering을 해본다.

 

1. 서버내 여러 사용자들이 페이지를 방문한 기록들을 json형태로 저장해둔 로그파일에서 파싱한 뒤

 

2. 각 사용자들별로 몇 번의 방문이 있었는지, 머문 시간은 얼마나 되는지를 Pandas로 데이터화한 뒤

1차 가공된 데이터를 기반으로 유사성향의 사용자들을 분류하기 위한 클러스터링을 수행하고자 한다.

 

3. 그리고 특정 사용자가 접속했을때, 해당 사용자가 속해 있는 고객군 내에서 다른 사용자들이 이용한 콘텐츠를

추천해주려는 것이 최족 목표이다.


Pandas Pivot Matrix 만들기 - pivot_table 함수

로그 파싱을 통해 Pandas로 1차 데이터를 생성해본 결과는 그렇게 해서 나온 결과물은 아래와 같다.

사용자별로 조회한 페이지 번호와 누적 조회건수, 누적 조회시간을 계산해서 저장해 뒀다.

user page cnt usetime
0 100537 18134

2.0

45.000000

1

100537

21545

4.0

32.500000

2

100537

17473

1.0

0.000000

...

...

...

...

...

106730

222624

23316

4.0

1224.000000

106732

222625

20144

1.0

0.000000

106733

222626

18134

1.0

0.000000

81593 rows × 4 columns

이제 본격적으로 각 사용자별로 이용한 페이지를 기반으로 사용자별 Clustering을 해보려고 한다.

이렇게 하면 사용자별로 방문한 페이지를 기초로 Clustering이 될것으로 예상했다.

 

Pandas는 Pivot 이라는 기능을 통해 위와 같은 Row Data에서

X축과 Y축을 지정하고 X/Y 축에 따른 Value 값을 뽑아낼 수 있도록 기능을 제공하고 있다.

(만들려는 Clustering용 데이터 형태는 사용자 x 페이지 Matrix 이다.)

 

방법은 매우 간단하다. Pandas의 pivot_table 함수를 활용하면 된다.

df.pivot_table(index='user', columns='page', values='usetime')
df.fillna(0, inplace=True)
df

그럼 아래와 같은 Matrix가 생성된다.

Clustering을 하고자하는 경우의 데이터 분석주제에서 자주 보이는 Matrix 형태. Sparce Vector가 생성되었다.

먼가 될거 같은 느낌이 든다ㅎㅎ

  user 10494 10500 10501 10510 ... 255330 255334 25347 25360 25364
5944 222577 0.0 0.0 0.0 0.0 ... 0.0 221.28 0.0 0.0 0.0
5945 222592 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
5946 222617 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
5947 222623 0.0 0.0 0.0 0.0 ... 0.0 258.33 0.0 0.0 0.0

 

 

KMeans로 Clustering 해보기

이제 위에서 만들어낸 Vector로 유사고객군을 Clustering 해보자.

Clustering은 가장 널리 알려진 KMeans를 사용했다.

적정한 Clustering 수를 파악하기 위해서 inertias 측정을 해봤다.

문제는...구글링을 통해 본 사례들처럼 먼가 명확한 변곡점이 보이지 않는다ㅠ

mnist 샘플링같은 걸로 Clustering을 하면 예쁜 변곡점이 보이지만 아무래도 이번 분석데이터는 그렇지 못한거 같다.

cluster_num = 10

model = KMeans(n_clusters=cluster_num)
model.fit(df)
df['clusterSeq'] = model.labels_

그래서 1차 변곡점으로 보여지는 10개로 Clustering을 시도해본다.

각 사용자별 그리고 Clustering 된 정보를 Matrix의 clusterSeq라는 Column으로 추가해준다.

 

데이터 시각화하기 - Plotly 3D Scatter

마지막으로 결과를 보기 위해서,

위에서 생성산 Matrix를 TSNE를 사용해서 3차원으로 축소하고 Clustering 번호를 붙여서 3차원 그래프를 그려봤다.

시각화를 위해서는 널리 사용중인 plotly 라이브러리를 사용했다.

 

import plotly.express as px

pca = TSNE(n_components = 3).fit_transform(df)
userPos = pd.DataFrame(columns=["userSeq", "clusterSeq", "x", "y", "z"])
userPos['size'] = 2
userPos['x'] = pca[:,0]
userPos['y'] = pca[:,1]
userPos['z'] = pca[:,2]

init_notebook_mode()

fig = px.scatter_3d(userPos, x='x', y='y', z='z', size='size',
              color='clusterSeq', symbol='clusterSeq', opacity=0.7)
fig.show()

Clustering 결과를 출력해봤다. 기대했던 예쁘게 분류된 그런 모양이 아니다ㅠ

 

결론

결과는...기대와 다르게 특정 Cluster로 쏠림현상이 발생했다;;; 아무래도 전략수정이 필요해보인다ㅠ

특정 Cluster 쏠린거만 제거하고 그래프를 그리니 참 예쁜 그림이 나오는데 쏠림현상이 너무 극심하고,

해당 Cluster내의 사용자들의 이용패턴도 특정지어 얘기하기 어렵게 골고루 분포되어 있었다.

(비슷한 특성의 사용자들끼리 잘 Clustering 이 되어야

이후 각 Cluster 내에서 다른 사용자간 콘텐츠 추천을 해줄 수 있을텐데 현 상태로는 어려울 것 같다)

 

원인을 추측해보건데

대부분의 사용자들이 한두개 페이지만 머물다 나가다보니

이 사용자들의 데이터가 Clustering을 명확히 하는데 어려움을 준것 같다. 어디까지나 추측이다;;;

아무래도 Clustering을 하기 위한 Matrix Value에

이런저런 가중치를 더해서 좀 더 사용자별로 특성을 명확히 표현해야할 것 같다.

(예를들면, 성별이라던지, 나이대, 접속한 시간대 등)

 

결국...이번에 해본 접근방법이 내가 당초 계획했던 것과는 다르게 결론이 난것 같다.

다른 방식으로 다시...시작해보자ㅠ

그래도 의미있는 실패의 결험을 쌓았다고 스스로 만족해본다;;;

반응형

댓글