[K-Pop 오디오 특성 분석 대시보드] 배경 및 데이터 수집, 정제

Eunsuh Kim·2023년 2월 10일
1
post-thumbnail

0. 배경 및 필요성

K-Pop '그룹'(인물)의 인기도가 아닌 '음악' 자체의 오디오 특성이 해당 그룹의 성공에 미친 영향이 있는지를 파악하기 위해 K-Pop 오디오 특성을 분석하는 프로젝트를 진행하였다.

1. 분석 목표

  1. 인기에 영향을 미치는 오디오 특성이 있는가?
  2. 국가별로 선호하는 오디오 특성이 있는가?
  3. 아티스트별 핵심 오디오 특성이 있는가?

2. 데이터 수집

'스포티파이 차트에 진입한 적이 있는 K팝 아이돌 그룹'의 곡들

을 분석 대상으로 선정하였다.

스포티파이 차트

스포티파이 차트를 인기도를 판단할 기준이 되는 차트로 선정한 이유는 (1) Spotify API를 사용할 수 있다는 점 그리고 (2) 스포티파이 글로벌 차트 관련 기록이 K팝의 '해외' 인기를 판단하기에 적합하다는 점 2가지가 있었다.

  • 스포티파이는 글로벌과 국가별 일간 및 주간 차트로 구성되어 있다.
  • 전세계적으로 약 2억 명의 유료 이용자 및 30%의 시장점유율을 확보한 스트리밍 플랫폼인데 한국의 경우 점유율이 아직 1.7%이기 때문에 전체 스트리밍 횟수에서 국내 비중은 매우 낮다. 따라서 글로벌 차트 관련 기록은 사실상 해외 기록으로 볼 수 있다.
  • 그래서 K팝 그룹별 글로벌 인기를 분석하기 위해, 해당 그룹의 곡이 스포티파이 글로벌 일간 차트에 차트인했는지, 즉 200위 안에 들었는지를 여부로 판단하였다.
  • 분석 대상을 ‘그룹’으로 잡았기 때문에 솔로 가수 또는 그룹 멤버가 솔로로 활동하여 차트인한 경우는 제외했다. 이것을 바탕으로 총 20개 그룹, 남자 그룹 9팀, 여자 그룹 11팀을 선정하였다. (여자 그룹을 선정할 때는 이 블로그 글을 참고하였다.) 분석 대상은 다음과 같다.
남자 그룹여자 그룹
BTS, ENHYPEN, Stray Kids, SEVENTEEN, BIGBANG, TREASURE, EXO, NCT DREAM, TOMORROW X TOGETHERBLACKPINK, TWICE, Red Velvet, (G)I-DLE, aespa, NMIXX, LE SSERAFIM, IVE, ITZY, Kep1er, NewJeans

각 분석 대상에 대한 아티스트 URL을 저장했다.

# 스포티파이 글로벌 일간 차트인 (걸그룹)
blackpink = 'https://open.spotify.com/artist/41MozSoPIsD1dJM0CLPjZF'
twice = 'https://open.spotify.com/artist/7n2Ycct7Beij7Dj7meI4X0'
redvelvet = 'https://open.spotify.com/artist/1z4g3DjTBBZKhvAroFlhOM'
newjeans = 'https://open.spotify.com/artist/6HvZYsbFfjnjFrWF950C9d'
ive = 'https://open.spotify.com/artist/6RHTUrRF63xao58xh9FXYJ'
lesserafim = 'https://open.spotify.com/artist/4SpbR6yFEvexJuaBpgAU5p'
itzy = 'https://open.spotify.com/artist/2KC9Qb60EaY0kW4eH68vr3'
aespa ='https://open.spotify.com/artist/6YVMFz59CuY7ngCxTxjpxE'
gidle = 'https://open.spotify.com/artist/2AfmfGFbe0A0WsTYm0SDTx'
kep1er = 'https://open.spotify.com/artist/5R7AMwDeroq6Ls0COQYpS4'
nmixx = 'https://open.spotify.com/artist/28ot3wh4oNmoFOdVajibBl'

# 스포티파이 글로벌 일간 차트인 (보이그룹)
bts = 'https://open.spotify.com/artist/3Nrfpe0tUJi4K4DXYWgMUX'
straykids = 'https://open.spotify.com/artist/2dIgFjalVxs4ThymZ67YCE'
seventeen = 'https://open.spotify.com/artist/7nqOGRxlXj7N2JYbgNEjYH'
txt = 'https://open.spotify.com/artist/0ghlgldX5Dd6720Q3qFyQB'
enhypen = 'https://open.spotify.com/artist/5t5FqBwTcgKTaWmfEbwQY9'
nctdream = 'https://open.spotify.com/artist/1gBUSTR3TyDdTVFIaQnc02'
exo = 'https://open.spotify.com/artist/3cjEqqelV9zb4BYE3qDQ4O'
treasure = 'https://open.spotify.com/artist/3KonOYiLsU53m4yT7gNotP'
bigbang = 'https://open.spotify.com/artist/4Kxlr1PRlDKEB0ekOCyHgX'

Spotify API

분석 대상에 대한 데이터셋을 추출하기 위해서 Spotify API를 활용했다.
API 활용 방법과 추출하는 코드, 추출한 세부 항목별 의미는 아래 참고 자료에 있는 Spotify for Developers 공식 문서, Spotipy 공식 문서, 를 포함한 여러 가지 자료들을 참고하였다.

간단히 요약하자면 Spotify API를 활용하기 위해서는 Spotify for Developers에서 앱 등록을 해야 하고, 'Spotipy'라는 파이썬 라이브러리를 통해 Spotify Web API를 이용할 수 있다.

수집한 데이터는 다음과 같다.
각 아티스트 -> 아티스트별 앨범 -> 앨범별 트랙 -> 트랙별 특성을 추출하는 방식으로 for문을 돌렸다.

  • 아티스트 (그룹) 정보
    • 아티스트 이름
    • 아티스트 ID
    • 아티스트 URI
    • artist popularity
  • 앨범 정보
    • 앨범 이름
    • 앨범 ID
    • 앨범 URI
    • 출시일
  • 트랙 (곡) 정보
    • 앨범의 track number
    • 트랙 이름
    • 트랙 이름 (formatted)
    • 트랙 ID
    • 트랙 URI
    • track popularity
    • audio features
artist_list = [blackpink, twice, redvelvet, newjeans, ive, lesserafim, itzy, aespa, gidle, kep1er, nmixx,
               bts, straykids, seventeen, txt, enhypen, nctdream, exo, treasure, bigbang]

feature_list = []

# 아티스트
for artist in artist_list:
    
    artistprofile = sp.artist(artist_id = artist)
    artistalbums = sp.artist_albums(artist_id = artist, limit = 50)
    
    artist_popularity = artistprofile['popularity']

    # 아티스트별 앨범
    for i in range(len(artistalbums['items'])):
        album_uri = artistalbums['items'][i]['uri']
        album_tracks = sp.album_tracks(album_uri)
        
        # 앨범별 트랙
        for j in range(len(album_tracks['items'])):
            track_number = album_tracks['items'][j]['track_number'] # track_number
            track_uri = album_tracks['items'][j]['uri'] # track uri
            track_id = album_tracks['items'][j]['id'] # track id
            track_popularity = sp.track(track_id)['popularity'] # track popularity (따로 저장)
            audiofeatures = sp.audio_features(track_uri)

            # 트랙별 audio features
            for feature in audiofeatures:
                try:
                    feature_list.append([artistalbums['items'][0]['artists'][0]['name'], #artist_name
                                         artistalbums['items'][0]['artists'][0]['id'], #artist_id
                                         artistalbums['items'][0]['artists'][0]['uri'], #artist_uri
                                         artist_popularity, #artist_popularity
                                         artistalbums['items'][i]['name'], #album_name
                                         artistalbums['items'][i]['id'], #album_id
                                         album_uri, #album_uri
                                         artistalbums['items'][i]['release_date'], #release_date
                                         track_number, #track_number
                                         title, #track_name
                                         track_name_changed, #track_name_formatted
                                         track_id, #track_id
                                         track_uri, #track_uri
                                         track_popularity, #track_popularity
                                         feature['danceability'], #danceability
                                         feature['energy'], #energy
                                         feature['key'], #key
                                         feature['speechiness'], #speechiness
                                         feature['acousticness'], #acousticness
                                         feature['instrumentalness'], #instrumentalness
                                         feature['liveness'], #liveness
                                         feature['valence'], #valence
                                         feature['tempo'], #tempo
                                         feature['duration_ms'], #duration_ms
                                         feature['time_signature'], #time_signature
                                         feature['loudness'], #loudness
                                         feature['mode'], #mode
                                         feature['type'] #type (총 28개)
                                        ])

                except Exception as e:
                    print(e, track_uri, "skipped")
                    continue
    
    print(artist, "done")

URI와 URL의 차이는?

  • URI: 특정 리소스를 식별하는 통합 자원 식별자(Uniform Resource Identifier)를 의미한다. 웹 기술에서 사용하는 논리적 또는 물리적 리소스를 식별하는 고유한 문자열 시퀀스다.
  • URL: 흔히 웹 주소라고도 하며, 컴퓨터 네트워크 상에서 리소스가 어디 있는지 알려주기 위한 규약이다. URI의 서브셋이다.
URIURL
spotify:track:054sQZ2qmw0Ya7N0XSxl3jhttps://open.spotify.com/track/054sQZ2qmw0Ya7N0XSxl3j

Audio Feature

추출한 audio feature의 의미는 다음과 같다.

특성의미
acousticness어쿠스틱 장르인 정도 (0~1 사이 값)
danceability춤 추기에 어울리는 정도 (0~1 사이 값). 속도, 리듬, 안정성, beat, 강도 등의 특성을 이용해 지표화.
energy빠르거나 시끄러운 음악인 정도 (0~1 사이 값)
instrumentalness보컬이 없는 곡인 정도 (0~1 사이 값)
liveness라이브 음원인 정도 (0~1 사이 값)
speechiness대화하는 (노래가 아닌) 오디오인 정도 (0~1 사이 값)
valence곡이 긍정적인 감정인지의 정도 (0~1 사이 값)
tempo곡의 빠르기. BPM
key음정. C = 0, 반음 올릴 때마다 + 1, -1인 경우는 결측치
modemajor: 1, minor: 0
time signature박자. 한 마디에 4분 음표가 몇 개 들어가는 지에 대한 지표. 정수로 3 ~ 7의 값을 갖는다. 정황상 6/8 은 3으로 표기되는 등 변환되어 표기되는 듯 하다.

3. 데이터 정제

곡이 아닌 음성 트랙 제거

  1. 특정 아티스트의 경우 음악이 아닌 음성 파일 또한 Spotify에 발매되었다.
    • '음악'에 해당하지 않으며 speechiness를 과도하게 높이기 때문에 제거하였다.

중복 곡 제거

여러 가지 경우에 따른 중복 곡이 존재했다.

  1. 아티스트가 곡을 싱글로 발매한 후 앨범으로 다시 발매하거나 리믹스, 외국어 버전을 발매한 경우, 한 가지 곡에 대한 여러 가지 버전이 존재했다. (원곡 제목 + '~ Ver.' 형식으로)

    • 여러 가지 버전이 존재하는 곡에 대해서는 원곡을 제외하고 모두 제거하였다. (버전이 변형되면 해당 곡의 특성이 변형되는 것과 같기 때문이다.)
  2. 저작권으로 인해 동일한 곡(같은 시점에 같은 이름으로 발매된 곡)에 대한 ID가 여러 개 존재하였다.

    • 가장 과거에 발매된 곡만 남기고 모두 제거하였다.
  3. API를 가져온 방식으로 인해 드라마/영화 OST의 경우 해당 K팝 그룹이 참여한 트랙 외 다른 트랙 또한 전부 수집되었다.

    • 해당 아티스트의 트랙을 제외하고 모두 제거하였다.

참고 자료

2. 데이터 수집

스포티파이 차트

4세대 여자 아이돌 기록실 4편 - 해외 음원 (스포티파이)

Spotify API

The Data Science of K-Pop: Understanding BTS through data and A.I.
https://github.com/haebichan/kpopclassifier
Web API Reference | Spotify for Developers
Spotipy 2.22.1 Documentation
Spotify API 사용법 - Spotipy(파이썬 라이브러리) 사용
https://www.charlezz.com/?p=44767

profile
안녕하세요!

0개의 댓글