用Python给你喜欢的音乐分个类吧
你喜欢什么样的音乐?目前,很多公司实现了对音乐的分类,要么是为了向客户提供推荐(如Spotify、SoundCloud),要么只是作为一种产品(如Shazam)。对音乐进行分类,首先要确定音乐类型。事实证明,用机器学习技术从大量数据中找出音乐的各种潮流和类型是非常成功的。音乐分析亦然。
本文我们将学习如何用Python进行音频/音乐信号分析以及之后如何用该技能对不同类型的音乐片段进行分类。
用Python处理音频
声音以音频信号的形式表示,音频信号具有频率、带宽、分贝等参数,音频信号一般可表示为振幅和时间的函数。
这些声音有多种格式,因此计算机可以对其进行读取和分析。例如:
• mp3 格式
• WMA (Windows Media Audio) 格式
• wav (Waveform Audio File) 格式
音频库
Python有一些很好用的音频处理库,比如Librosa和PyAudio。另外,还有一些基本的音频功能的内置模块。
我们将主要使用两个音频库进行音频采集和回放,如下:
1.Librosa
Librosa是一个Python模块,通常用于分析音频信号,但更适合音乐信号分析。它包括构建一个音乐信息检索(MIR)系统的具体细节,目前,Librosa已充分实现文档化,并具有许多相关的示例和教程。
安装

可以安装附带很多音频解码器的ffmpeg(一个开源免费跨平台的视频和音频流方案)以提高音频解码功率。
2.IPython.display.Audio
IPython.display.Audio可以让用户直接在Jupyter notebook中播放音频。
音频包加载

以上步骤的返回值为一段音频的时间序列,其默认采样频率(sr)为22KHZ mono。我们可将其改为:
librosa.load(audio_path, sr=44100)
可重新采样为44.1KHZ,
librosa.load(audio_path, sr=None)
或者不重新采样。
采样频率指音频每秒钟的采样样本数,以Hz或kHz表示。
音频播放
用Ipython.display.Audio 播放音频。
import IPython.display as ipd
ipd.Audio(audio_path)
以上步骤的返回值为Jupyter notebook的一个音频插件。如下:
这里的插件不起作用,不过放到你的notebooks上就可以了。
以下音频也可用mp3格式或WMA格式听。
可视化音频(Visualizing Audio)
波形音频 (Waveform)
我们可以用librosa.display.waveplot来绘制音频。

上图显示了该段波形音频的振幅包络线(amplitude envelope)。
声谱图(spectrogram)
声谱图(spectrogram)是声音或其他信号的频率随时间变化时的频谱(spectrum)的一种直观表示。声谱图有时也称sonographs,voiceprints,或者voicegrams。当数据以三维图形表示时,可称其为瀑布图(waterfalls)。在二维数组中,第一个轴是频率,第二个轴是时间。
我们可以用librosa.display.specshow 来展示声谱图。、

纵轴显示的是频率(从0到10kHz),横轴显示的是音频的时间。因为所有可见的波动都发生在频谱的底部,故这里将频率轴转换成对数轴。
librosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='log')
plt.colorbar()
音频编写
用librosa.output.write_wav 将NumPy数组保存到WAV文件中。
librosa.output.write_wav('example.wav', x, sr)
创建音频信号
现在让我们创建一个220HZ的音频信号。由于音频信号是一个numpy数组,所以创建后需将其转换为音频函数。

然后,这就是你创建的第一个音频信号。
特征提取
每一个音频信号都有很多特征。然而,我们必须提取出与我们试图解决的问题相关的特征。提取特征以用于分析的过程称为特征提取。接下来我们将详细研究其中几个特征。
过零率(Zero Crossing Rate)
过零率(zero crossing rate)是一个信号符号变化的比率,即,在每帧中,语音信号从正变为负或从负变为正的次数。 这个特征已在语音识别和音乐信息检索领域得到广泛使用,通常对类似金属、摇滚等高冲击性的声音的具有更高的价值。
现在我们来计算示例音频片段的过零率:


上图似乎有6个过零点,用librosa来验证下该结果。

频谱质心(Spectral Centroid)
频谱质心指示声音的“质心”位于何处,并按照声音的频率的加权平均值来加以计算。 假设现有两首歌曲,一首是蓝调歌曲,另一首是金属歌曲。现在,与同等长度的蓝调歌曲相比,金属歌曲在接近尾声位置的频率更高。所以蓝调歌曲的频谱质心会在频谱偏中间的位置,而金属歌曲的频谱质心则靠近频谱末端。
用librosa.feature.spectral_centroid 计算出每一帧音频信号的频谱质心。

频谱质心在接近末端处有上升。
谱滚降(Spectral Rolloff)
谱滚降(Spectral Rolloff)是对信号形状的测量,表示的是在谱能量的特定百分比(如85%)时的频率。
librosa.feature.spectral_rolloff 计算出每一帧信号的滚降频率。

梅尔频率倒谱系数(Mel-Frequency Cepstral Coefficients)
信号的梅尔频率倒谱系数(MFCC)是一个通常由10-20个特征构成的集合,可简明地描述频谱包络的总体形状,对语音特征进行建模。
这次我们使用一个简单的循环波。

用librosa.feature.mfcc 计算出音频信号的梅尔频率倒谱系数:

计算出该段超过97帧的音频的梅尔频率倒谱系数为20。
我们也可以给特征标上刻度,使其每个系数有相应的零均值和单位方差。


Chroma Frequencies
色度特征是对音乐音频的一种有趣生动的表示,可将整个频谱投射到代表“八度”(在音乐中,相邻的音组中相同音名的两个音,包括变化音级,称之为八度。)上12个不同的半音(或色度)的12进制上。色度向量(chroma vector )(维基百科)(FMP,p.123)是一个通常包含12个元素特征的向量,表示信号中每个音级{C, C#, D, D#, E, …, B}中的能量。
用librosa.feature.chroma_stft 计算Chroma Frequencies。

案例分析:对歌曲类型进行分类
以上我们对声学(听觉)信号及其特征和特征提取过程进行了概述,现在让我们用刚习得的技能来解决机器学习问题。
目标
本节,我们将尝试创建一个分类器将歌曲归为不同的类型。假设这样一个场景:出于某种原因,我们在硬盘上找到一堆随机命名的MP3文件,且文件里有音乐。我们的任务是根据音乐类型将它们分到不同的文件夹中,如爵士、古典音乐、乡村音乐、流行音乐、摇滚乐和金属乐。
数据集
我们将用最常用的的GITZAN数据集进行案例研究。G. Tzanetakis和P. Cook在2002年IEEETransactions on audio and Speech Processing中发表的著名论文: Musical genre classification of audio signals (音频信号的音乐类型分类)中曾用到该数据集。
该数据集每30秒包含1000条音轨,共包含10个音乐类型,即布鲁斯、古典、乡村、迪斯科、嘻哈、爵士、雷鬼、摇滚、金属和流行音乐。每种类型包含100段声频。
数据处理
在训练分类模型之前,我们须将原始数据从音频样本转换成更有意义的表示形式。需将音频片段从.au格式转换为能与python的 wave模块兼容的.wav格式,以读取音频文件。不过我常用的是开源SoX模块。
sox input.au output.wav
分类
特征提取(Feature Extraction)
我们接下来需要从音频文件中提取出有意义的特征。为了对音频片段进行分类,这里将选择5个特征,即梅尔频率倒谱系数(Mel-Frequency Cepstral Coefficients),频谱质心 (Spectral Centroid),过零率(Zero Crossing Rate), Chroma Frequencies,谱滚降(Spectral Roll-off)。然后将所有特征附加到.csv文件中,以便使用分类算法。
分类(Classification)
提取出特征后,用现有的分类算法将歌曲分为不同的类型。你可以直接用声谱图进行分类,也可以在提取特征后使用分类模型。
无论采用哪种方式,都要在模型上进行大量的实验。你可以进行试验和改进结果。建议试试CNN模型,它(在声谱图上)的精确度更高。
音乐类型分类的笔记
导入库

音乐和特征提取
数据集
我们用GTZAN genre collection 数据集进行分类。
数据集包含10中音乐类型。如下:
• 布鲁斯
• 古典
• 乡村
• 迪斯科
• 嘻哈
• 爵士
• 金属乐
• 流行音乐
• 雷鬼
• 摇滚
每一种音乐类型包含100首歌曲。共计1000首歌曲。
音频的声谱图提取

将所有的音频文件转换成相应的声谱图,以方便提取特征。
声谱图特征提取
我们将提取以下特征:
• 梅尔频率倒谱系数(Mel-frequency cepstral coefficients (MFCC))(20 个)
• 频谱质心(Spectral Centroid)
• 过零率(Zero Crossing Rate)
• Chroma Frequencies
• 谱滚降(Spectral Roll-off)

将数据写入csv 文件

以上数据已被提取并写入data.csv文件。
用Pandas进行数据分析

5行× 28列

对标签进行编码

给特征栏标上刻度

将数据分为训练集和测试集

使用Keras进行分类
创建自己的网络

以上数据的精确度不如训练数据的精确度高,这说明可能存在“过度拟合”(Overfitting)。
对所用方法进行验证
我们要从训练数据中留出200个样本作为测验集:

对测试集进行预测

下一步
音乐类型分类是音乐信息检索的众多分支之一。你还可以对音乐数据执行其他任务,如节拍跟踪(beat tracking)、音乐生成、推荐系统、音轨分离(track separation)、乐器识别等。音乐分析是一个既多元化又有趣的领域。音乐在某种程度上代表了用户的一个时刻。在数据科学领域,发现并描述这些时刻将会是一个有趣的挑战。