working_helen

[Audio feature 군집화] Spotify Song Clustering with k-means 본문

deep daiv./추천시스템 project

[Audio feature 군집화] Spotify Song Clustering with k-means

HaeWon_Seo 2023. 9. 16. 00:11

앞서 학습한 k-means 군집화 알고리즘을 적용하여 Spotify 노래 데이터 clustering하는 과정에 대해 정리해본다. 본 프로젝트에서는 audio feature를 이용해 노래의 mood cluster를 구하는 과정을 진행했다.

 

참고한 이전 분석 자료

 

International Journal of Music Science, Technology and Art

IJMSTA - Vol. 5 - Issue 1 - Janury 2023 ISSN 2612-2146 Pages: 13 Spotify Song Analysis by Statistical Machine Learning Authors: Federica Biazzo, Matteo Farné Categories: Journal Abstract - This paper aims to study the use of Artificial Intelligence in the

www.ijmsta.com

Spotify-Music Clustering

Music Recommendation System using Spotify Dataset

Building Mood-Based Spotify Playlists using K-Means Clustering

 

 

1. 군집화 알고리즘

  1) 군집화 알고리즘의 종류

  2) k-means를 사용한 이유 

2. Scaling

  1) Scaler 종류

  2) MinMaxScaler를 사용한 이유 

3. 변수 PCA

4. k-means clustering

5. clustering 결과

  1) 시각화

  2) 군집별 특성 확인

 

 


1. 군집화 알고리즘

: 비슷한 특성을 가진 데이터끼리 집단을 나누어 레이블링하는 비지도 학습 알고리즘

 

  1) 군집화 알고리즘의 종류

 

k-means

장점 단점
- 알고리즘이 쉽고 간결하여 가장 일반적으로 사용한다.

- 데이터와 그룹 간 거리 계산에만 의존하기 때문에 계산량이 적고, O(n)의 계산복잡도를 가진다.

- 클러스터 내 데이터가 원형으로 흩어져 있는 경우에 효과적
- 직접 최적의 군집 수 k를 정해야한다.
- 초기 중심점 위치에 따라 클러스터링 결과가 달라질 수 있다.

- feature 개수가 매우 많을수록 군집화 정확도가 떨어진다.(PCA 차원 축소를 적용한 후 진행하는 방안)

- 평균값을 클러스터 중심점으로 사용한다는 특성으로 인해 군집화가 잘 적용되지 않는 분포가 존재한다.

 

 

 

 

GMM(Gaussian Mixture Model)

출처 : https://daebaq27.tistory.com/49

- 정규분포 기반 군집화 방식

- 주어진 데이터 분포를 k개의 가우시안 분포가 혼합된 것으로 가정하는 방법

- 혼합 가우시안 분포에서 k개의 가우시안 분포를 추출 → 각 데이터가 어느 가우시안 분포에 속하는 추정

- 즉 k개의 가우시안 분포 = k개의 군집

- 각 클러스터의 가우스 파라미터를 찾기위해 Expectation-Maximization(EM) 최적화 알고리즘을 사용

장점 단점
- 기하학적인 분포의 군집, 서로 겹치는 군집에 대해서도 군집화할 수 있다.

- 데이터가 두 개의 클러스터에 겹쳐있는 경우 각 클러스터에 속할 확률을 제시해줌으로써 mixed membership을 지원한다.

- 원형 분포만 표현하는 k-means에 비해 더 다양한 분포를 표현할 수 있다. GMM은 표준편차 파라미터 덕분에 원뿐만 아니라 타원 모양의 분포를 표현할 수 있다. 따라서 GMM은 타원형으로 길게 늘어진 데이터 군집화에 효과적이다.
- k-means와 마찬가지로 군집 개수를 의미하는 가우시안 분포의 개수 k를 직접 정해야한다.

- 각 가우시안 분포마다 충분한 데이터들이 있어야, 분포 파라미터 추정이 잘 수행될 수 있다.

- k-means에 비해 계산량이 많다.

 

from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(n_components=k값, n_init=10, tol=1e-3, max_iter=1000).fit(df)

#군집 예측 결과 저장
gmm_cluster_labels = gmm.predict(df)
df['gmm_cluster'] = gmm_cluster_labels

#모델 성능 확인
gm.aic(df)
gm.bic(df)
gm.score(df)

 

  • 모델 파라미터
    tol : 수렴 임계값, 이 임계값보다 낮으면 EM 반복이 중지, default = 1e-3
    max_iter : 수행할 EM 반복 횟수, default = 100
    n_init : 수행할 초기화 횟수, default = 1
  • 모델 method
    aic, bic : AIC, BIC값 반환
    score : 데이터셋의 샘플당 평균 log-likelihood 반환 

 

출처 : https://yeong-jin-data-blog.tistory.com/entry/GMM-Gaussian-Mixture-Models

- GMM은 각 클러스터에 속할 확률값을 사용하는 모델이기 때문에 실루엣 계수가 아닌 log-likelihood 기반의 AIC(Akaike Iinformation Criterion)와 BIC(Bayesian Information Criterion)를 사용한다.
- likelihood가 클수록 = log-likelihood가 클수록
= AIC와 BIC값이 작을수록 모델의 성능이 좋다.
- 따라서 GMM은 AIC 또는 BIC가 최소화되는 k를 군집 개수로 삼는다. 

 

 

 

 

 

DBSCAN(Density Based Spatial Clustering of Applications with Noise)

출처 : https://velog.io/@jeong_woo/Cesium.js-v-world-%EC%A7%80%EB%8F%84-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EB%A7%81

- 밀도 기반 군집화 방식
- 같은 클러스터에 속하는 데이터는 서로 근접하게 분포할 것이라고 가정하고, 데이터의 밀도가 사전에 지정된 기준 이상인 경우 하나의 클러스터로 구분하는 방식

- DBSCAN 과정

 

  • 클러스터 반경 ε (epsilon) / 반경 내 데이터 최소 개수 minPoints 결정
  • step 1. 임의의 데이터 포인트를 선택
  • Step 2. 해당 데이터의 종류 판단
    데이터를 기준으로 ε 반경 내에 minPoints 개수 이상의 데이터가 있다면 Core point로 할당
    데이터를 기준으로 ε 반경 내에 minPoints 개수 이상의 데이터가 없다면 Border point로 할당
  • Step 3. 어떤 데이터가 Step 2가 Core point이고, 다른 군집에 할당되어있다면 두개의 군집을 하나로 묶음
  • Step 4. 모든 데이터가 클러스터에 할당될 때까지 반복
  • Core point도 Border point에도 해당하지 않아서 군집이 되지 않는 point는 Noise point가 된다.
장점 단점
- k-means나 GMM에 비해 클러스터 분포 형태에 구애받지 않기 때문에 기하학적으로 복잡한 분포의 데이터에도 효과적으 군집화가 가능하다.

-  자체 계산 과정을 통해 클러스터 개수가 결정되기 때문에 사전에 클러스터 를 지정할 필요가 없다.

- 노이즈에 강하다.
- 각 클러스터의 밀도가 다양한 경우 군집화가 잘 수행되지 않는다.
밀도가 다양해지면 neighborhood point를 판단하는 거리 임계값 ε 및 minPoints가 클러스터에 따라 크게 달라지기 때문에 일관적인 기준값을 사용하면 군집화가 어려워진다.

- 고차원 데이터거나 데이터의 분포를 모르는 경우 적절한 임계값을 설정하기 어렵다.

- 데이터가 학습되는 순서에 따라 영향을 받는다.

 

 

 

2) k-means를 사용한 이유 

 

- audio feature 변수 개수가 많아 시각화 상태에서 데이터 분포를 파악하는게 어려움

→ 고차원 데이터거나 데이터의 분포를 모르는 경우 적절한 임계값을 설정하기 어려운 DBSCAN 제외

 

- Spofity audio feature 분류와 관련된 이전 분석 자료를 살펴보았을때 대부분 k-means를 사용했기 때문에 가장 일반적인 kmeans를 사용해보기로 결정

- k-means보다 더 범용적인 GMM도 함께 적용해보았으나 결과적으로 GMM과 k-means의 결과가 거의 일치하여 k-means 알고리즘을 최종 모델로 선택함 

 

 

 

 

 

 

2. Scaling

- 다차원 데이터에서 feature의 범위나 분포를 동일하게 조정해주는 과정

- 다차원 데이터에서 feature들은 서로 다른 단위를 가지고 있는데, 거리 기반 모델의 경우 단위의 수치적 값이 상대적으로 더 큰 feature가 단순히 단위 차이로 인해 계산 과정에 더 많은 영향을 미칠 수 있다.

- 이러한 문제를 방지하기 위해 모든 feature 단위의 수치적 크기를 동일하게 맞춰주는 scaling을 진행한다.

 

1) Scaler 종류

 

StandardScaler

- 각 feature 값에 대하여 해당 feature의 평균을 빼고, 분산으로 나눠주는 표준화 과정을 수행

- 모든 feature가 N(0,1)의 정규분포를 따르게 변환한다.

- 데이터의 정규성을 가정하는 알고리즘을 구현하는 경우 잘 사용된다.

- 이상치의 영향을 크게 받으며, 데이터의 기존 분포 형태를 왜곡할 수 있다는 문제점이 있다.

from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()
df_scaled = standardScaler.fit_transform(df)
df_scaled = pd.DataFrame(df_scaled, columns=df.columns)

 

 

RobustScaler

- StandardScaler과 유사하게 각 feature 값에 대하여 해당 feature의 median을 빼고, IQR로 나눠주는 과정을 수행

- StandardScaler에서 보다 더 넓은 분포 형태로 표준화된다.

- 다른 Scaling 방법에 비해 이상치에 의한 영향을 최소환 기법이다.

- 데이터의 기존 분포 형태를 왜곡할 수 있다는 문제점이 있다.

from sklearn.preprocessing import RobustScaler
robustScaler = RobustScaler()
df_scaled = robustScaler.fit_transform(df)
df_scaled = pd.DataFrame(df_scaled, columns=df.columns)

 

 

MinMaxScaler

- 모든 feature에 대하여 최솟값은 0, 최댓값은 1이 되도록 값을 [0, 1] 범위로 변환

- 이상치가 있는 경우 이상치가 끝값이 되어 매우 좁은 범위로 압축될 수 있기 때문에 이상치에 민감하다.

from sklearn.preprocessing import MinMaxScaler
minMaxScaler = MinMaxScaler()
df_scaled = minMaxScaler.fit_transform(df)
df_scaled = pd.DataFrame(df_scaled, columns=df.columns)

 

 

MaxAbsScaler

- 모든 feature에 대하여 최소절댓값은 0, 최대절댓값은 1이 되도록 값을 [-1, 1] 범위로 변환

- MinMaxScaler와 유사한 이유로 이상치에 민감하다.

from sklearn.preprocessing import MaxAbsScaler
maxAbsScaler = MaxAbsScaler()
df_scaled = maxAbsScaler.fit_transform(df)
df_scaled = pd.DataFrame(df_scaled, columns=df.columns)

 

 

 

2) MinMaxScaler를 사용한 이유 

 

- 가장 적합한 Scaling 방법은 데이터의 분포나 유형에 따라 달라지기 때문에 분석하고자 하는 데이터의 특성에 맞는 scaling 방법을 적절히 선택해야한다. 일반적으론 StandardScaler를 많이 사용한다.

 

- 본 프로젝트에서 사용한 k-means 알고리즘의 경우 정규분포를 가정할 필요가 없었다.

- 위와 같이 audio feature data의 분포를 확인해보았을때, 값이 한쪽으로 쏠려있지만 중심에서 벗어난 값들이 이상치는 아닌 skewed된 형태의 분포를 보였다. audio feature의 차이로부터 노래를 clustering하는 것이 목표였기 때문에 기존의 노래 간 차이를 드러내는 skewed한 분포를 최대한 변형시키지 않는 것이 적절하다고 판단했다. 이에 따라 StandardScaler와 RobustScaler를 사용하지 않았다.

- 원래 데이터의 범위가 다 양수였기 때문에 MinMaxScaler와 MaxAbsScaler의 결과는 동일하다.

 

➡️ 따라서 기존 데이터 분포를 잘 보존하고, 양수 범위에서 sacling하는 MinMaxScaler를 사용한다.

 

 

 

 

 

3. 변수 PCA

- audio feature 변수가 11개로 많고, 일부 변수는 노래 간 분류에 기여도가 낮을 것이라 예상 (사전 조사)

- k-means의 경우 feature 개수가 매우 많을수록 군집화 정확도가 떨어지는 단점이 있었기 때문에 PCA 수행

 

- 변수 PCA를 통해 audio feature 변수를 차원 축소한 후, 추출된 PC를 기준으로 k-means를 수행

- PCA 결과 : 분산 설명력 90% 기준 7개, 70% 기준 3개의 PC를 사용

(노래를 가능한 많은 cluster로 나눈는게 목표 + 노래 간 차이를 직접 들어본 후, PC 3개인 경우로 하기로 결정)

 

 

 

 

 

4. k-means clustering

- 최적 k값 확인 : Elbow Method 수행 결과 k=6에서 최적

- 실루엣 계수 : SilhouetteVisualizer 이용, 전체 데이터 평균 실루엣 계수 = 0.443279

 

 

 

 

 

5. clustering 결과

1) 시각화

- feature가 4개 이상인 경우 시각화가 어렵기 때문에 2/3차원으로 차원 축소를 진행해 시각화한다.

 

t-SNE (t-distributed stochastic neighbor embedding, t-분포 확률적 임베딩)

: 차원 축소 기법의 일종

- 특히 고차원 데이터의 2/3차원 시각화에 유용하게 사용

- 비슷한 데이터는 근접한 2/3차원의 지점으로, 다른 데이터는 멀리 떨어진 지점으로 맵핑한다.

- N개의 데이터에 대해 N^2 시간의 계산이 필요할 정도로 많은 계산이 요구된다.

 

  • PCA : 원본 데이터의 정보를 가장 잘 유지하면서 차원을 줄이는 차원 축소 방법
  • t-SNE : 원본 데이터를 가장 잘 표현할 수 있도록 차원을 줄이는 차원 축소 방법

 

-  PCA의 경우 목표가 '데이터의 정보를 가장 잘 보존하는' 것이고, t-SNE의 경우 '원본을 가장 잘 표현할 수 있는' 방식이라는 점에서 차이가 있다. 이로 인해 PCA가 잘 적용되지만 그룹에 따른 차이를 시각화로 확인이 어려운 경우, 동일한 데이터에 대해 t-SNE를 이용해 시각화하면 그룹에 따른 차이를 더 명확하게 확인할 수 있다.

 

from sklearn.manifold import TSNE

# 2차원 t-SNE 임베딩
tsne_df = TSNE(n_components = 2).fit_transform(df)
tsne_df = pd.DataFrame(tsne_np, columns = ['component 0', 'component 1'])

# 3차원 t-SNE 임베딩
tsne_np = TSNE(n_components = 3).fit_transform(train_df)
tsne_df = pd.DataFrame(tsne_np, columns = ['component 0', 'component 1', 'component 2'])

 

clustering 시각화 결과

 

 

 

2) 군집별 특성 확인

 

[audio feature에 대한 변수 설명]

https://developer.spotify.com/documentation/web-api/reference/get-audio-features

 

Web API Reference | Spotify for Developers

Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and activity. Typically, energetic tracks feel fast, loud, and noisy. For example, death metal has high energy, while a Bach prelude scores low on the scale. Perceptual fe

developer.spotify.com

 

cluster별 audio feature 평균값

 

 

Cluster1

 

- 박자 타기 좋은 음악

- '악기 소리'는 거의 없고, 탁탁 하는 박자 소리가 중심 

- 완전 밝거나 우울하거나 하는 느낌보단 미소 지을 수 있는 정도의 여유로움

- 전주/간주에 비해 가사와 노래가 많음

 

→ 리듬 타면서 들을 수 있는, 가사 위주 노래

→ 힙합 음악 / 여유로운 카페 음악

 

 

Cluster2

 

- 속도감은 있는데 노래 자체는 밝지 않음

- 전반적으로 1번보다 더 어두운 느낌으로 들림

- 1과 유사하게 발로 박자 탈 수 있는 수준의 리듬감

- 가사 중심 + 힙합 음악 다수

 

→ 리드미컬하고 속도감 있는데, 어두운 노래

→ 힙합 음악

 

 

 

Cluster3

 

- 박자 소리가 많지 않음, 흘러가는 듯한 배경 음악

- 어둡고, 느리고 잔잔한 느낌의 음악 다수 (발라드)

- 울리는 느낌의 백음악 + 코러스나 화음이 많은 (풍부한 백사운드)

- 1, 2에 비해 가사보다 배경음악이 많은 편

 

→ 어둡고 잔잔한 노래, 풍부하고 화음이 많은 백음악

→ 어두운 발라드 계열 / 느린 속도의 힙합

 

 

Cluster4

 

- cluster1과 유사점 = 박자 타기 좋음 음악

- cluster1과 차이점 = 더 어둡고, 늘어지는 느낌(chill)의 곡이 많음, 전주도 더 긴 경향

 

→ 1과 동일한 결의 음악 중에서 조금 더 어둡고, 느리고, chilling한 음악 계열

→ 리듬 타면서 들을 수 있는, 가사 위주 노래

→ 힙합 음악 / 여유로운 카페 음악

 

 

 

Cluster5

 

- 막 밝은 느낌의 노래는 아니지만, 완전 우울한 측면도 아님

- 중간에 데시벨 높은 구간이 존재하거나, 그냥 전체적으로 데시델이 큰 노래

- 간주 부분에서 노래만 들려주지 않고, 가사로 채운 형태

 

→ 어둡고 빠르진 않은데, 높은 데시벨의 가사 구간이 존재하는 노래

→ 어두운 + 웅장함 + 데시벨 높음 + 가사 위주 노래

 

 

 

Cluster6

 

- 느리고 잔잔하고 어두운 계열

- 자신감 저하/고민/생각거리 많은 상태에서 들으면 공감될 것 같은 느낌

-가사 많이 없이 잔잔한 배경 음악 흘러감 

 

 

 

 

 

 

 

Jupyter Notebook

 

 

 

 

 

Reference

[Clustering]

https://bangu4.tistory.com/98
https://saint-swithins-day.tistory.com/81
https://daebaq27.tistory.com/49
https://studying-haeung.tistory.com/14
https://steadiness-193.tistory.com/283

 

[GMM]

https://scikit-learn.org/stable/modules/generated/sklearn.mixture.GaussianMixture.html#sklearn.mixture.GaussianMixture.bic
https://yeong-jin-data-blog.tistory.com/entry/GMM-Gaussian-Mixture-Models

 

[Scaling]

https://syj9700.tistory.com/56
https://dacon.io/codeshare/4526
https://mkjjo.github.io/python/2019/01/10/scaler.html
https://www.linkedin.com/advice/1/what-pros-cons-different-scaling-methods-data-normalization

 

[t-SNE]

https://jimmy-ai.tistory.com/126
https://bigdatamaster.tistory.com/186
https://skyeong.net/284
https://en.wikipedia.org/wiki/T-distributed_stochastic_neighbor_embedding