Python에서 Spotify 1부: 전처리
이 기사에서는 Spotify 데이터를 Python으로 가져오기 시작합니다. 이것은 Python의 Spotify에 대한 일련의 기사 중 첫 번째 기사입니다.
이 기사에서는 다음을 수행합니다.
- Spotify 데이터를 Python으로 가져오는 방법을 보여줍니다.
- 저장된 노래 재생 목록을 데이터 프레임에 로드합니다.
- 저장된 모든 노래에서 오디오 기능을 해제하십시오.
- 각 노래에 장르(그룹)를 추가합니다.
- 작은 결론을 내리고 다음 단계에 대해 이야기하십시오.
시작하려면 사용자 Spotify API 자격 증명이 필요합니다.
이렇게 하려면 다음 단계를 따라야 합니다.
- Spotify 개발자 대시보드(https://developer.spotify.com/dashboard/applications) Spotify 계정으로 로그인합니다.
- 새로운 Spotify 응용 프로그램을 만들려면 "앱 만들기" 버튼을 클릭하십시오.
- 이름, 설명 및 웹 사이트와 같은 응용 프로그램에 필요한 정보를 입력하십시오. "리디렉션 URI" 필드를 리디렉션 URL로 사용하려는 URL로 설정할 수 있습니다.
- 애플리케이션을 생성하면 "클라이언트 ID" 및 "클라이언트 암호" 값이 제공됩니다.
- 제공한 "REDIRECT" URL과 일치하도록 Spotify 애플리케이션의 "리디렉션 URI"도 설정해야 합니다 .
"credentials" 파일에 다음과 같은 방법으로 자격 증명을 저장했습니다.
사용자 = '...'
CID = '...'
비밀 = '...'
리디렉션 = '...'
Jupiter Notebook에서 다음 코드를 실행하여 자격 증명을 사용하여 사용자 토큰을 생성할 수 있습니다.
#importing libraries
import credentials
import spotipy
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Retrieve user credentials from separate file
user = credentials.USER
cid = credentials.CID
secret = credentials.SECRET
redirect_uri = credentials.REDIRECT
# Define scope of access
scope = 'user-library-read' # user-library-read, user-read-recently-played
# Prompt for user token using credentials
token = spotipy.util.prompt_for_user_token(user, scope, client_id=cid, client_secret=secret, redirect_uri=redirect_uri)
# Create Spotify token and check if successful
if token:
sp = spotipy.Spotify(auth=token)
print('Token created for', user)
else:
print("Can't get token for", user)
# User data
user_data = sp.current_user()
print('My data:')
print('Name:', user_data['display_name'])
print('Followers:', user_data['followers']['total'])
print('Link:', user_data['external_urls']['spotify'])
Spotify 라이브러리에서 저장된 노래 가져오기
다음 코드에서는 저장된 노래가 Spotify 라이브러리에서 검색됩니다. 노래는 pandas 데이터 프레임에 저장됩니다.
# Function to get all saved tracks
def get_saved_tracks():
results = sp.current_user_saved_tracks()
tracks = []
while results['next']:
tracks.extend(results['items'])
results = sp.next(results)
return tracks
# Converting tracks to dataframe
def deconstruct_tracks(tracks):
saved_tracks = []
for track in tracks:
saved_track = {
'added_at': track['added_at'],
'id': track['track']['id'],
'name': track['track']['name'],
'popularity': track['track']['popularity'],
'uri': track['track']['uri'],
'artist': track['track']['artists'][0]['name'],
'album': track['track']['album']['name'],
'release_date': track['track']['album']['release_date'],
'duration_ms': track['track']['duration_ms']
}
saved_tracks.append(saved_track)
return pd.DataFrame(saved_tracks)
tracks_called = get_saved_tracks()
tracklist = deconstruct_tracks(tracks_called)
#%%
tracklist.head(10)
오디오 기능 로드 중
Spotify에서 저장된 노래에 대한 탐색적 분석을 수행하려면 먼저 노래에서 일부 기능을 파생해야 합니다. 파생될 기능은 다음과 같습니다.
Acousticness : 트랙이 음향인지 여부를 나타내는 0.0에서 1.0 사이의 값으로, 1.0은 음향 특성에 대한 높은 신뢰도를 나타냅니다.
댄스 가능성 : 템포, 리듬 안정성, 비트 강도 및 규칙성과 같은 요소를 기반으로 트랙이 댄스에 얼마나 적합한지 설명하는 0.0에서 1.0까지의 척도입니다.
Energy : 트랙의 강도와 활동을 나타내는 0.0에서 1.0 사이의 값으로 빠르고 크고 시끄럽게 느껴지는 에너지 넘치는 트랙입니다. 동적 범위, 인지 음량, 음색, 시작 속도 및 엔트로피와 같은 지각 기능이 이 특성에 기여합니다.
Instrumentalness : 트랙에 보컬이 포함되어 있는지 여부에 대한 예측으로, 1.0에 가까운 값은 보컬 콘텐츠가 없을 가능성이 더 높음을 나타냅니다. 0.5 이상의 값은 일반적으로 악기 트랙을 나타내며 값이 1.0에 가까워질수록 신뢰도가 높아집니다.
Liveness : 레코딩에서 청중의 존재를 나타내는 값으로, 값이 높을수록 라이브 공연의 가능성이 높음을 나타냅니다. 0.8 이상의 값은 라이브 트랙일 가능성이 높습니다.
Loudness : 데시벨(dB) 단위의 트랙 전체 음량으로 전체 트랙의 평균이며 트랙의 상대적인 음량을 비교하는 데 유용합니다. 값의 범위는 일반적으로 -60에서 0dB 사이입니다.
Speechiness : 트랙에 음성 단어가 있음을 나타내는 척도이며 값이 1.0에 가까울수록 더 음성과 유사한 녹음을 제안합니다. 0.66 이상의 값은 전적으로 음성으로 구성된 트랙을 설명하고 0.33에서 0.66 사이의 값은 랩 음악을 포함하여 음악과 음성이 혼합된 것을 나타낼 수 있습니다. 0.33 미만의 값은 대부분 음악 및 비음성 트랙을 나타냅니다.
템포 : 트랙의 전체 예상 템포(BPM)로 음악의 속도를 나타냅니다.
박자표 : 각 소절이나 소절의 비트 수를 지정하는 음악 용어입니다.
Valence : 0.0에서 1.0 사이의 값으로 트랙이 전달하는 음악적 긍정적인 정도를 나타냅니다. Valence가 높을수록 행복과 같은 긍정적인 감정이 더 많고, Valence가 낮을수록 슬픔과 같은 부정적인 감정이 더 많이 나타납니다.
모드 : 트랙의 형식(메이저 또는 마이너) 표시기이며, 1은 메이저를 나타내고 0은 마이너를 나타냅니다.
키 : 표준 피치 클래스 표기법(예: 0 = C, 1 = C♯/D♭, 2 = D 등)을 사용하여 정수로 매핑된 트랙의 예상 전체 키입니다.
다음 코드를 사용하여 이러한 모든 기능을 파생시킵니다.
# Function to get all audio features of the saved tracks
def get_track_features(id):
metadata = sp.track(id)
features = sp.audio_features(id)
# metadata
id = metadata['id']
name = metadata['name']
album = metadata['album']['name']
artist = metadata['album']['artists'][0]['name']
release_date = metadata['album']['release_date']
length = metadata['duration_ms']
popularity = metadata['popularity']
# audio features
acousticness = features[0]['acousticness']
danceability = features[0]['danceability']
energy = features[0]['energy']
instrumentalness = features[0]['instrumentalness']
liveness = features[0]['liveness']
loudness = features[0]['loudness']
speechiness = features[0]['speechiness']
tempo = features[0]['tempo']
time_signature = features[0]['time_signature']
valence = features[0]['valence']
mode = features[0]['mode']
key = features[0]['key']
track = [name, album, artist, release_date, length, popularity, danceability, acousticness, danceability, energy,
instrumentalness, liveness, loudness, speechiness, tempo, time_signature, valence, mode, key]
return track
print("Function defined")
# Loop through each track id and get the tracks features
for i in range(len(tracklist)):
try:
track = get_track_features(tracklist['id'][i])
tracklist.loc[i, 'name'] = track[0]
tracklist.loc[i, 'album'] = track[1]
tracklist.loc[i, 'artist'] = track[2]
tracklist.loc[i, 'release_date'] = track[3]
tracklist.loc[i, 'length'] = track[4]
tracklist.loc[i, 'popularity'] = track[5]
tracklist.loc[i, 'danceability'] = track[6]
tracklist.loc[i, 'acousticness'] = track[7]
tracklist.loc[i, 'danceability'] = track[8]
tracklist.loc[i, 'energy'] = track[9]
tracklist.loc[i, 'instrumentalness'] = track[10]
tracklist.loc[i, 'liveness'] = track[11]
tracklist.loc[i, 'loudness'] = track[12]
tracklist.loc[i, 'speechiness'] = track[13]
tracklist.loc[i, 'tempo'] = track[14]
tracklist.loc[i, 'time_signature'] = track[15]
tracklist.loc[i, 'valence'] = track[16]
tracklist.loc[i, 'mode'] = track[17]
tracklist.loc[i, 'key'] = track[18]
# Save to df
tracklist.to_csv('tracklist.csv', index=False, encoding='utf-8')
except:
print(f"Error with track {i}")
pass
print(f"Features of {len(tracklist)} tracks extracted and saved to tracklist.csv")
한 곡에 대해 한 곡의 오류가 발생했습니다. 실제 곡이 아니라 Kerri Chandler의 2시간 분량의 믹스였기 때문입니다. 물론 이러한 모든 오디오 기능에 대해 하나의 값을 도출하는 것은 불가능합니다. 따라서 이 '노래'는 다음 처리 단계로 넘어가지 않습니다.
장르
Spotify API는 노래에 어떤 장르도 제공하지 않습니다. 이것은 우리가 해결해야 할 것입니다. 각 아티스트의 관련 장르를 가져와서 각 노래에 추가할 수 있는 API를 사용하여 이를 수행할 수 있습니다.
# Add all genres of the artists to the dataframe
genres = []
for i in range(len(data)):
artist = data['artist'][i]
artist_id = sp.search(artist, type='artist')['artists']['items'][0]['id']
artist_genres = sp.artist(artist_id)['genres']
genres.append(artist_genres)
data['genres'] = genres
data.head(10)
# Transform the genre column to extract specific genres
data['genres'] = data['genres'].astype(str)
data['genres'] = data['genres'].str.replace('[', '')
data['genres'] = data['genres'].str.replace(']', '')
data['genres'] = data['genres'].str.replace("'", '')
data['genres'] = data['genres'].str.replace('"', '')
data.head(10)
# Search for predefined genres in the genre column
strings = ['pop', 'techno', 'house', 'disco', 'electronic',
'trance', 'hip hop', 'rap', 'r&b', 'soul', 'rock',
'metal', 'punk', 'jazz', 'blues', 'country', 'folk',
'reggae', 'classical', 'indie', 'funk']
for string in strings:
data.loc[data['genres'].str.contains(string), 'genre_group'] = string
data.head(10)
장르별 개수:
# Check how many tracks are in each genre group
data['genre_group'].value_counts()
# Count missing values
data['genre_group'].isnull().sum()
print(f"{data['genre_group'].isnull().sum()} tracks are missing a genre group")
# visualize the distribution of the genres
plt.figure(figsize=(15, 10))
sns.countplot(y='genre_group', data=data, order=data['genre_group'].value_counts().index)
for i, genre in enumerate(data['genre_group'].value_counts().index):
count = data['genre_group'].value_counts()[genre]
plt.text(count + 10, i, f'{count}', ha='left', va='center', color='black')
plt.title('Distribution of genres with counts')
plt.show()
인디, 디스코, 소울 음악을 들으면서 펑키하고 하우시한 분위기를 자주 내는 걸 알 수 있다.
참고: 291개의 트랙에 장르(그룹)가 없습니다. 이것은 이 시리즈의 2부에서 다루게 될 문제입니다.
다음 단계
이 데이터 프레임을 CSV 파일로 저장합니다.
data.to_csv('tracklist.csv', index=False, encoding='utf-8')
다음 기사에서는 다음과 같이 하겠습니다.
- 탐색적 데이터 분석을 수행합니다.
- 장르가 없는 노래에 장르를 지정하는 방법을 보여줍니다.
- 기계 학습을 사용하여 음악이 자동으로 정렬되는 저장된 노래의 재생 목록을 만듭니다.
- 이 프로세스를 자동화합니다.
노트북은 내 GitHub에서 사용할 수 있습니다.
이 프로젝트를 함께 작업한 Nils Jennissen과 Gabriel Ronnó에게 큰 감사를 드립니다. Medium 및 GitHub에서 그를 팔로우하십시오.
- https://medium.com/@nilsjennissen
- https://github.com/nilsjenn
- https://medium.com/@gabriel_renno
- https://github.com/GabrielRenno
멋진 일러스트레이션은 Kateryna Malachkova가 제작했습니다. 그녀의 미디엄과 인스타그램을 꼭 확인하세요!
- https://medium.com/@malachkovak
- https://instagram.com/ph_malachkova?igshid=ZjE2NGZiNDQ=
- https://github.com/rubentak
- https://www.linkedin.com/in/ruben-tak-665b66194/

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































