自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

讓數據科學家代替DJ?Python幫你實現(xiàn)

開發(fā) 后端
數據科學是一門龐大的學科,它不斷地擴展到新的行業(yè),音樂產業(yè)就是其中之一。如果把這些應用程序當作一個“黑匣子”,可以觀察到它的輸入(數據)和輸出(產品)。

 [[321520]]

數據科學是一門龐大的學科,它不斷地擴展到新的行業(yè),音樂產業(yè)就是其中之一。如果把這些應用程序當作一個“黑匣子”,可以觀察到它的輸入(數據)和輸出(產品)。該項目旨在使用Python操作Spotify音樂數據,其范圍有兩個:

  • 證明API(應用程序編程接口)的存在對于向算法提供超精細數據具有重要意義。
  • 演示簡單的統(tǒng)計數據(適當應用時)如何對日常行為進行編碼,將其分解為基本要素,并在其基礎上構建有價值的產品。

這個故事,最開始是為了調查音樂背后的統(tǒng)計數據,最后發(fā)現(xiàn)方程式背后也有“音樂”……

概念

假設一個情景。作為一名數據科學家,筆者工作的數據公司(Data Corp)記錄了青年營銷部門獲得的可觀利潤,因此公司決定舉辦聚會犒勞年輕的客戶。

在沒有DJ的情況下,主管讓筆者負責音樂,讓派對持續(xù)到早上!她給了筆者一些Spotify播放列表,讓筆者最終選定并創(chuàng)建一個。然而,忽視現(xiàn)代音樂趨勢讓筆者遇到一個棘手的問題。

使用Python訪問所有播放列表,提取每個曲目的每個音頻特征進行統(tǒng)計分析,并將最適合(派對)的曲目包裝到最終的播放列表中,如何?當然,這里有一個技術性的問題:一個節(jié)拍也聽不到!

為了更好地傳達結果,假定:

#1:個人Spotify播放列表代表的是公司給筆者的。

#2:該聚會的目標群體是18至30歲的年輕人,這意味著……跳舞!然而,他們中的許多人可能會有家人陪伴,也就是說,一小部分客人會更好地享受到歡快的音樂。

#3:在音頻特性中,Spotify只考慮了 danceability, energy, tempo, loudness & valence (見第2節(jié))。那是因為,它們能更好地表達一首曲子是否適合一個舞會。

#4:改進所選播放列表的方法有兩種:刪除或添加分別被視為“壞”或“好”(涉及一個或多個音頻特征)的曲目。筆者只采用后者,以擴大最終的播放列表。

筆者打算按下面的步驟來做:

  • 設置運行代碼的環(huán)境。
  • 請求Spotify API獲取所有相關音樂數據并提供簡要說明。
  • 使用Numpy、Pandas和一些附加的Python庫執(zhí)行EDA(探索性數據分析),以數字和可視化的方式探索候選播放列表。
  • 選擇-使用兩種統(tǒng)計技術優(yōu)化最合適的播放列表。

一、設置

在本節(jié)中,設置所需的環(huán)境,以便應用分析技術。如果已經準備好下面列出的任何部分,可以跳過它們。

  • 申請Spotify開發(fā)者帳戶并創(chuàng)建應用程序。[在此過程中,將創(chuàng)建一個客戶ID,并為應用程序提供一個客戶機密]。
  • 安裝Jupyter Notebook-一個開源的web應用程序,用于創(chuàng)建/共享包含實時代碼、方程式、可視化和敘述性文本的文檔。
  • 安裝Spotipy-用于訪問Spotify Web API和請求的輕量級Python庫-用于尋址API的Python模塊??梢允褂肅LI(命令行界面)或Jupyter notebook來運行以下命令:
  1. pip install spotipy 
  2.              pipinstall requests 

install.py

  • 導入必要的庫:
  1. # Import the libraries 
  2.        import os 
  3.        import pandas as pd 
  4.        import numpy as np 
  5.        import json 
  6.        importmatplotlib.pyplot as plt 
  7.        import seaborn as sns 
  8.        import spotipy 
  9.        importspotipy.util as util 
  10.        fromspotipy.oauth2 importSpotifyClientCredentials 
  • 執(zhí)行授權代碼流:
  1. Declare the credentials 
  2.          cid ='XXXX' 
  3.          secret ='XXXX' 
  4.          redirect_uri='http://localhost:7777/callback' 
  5.          username ='XXXX' 
  6.         # Authorization flow 
  7.          scope ='user-top-read' 
  8.          token = util.prompt_for_user_token(username, scope, client_id=cid,client_secret=secret, redirect_uri=redirect_uri) 
  9.         if token: 
  10.              sp = spotipy.Spotify(auth=token) 
  11.          else
  12.              print("Can'tget token for", username)auth.py 

請注意,與其通過筆記本直接聲明憑證,還不如通過相應地設置環(huán)境變量,使它們暫時可用:

  1. export SPOTIPY_CLIENT_ID="XXXX" 
  2.                       exportSPOTIPY_CLIENT_SECRET="XXXX" 
  3.               exportSPOTIPY_REDIRECT_URI="http://localhost:7777/callback" 

二、數據解釋與獲取

Spotify為其開發(fā)人員提供了許多表征音軌的音頻特征(有關音頻特性對象的更全面的解釋,請參見此處)。下面列出要使用的特征,并簡要說明:

  • Loudness:[-60.0-0db]描述了音軌的整體響度,或者說,聲音的質量,這是與體力(振幅)相關的主要心理因素。
  • Energy:[0.0-1.0]描述了對活動和強度的感性測量。充滿活力的音軌讓人感覺快速、響亮和嘈雜。
  • Valence:[0.0-1.0]描述音軌聽起來“積極”的程度。高價意味著更積極的聲音(如歡快、歡快等)。
  • Tempo:以BPM為單位描述音軌的總體估計節(jié)奏(每分鐘節(jié)拍),直接從節(jié)拍平均的持續(xù)時間得出。
  • Danceability:[0.0-1.0]根據音樂元素(節(jié)奏、穩(wěn)定性、節(jié)拍強度等)的組合,描述一個軌道是否適合跳舞。低值意味著較少的舞步。

數據提取部分分三步完成:訪問用戶播放列表;提取每個播放列表的曲目;提取每個曲目的音頻特征。對于每個步驟,創(chuàng)建一個函數,實現(xiàn)相應的Spotipy方法。

(a)訪問用戶的播放列表

  1. deffetch_playlists(sp,username): 
  2.                      ""
  3.                      Returns theuser's playlists. 
  4.                     ""
  5.                      id = [] 
  6.                      name = [] 
  7.                      num_tracks = [] 
  8.                      #Make the API request 
  9.                      playlists = sp.user_playlists(username) 
  10.                      for playlist in playlists['items']: 
  11.                          id.append(playlist['id']) 
  12.                          name.append(playlist['name']) 
  13.                          num_tracks.append(playlist['tracks']['total']) 
  14.                   # Create the final df   
  15.                      df_playlists = pd.DataFrame({"id":id, "name":name"#tracks": num_tracks}) 
  16.                      return df_playlists 
  17.               playlists =fetch_playlists(sp,username) 
  18.                  playlists= playlists[:4].copy() 
  19.                  playlists 

fetch_plst.py

此函數返回一個數據幀,其中包含用戶播放列表的id、name和曲目數#tracks。顯然,有4個候選播放列表:

讓數據科學家代替DJ?Python幫你實現(xiàn)

playlists 數據幀

(b) 獲取播放列表的曲目

  1. deffetch_playlist_tracks(sp, username, playlist_id): 
  2.                            ""
  3.                            Returns thetracks for the given playlist. 
  4.                           ""
  5.                            offset =0 
  6.                            tracks = [] 
  7.                            #Make the API request 
  8.                            whileTrue: 
  9.                                content = sp.user_playlist_tracks(username, playlist_id, fields=None, limit=100, offset=offset,market=None) 
  10.                                tracks += content['items'
  11.                                if content['next'] isnotNone: 
  12.                                    offset +=100 
  13.                                else
  14.                                    break 
  15.                                    track_id = [] 
  16.                            track_name = [] 
  17.                            for track in tracks: 
  18.                                track_id.append(track['track']['id']) 
  19.                                track_name.append(track['track']['name']) 
  20.                            #Create the final df 
  21.                            df_playlists_tracks = pd.DataFrame({"track_id":track_id, "track_name": track_name}) 
  22.                            return df_playlists_tracks 

fetch_trcs.py

這個函數以playlist_id作為參數,返回一個數據幀,包括每個曲目的曲目 track_id 和 track_name 。不直接調用它,而是在下面的函數中使用它。

(c) 獲取曲目的音頻特征

  1. deffetch_audio_features(sp, username, playlist_id): 
  2.                           ""
  3.                           Returns theselected audio features of every track, 
  4.                           for the givenplaylist. 
  5.                          ""
  6.                           # Usethe fetch_playlist_tracks function to fetch all of the tracks 
  7.                           playlist =fetch_playlist_tracks(sp, username, playlist_id) 
  8.                           index =0 
  9.                           audio_features = [] 
  10.                           #Make the API request 
  11.                           while index < playlist.shape[0]: 
  12.                               audio_features += sp.audio_features(playlist.iloc[index:index+50, 0]) 
  13.                               index +=50 
  14.                           #Append the audio features in a list 
  15.                           features_list = [] 
  16.                           for features in audio_features: 
  17.                               features_list.append([features['danceability'], 
  18.                                                     features['energy'],features['tempo'], 
  19.                                                     features['loudness'],features['valence']]) 
  20.                           df_audio_features = pd.DataFrame(features_list,columns=['danceability''energy'
  21.                                              'tempo''loudness''valence']) 
  22.                        # Set the 'tempo' & 'loudness' in the same range withthe rest features 
  23.                           for feature in df_audio_features.columns: 
  24.                               if feature =='tempo'or feature =='loudness'
  25.                                   continue 
  26.                               df_audio_features[feature] =df_audio_features[feature] *100 
  27.                           #Create the final df, using the 'track_id' as index for future reference 
  28.                           df_playlist_audio_features = pd.concat([playlist,df_audio_features], axis=1) 
  29.                           df_playlist_audio_features.set_index('track_id', inplace=Truedrop=True
  30.                           return df_playlist_audio_features 

fetch_aud_ftrs.py

給定 playlist_id 作為參數,此函數返回每個曲目的 track_id, name 和音頻特征(danceability, energy, tempo, loudness, valence)。因此,對于4個播放列表中的每一個,創(chuàng)建相應音頻特征的數據幀:

  1. df_dinner =fetch_audio_features(sp, username, '37SqXO5bm81JmGCiuhin0L'
  2.                        df_party=fetch_audio_features(sp, username, '2m75Xwwn4YqhwsxHH7Qc9W'
  3.                        df_lounge=fetch_audio_features(sp, username, '6Jbi3Y7ZNNgSrPaZF4DpUp'
  4.                        df_pop=fetch_audio_features(sp, username, '3u2nUYNuI08yUg877JE5FI'

aud_ftrs.py

讓數據科學家代替DJ?Python幫你實現(xiàn)

df_dinner 數據框示例

僅僅借助API的力量就獲得了所有必要數據的純編碼!

三、EDA

為了減少混亂,這里不包括數據可視化代碼,但它可以在GitHub repo上使用。

首先,在一個圖中描繪所有播放列表的音頻特征,以便容易地感知哪個最適合聚會。

讓數據科學家代替DJ?Python幫你實現(xiàn)

音頻特征水平條形圖

顯然,把特征作為整體來看,Party和Pop播放列表取代了另外兩個。仔細看看這兩個,就能更清楚地了解哪一個占上風…

讓數據科學家代替DJ?Python幫你實現(xiàn)

df_party 和df_pop水平橫條圖

除了danceability特征外,其他特征在派對播放列表中更高。這是一個必須選擇和建立,以完善最終的播放列表。

四、播放列表的優(yōu)化

其主要作用是盡可能增加派對播放列表的音頻特征。但是,增加一個特征可能會減少另一個特性,因此必須考慮優(yōu)先級。就筆者個人而言,根據假設2,danceability(年輕人)應該是主要特征,下一個特征是valence(家庭成員)。

這些變量是定量的,同時也屬于比率尺度的測量。因此,箱線圖可以有效地描述每個特征的個體分布。這樣的圖表和描述性統(tǒng)計表(通過pandas.DataFrame.describe方法)可以提供關于每個特定四分位數下的值的比例的良好視覺展示。

下面將詳細說明原始的df_party數據框,突出顯示danceability和valence平均值、第二(中位數)和第三個四分位數:

讓數據科學家代替DJ?Python幫你實現(xiàn)
讓數據科學家代替DJ?Python幫你實現(xiàn)

df_party數據的描述性統(tǒng)計和箱線圖

豎直的黃線是中位數,而▴符號代表平均數。一般的目標是“推動”每一個特征的分布盡可能地向右,也就是說,沿著播放列表曲目方向增加,以便獲得一個更好的“聚會”體驗!根據假設4,從df_pop(第二個決賽播放列表)中添加曲目,每次都尋找機會:

  • 將平均值向右移動(增加平均音頻特征)
  • 或將中位數移到平均值的右側(確保至少50%的歌曲高于平均值)
  • 或兩者兼而有之

方法一

一個好的出發(fā)點是,抽取一個df_pop的樣本,并將其添加到主樣本(df_party)中,隨機的除外。通過使用pandas.DataFrame.sample()函數和weights參數,可以預先配置danceability值越大,就越有可能對相應的行進行采樣。這種方法產生的數據框是df_party_exp_I(exp代表expanded)。

  1. # Take a sample from the Pop playlist 
  2.       df_pop_sample_I= df_pop.sample(n=40, weights='danceability',random_state=1) 
  3.       df_pop_sample_I.describe() 
  4.      # Concatenate the original playlist with the sample 
  5.       df_party_exp_I= pd.concat([df_party, df_pop_sample_I]) 
  6.       df_party_exp_I.describe() 

sample_I.py

讓數據科學家代替DJ?Python幫你實現(xiàn)
讓數據科學家代替DJ?Python幫你實現(xiàn)

df_party_exp_I描述性統(tǒng)計和方框圖

  • 主要音頻特征danceability增加;平均值上升近0.5,其分布也略有優(yōu)化。中位數從68.20移到69.30,第三(上)四分位數分別從77.20移到78.90。
  • 但是, valence特征下降了0.61,四分位都沒有向右移動。鑒于此,應該尋找進一步的優(yōu)化機會。

方法二

這一次將利用NumPy布爾索引并過濾Pop播放列表,以便只返回滿足指定條件的行。特別是,將danceability和valence特征設置為高于派對播放列表的相應平均值,分別為69.55和51.89。

  1. # Take a sample from the Pop playlist 
  2.        df_pop_sample_II= df_pop[(df_pop['danceability'] >69.55) & (df_pop['valence'] >51.89)].copy() 
  3.       # Concatenate the original playlist with the sample 
  4.        df_party_exp_II= pd.concat([df_party, df_pop_sample_II]) 
  5.        df_party_exp_II.describe() 

sample_II.py

讓數據科學家代替DJ?Python幫你實現(xiàn)
讓數據科學家代替DJ?Python幫你實現(xiàn)

df_party_exp_II描述性統(tǒng)計和方框圖

  • danceability增加更多。這次平均值增加了將近2.17!隨著中位數和上四分位數向右移動,沿著該功能的曲目分布也得到了優(yōu)化,這基本上意味著至少50%的播放列表高于主要聲學功能的“新”較高平均值(71.71)。
  • 盡管如此,valence特征下降了4.21,第二和第三個四分位數均高于平均值。

方法三

一個特征的優(yōu)化并不一定意味著其他特征的優(yōu)化。為了改善這一缺點,將引入一個方程,其變量是聲學特征,參數是賦予它們的權重。既然非常重視danceability特征,那么相應的權重應該更高。最后分數計算如下:

Score =(danceability *30)+(energy *20)+(tempo *20)+(loudness *10)+(valence *20)

為播放列表的每個單曲計算這個分數(創(chuàng)建一個新的列score),然后計算各自的描述性統(tǒng)計。這樣,可以更好地評估,豐富df_party,同時在每個特征上實現(xiàn)更統(tǒng)一(根據權重)的優(yōu)化。

簡言之,df_party, df_party_exp_I & df_party_exp_II的平均score分別為7355分、7215分和7416分。很明顯,雖然方法一相比原來的播放列表找到了更好的danceability,但它破壞了派對的整體體驗(平均score從7355下降到7215)。就方法二而言,平均score提高了近62分。然而,也可以不用這兩種方法…

這一次,通過使用新引入的score列,將過濾df_pop數據幀,并獲取注意到score高于df_party平均值的行。因此,增加后者!

  1. # Take a sample from the Pop playlist 
  2.       df_pop_sample_III= df_pop[df_pop['score'] > df_party['score'].mean()].copy() 
  3.      # Concatenate the original playlist with the sample 
  4.       df_party_exp_III= pd.concat([df_party, df_pop_sample_III]) 
  5.       df_party_exp_III.describe() 

sample_III.py

讓數據科學家代替DJ?Python幫你實現(xiàn)
讓數據科學家代替DJ?Python幫你實現(xiàn)

df_party_exp_III描述性統(tǒng)計和方框圖

事實上,這次:

  • danceability特征提高了近1.17,valence增加了4.06(平均值的右移)
  • 兩種分布都得到改善(中位數移到平均值的右側)
  • score為122.3,是目前為止最好的!(上下文意味著更高的潛力,播放列表在加權音頻特征上更加統(tǒng)一)

作為一個完整的檢查,應該一次性描述和比較所有的方塊圖—這可能看起來有點擁擠。幸運的是,變量的性質(見上文)允許使用KDE(內核密度圖)。

讓數據科學家代替DJ?Python幫你實現(xiàn)

KDE圖

現(xiàn)在非常清楚了,方法三(綠色分布)是最好的,因為它實現(xiàn)了更高的右移。

最后,最終得到的數據幀(df_party_exp_III)包含了最終的音軌。唯一懸而未決的操作是將其轉換為真正的播放列表。下面,第一個函數創(chuàng)建最終的播放列表,將其名稱作為參數以及描述。另一個,從數據幀遷移軌跡。

請注意,授權流將再次運行,這次將使用不同的作用域(playlist modify public)。只需查看指南就好(https://github.com/makispl/Spotify-Data-Analysis/blob/master/README.md)。

  1. defcreate_playlist(sp,username, playlist_name, playlist_description): 
  2.                         playlists = sp.user_playlist_create(username, playlist_name, description =playlist_description) 
  3.   
  4. create_plst.py 
  5.   
  6. defenrich_playlist(sp,username, playlist_id, playlist_tracks): 
  7.                      index =0 
  8.                      results = [] 
  9.                      while index <len(playlist_tracks): 
  10.                          results += sp.user_playlist_add_tracks(username, playlist_id, tracks =playlist_tracks[index:index +100]) 
  11.                          index +=100 

enrich_plst.py

  1. # Make a temporary list of tracks 
  2.        list_track =df_party_exp_III.index 
  3.       # Create the playlist 
  4.        enrich_playlist(sp,username, '779Uv1K6LcYiiWxblSDjx7', list_track) 

create_plst.py

讓數據科學家代替DJ?Python幫你實現(xiàn)

播放列表數據幀

讓數據科學家代替DJ?Python幫你實現(xiàn)

Bingo!

結論

到目前為止,已經處理了數百首曲目,檢查了它們的音頻特征,最后選擇了最適合聚會的曲目,只用到了Python。通過這種方式,成功地完成了任務:

  • 演示了簡單(描述性)的統(tǒng)計數據和編碼(如果適當組合)是如何計算出此類耗時的活動的。
  • “嘗到”了擁有可請求的API的重要性,以便提取有意義的數據。

無論是從DJ還是從數據科學家的角度“深入”音樂世界,這無疑都是美妙的……

但是,有效地,當涉及到大量音樂數據集的精確性、敏捷性和徹底處理時,后者可以通過幾行代碼來指示計算機體面地執(zhí)行。也就是說,有一件事是必然的:

數據科學已經找到了另一個發(fā)展壯大的“市場”,這意味著統(tǒng)計背后確實有“音樂”,達到了節(jié)拍背后有數學的水平…

Jupyternotebook已準備好立即運行,讓Pandas搖滾吧!

 

責任編輯:華軒 來源: 今日頭條
相關推薦

2017-08-04 15:53:10

大數據真?zhèn)螖祿茖W家

2012-12-26 10:51:20

數據科學家

2018-12-24 08:37:44

數據科學家數據模型

2020-03-20 14:40:48

數據科學Python學習

2012-12-06 15:36:55

CIO

2019-07-30 11:47:29

數據科學云計算機器學習

2018-02-28 15:03:03

數據科學家數據分析職業(yè)

2020-02-12 16:49:49

數據科學技能云計算

2012-12-26 10:18:47

大數據數據科學家

2012-12-25 09:58:50

數據科學家大數據

2018-10-16 14:37:34

數據科學家數據分析數據科學

2012-06-12 09:33:59

2019-09-11 14:34:13

排序算法數據科學

2012-12-27 09:52:23

數據科學家大數據

2014-07-03 09:38:19

2019-08-26 09:47:56

數據科學家數據分析

2018-05-04 15:09:25

數據科學面試數據科學家

2018-05-05 07:46:39

數據科學面試大數據

2016-08-02 17:00:12

Hadoop大數據系統(tǒng)

2016-04-11 14:15:06

數據科學數據挖掘工具
點贊
收藏

51CTO技術棧公眾號