일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 전처리
- GA4
- 팀프로젝트
- 기초통계
- 군집화
- 크롤링
- 데이터 분석
- jd
- If
- 기초프로젝트
- streamlit
- data analyst
- SQLD
- 히트맵
- 머신러닝
- SQL
- 프로젝트
- 프롬프트 엔지니어링
- cross join
- 서브쿼리
- 데이터분석
- 태블로
- Python
- lambda
- 시각화
- 최종 프로젝트
- Chat GPT
- 클러스터링
- pandas
- da
- Today
- Total
세조목
최종 프로젝트 22일차(24.04.19) 본문
최종 프로젝트 22일차입니다.
금일은 클러스터링 분석 작업을 진행했습니다.
어제 포스팅에서 저희가 정한 기준에 따라서 컬럼을 삭제해가면서
실험해보겠다고 했는데요,
2024.04.18 - [데이터 분석 공부/프로젝트] - 최종 프로젝트 21일차(24.04.18)
팀원들 모두 진행하는 방식이 조금씩 상이했습니다.
저의 경우 한 개 컬럼을 제거하고,
그 데이터셋을 가지고서 K-means 군집화를 한 후
그 결과값을 가지고서 Radar plot을 그려서 군집화가 제대로 이루어졌는지를 확인했는데
다른 팀원들의 경우 군집화를 한 후, 이를 시각화하기위해서 PCA를 추가적으로 진행했습니다.
그 중에서 한 명은 두 개 컬럼만 남긴 데이터셋으로 바로 PCA를 진행했고,
나머지 한 명은 PCA를 총 두 번(ex. 초기 군집화 時 한 번, 시각화하기위해 한 번) 돌렸습니다.
저희는 PCA를 하기로한게 아닌데 왜 PCA를 했는지가 의아하긴했습니다.
두 개 컬럼만 남긴 데이터셋으로 PCA를 진행한 경우는 이해가 되는데
PCA를 두 번 돌린 경우는 이해가 잘 안 됐습니다.
왜냐하면 차원을 한 번 축소해서 결과값을 확인했는데
여기서 한 번 더 PCA를 진행하면 기존 결과값이 어그러진다고 생각했기 때문입니다.
* 나중에 확인 결과 현업에서는 이런식으로 시각화를 위해 PCA를 한 번 더 진행하는 것이 일반적이라고 들었습니다.
관련해서 팀원들과 계속 얘기 나눈 결과 그러면 처음부터 PCA를 하고 군집화를 진행하자는 쪽으로
의견이 모아졌습니다.
우선 몇 개의 차원으로 축소해야 할 지 판단해야했으므로
차원별 분산보존율을 확인했습니다.
아래 첫번째 이미지에서 확인할 수 있는 것처럼
차원을 축소했을 때 각 차원이 기존 데이터의 분산을 얼마나 보존하고 있는지를 확인할 수 있는데요,
각 비율을 모두 더했을 때 90% 이상 정도가 나오면 기존 분산을 잘 보존하고 있다고 볼 수 있습니다.
그래서 각 차원별 분산 보존율을 확인해본 결과 5차원 이상 10차원 이하에서 정해야할 것 같았습니다.
결과적으로 저희가 정한 차원은 6개의 차원이었는데 그 이유는
차원이 높아질수록 보존율이 높아지는 것은 맞지만 저희가 가지고 있는 데이터셋의 특성상
리뷰별 특성이 그렇게까지 명확하지 않으므로 차원을 높일 경우 데이터들이 흩어져서
군집화가 제대로 이루어지지 않을 것이라고 판단했기 때문입니다.
# 차원별 분산보존율
column = []
sum = 0
for a in range(2, 21):
for b in range(a):
column.append(f'pc{b}')
pca = PCA(n_components=a)
df_anal_pca = pd.DataFrame(data = pca.fit_transform(df_anal), columns = column)
column = []
for c in range(len(pca.explained_variance_ratio_)):
sum+=pca.explained_variance_ratio_[c]
print(f'{a}차원의 분산 보존율은 {sum}입니다.')
sum = 0
6개의 차원으로 축소시킨 후 k-means 클러스터링을 진행했고,
radar plot을 그리기위해 중심점을 잡아주었습니다.
# 차원 축소
pca = PCA(n_components=6)
df_anal_pca = pd.DataFrame(data = pca.fit_transform(df_anal), columns = ['pc1', 'pc2', 'pc3', 'pc4', 'pc5', 'pc6'])
# k-means 클러스터링
kmeans = KMeans(n_clusters=6, random_state=0).fit(df_anal_pca)
# radar plot을 그리기위한 별도의 데이터프레임 생성
df_centroids = pd.DataFrame(kmeans.cluster_centers_, columns = df_anal_pca.columns)
df_centroids
이를 가지고서 radar plot을 그렸습니다.
from collections import Counter
import plotly.graph_objects as go
# 군집별 데이터 개수 카운팅
c = Counter()
c.update(kmeans.labels_) # kmeans.labels_에 있는 레이블의 등장 횟수를 c에 추가함(딕셔너리 형태)
c
# radar plot 그리기
def plot_radar_from_centroid(df_centroids):
fig = go.Figure()
categories = df_centroids.columns
for row in df_centroids.iterrows():
fig.add_trace(go.Scatterpolar(
r=row[1].tolist(),
theta=categories,
fill='toself',
name='cluster {}'.format(row[0])
))
fig.update_layout(
autosize=False,
width=1000,
height=800,
)
fig.show()
plot_radar_from_centroid(df_centroids)
이렇게 군집이 이루어졌는데요,
위 plot은 차원 6개 군집 6개일 때의 plot입니다.
차원은 앞서 말씀드린것과 같이 5개와 10개 사이에서 고민했으나
데이터 특성상 차원이 너무 많아지면 데이터가 흩어져서 군집화하기가 힘들 것 같았기에 6개 정도로 추렸고,
군집의 경우 실무 경험이 많으신 튜터님의 의견을 적극 반영하여 6개로 정했습니다.
튜터님의 말씀을 들어보니 일반적으로 4개에서 6개 정도로 군집을 많이 설정한다고 하셨습니다.
그래서 군집 4, 차원 6 / 군집 5, 차원 6 / 군집 6, 차원 6 으로 radar plot을 돌려보았을 때
가장 군집이 잘 이루어졌다고 판단되었던 군집 6, 차원 6을 최종 선정했습니다.
차원과 군집이 정해졌고, radar plot까지 그려봤으니
이제 각 군집이 어떠한 특성을 가지고 있는지 확인할 필요가 있었습니다.
그러려먼 우선 각 차원이 어떤 특성을 가지고 있는지를 확인해야했습니다.
# 주성분과 feature간의 관계 확인
pca_com = pca.components_
pca_comdf = pd.DataFrame(pca_com, columns = df_anal.columns, index=[f'pca{idx+1}' for idx in range(pca_com.shape[0])])
pca_comdf
# 차원 정체성 확인 작업
feature_pca = pca_comdf.transpose().sort_values('pca6', ascending=False)
feature_pca
이런식으로 각각의 특성들이 특정 차원에 어느정도의 영향을 미치는지를 확인할 수 있는데
차원별로 내림차순해서 가장 영향을 많이 미치는 특성들을 확인했습니다.
이 작업이 마무리가 되면 다시 radar plot을 보고서 각 군집이 어느 차원에 몰려있는지를 확인 후
앞 단계에서 살펴봤던 결과값을 가지고서 군집의 정체성을 설명할 수 있습니다.
이 작업은 내일 이어서 게속 진행할 예정입니다.
'데이터 분석 공부 > 프로젝트' 카테고리의 다른 글
최종 프로젝트 24일차(24.04.21) (3) | 2024.04.21 |
---|---|
최종 프로젝트 23일차(24.04.20) (0) | 2024.04.20 |
최종 프로젝트 21일차(24.04.18) (1) | 2024.04.18 |
최종 프로젝트 20일차(24.04.17) (0) | 2024.04.17 |
최종 프로젝트 19일차(24.04.16) (0) | 2024.04.16 |