前言:
簡單地分析一下自己的音樂收藏。
那么就讓我們愉快地開始吧~~~
相關工具
Python版本:3.6.4
相關模塊:
numpy模塊;
sklearn模塊;
matplotlib模塊;
以及一些Python自帶的模塊。
mpg123:
1.25.10
環境搭建
安裝Python並添加到環境變量,pip安裝需要的相關模塊;
將相關文件中提供的mpg123.zip文件解壓后添加到環境變量中,例如:
開始分析
方便起見,所有的音樂文件均先轉為.wav格式后再做分析。
從最簡單的開始吧!讓我們先來看看不同歌手的聲音波形圖:
周傑倫:
感覺波形圖好混亂,似乎是數據量太大引起的,於是我打算換一個策略,只畫出每首歌曲前10秒的波形圖來作比較,畢竟良好的開端是成功的一半?
周傑倫:
許嵩:
陳奕迅:
Interesting...
好像還是挺有意思的,但並看不出什么端倪來的樣子,同一個歌手唱的歌的波形結構之間的差異和不同歌手唱的歌的波形結構之間的差異仿佛都挺大的。雖然並沒有規定說同一個歌手唱的歌的波形結構之間的差異一定很小,不同歌手唱的歌的波形結構之間的差異一定很大。
好吧,有些混亂,還是隨意點的好。那么我們來嘗試性地提取一下歌曲的特征吧。我們打算提取的歌曲特征有:
① 歌曲波形的統計矩,包括均值、標准差、偏態和峰態,同時,我們通過平滑窗(遞增平滑,長度分別為1,10,100,1000)來獲取這些特征在不同時間尺度上的表現;
② 為了體現信號的短時變化,我們可以計算一下波形一階差分幅度的統計矩,同樣也通過平滑窗來獲取這些特征(均值、標准差、偏態和峰態)在不同時間尺度上的表現;
③ 最后,我們計算一下波形的頻域特征,這里我們只計算歌曲在不同頻段(將整個頻段均分為10份)的能量占比,不過直接對歌曲的波形數據作快速傅里葉變換的話其計算量過於龐大了,因此先讓波形數據通過長度為5的平滑窗再對其作快速傅里葉變換。
綜上所述,我們已經獲得了歌曲的42個特征值。下面我們嘗試利用這些特征值對我這幾天下載的43首歌曲進行k均值聚類。首先,為了便於結果的可視化,我們利用PCA對數據進行降維(42維特征到2維特征),為了方便起見,我們直接調庫(sklearn)實現,結果打印如下:
OK,接下來我們就可以對降維后的數據進行聚類了,這里我們將自己實現一下k均值聚類算法而不是簡單地調庫,最終的聚類結果如下圖所示(k=4):
接下來我們嘗試先對歌曲的42個特征值進行歸一化處理,然后再進行上面的PCA和聚類操作,同時令k=3,最終的聚類結果如下圖所示:
Emmm,好像效果更差了。
不過我發現我喜歡了8年的歌“尾戒”竟然一枝獨秀了!還是很棒的,哈哈~~~
當然,這里有一個問題,歌曲的42個特征值是人工選取的,也許並不很好的表現出歌曲特征,且這些特征之間的相關系數是不為0的,也就是存在冗余特征。
https://www.christianpeccei.com/musicmap/
一文利用了遺傳算法從42個特征值中篩選出了18個特征值作為歌曲最終的特征向量,其結果如下:
懶得復現了,直接用他的結論重新進行聚類,結果如下(k=3):
那就這樣吧,就當學點基礎的音頻處理、機器學習和可視化技術了。
文章到這里就結束了,感謝你的觀看,關注我每天分享Python技術分享,下篇文章分享垃圾郵件識別