1 #利用knn算法分类音乐,将音乐进行情绪分类2 #将音乐分为兴奋的(excited), 愤怒的(angry),悲伤的(sorrowful),轻松的(relaxed)3
4 #可分离因素5 # mfcc6
7 import numpy asnp8 from matplotlib import pyplot asplt9 from scipy import io asspio10 fromsklearn.decomposition import pca11 fromsklearn.preprocessing import StandardScaler12 import librosa13 import librosa.display14 frommutagen.mp3 import MP315 import numpy asnp16 import os17
18 def getFeature(path):19 y, sr =librosa.load(path)20
21 mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40)22 mfccNew = np.ravel(mfccs[:, :1000])23 returnmfccNew24
25 def loadDataSet():26 #歌曲的数量27 dataSet = np.zeros((40, 40000))28 labels =[]29
30 excited = r'./musicF/excited'
31 angry = r'./musicF/angry'
32 sorrowful = r'./musicF/sorrowful'
33 relaxed = r'./musicF/relaxed'
34
35 filenames =os.listdir(excited)36 i = 0
37 for filename infilenames:38 print(filename)39 dataSet[i] = getFeature(excited + '/' +filename)40 labels.append('excited')41 i += 1
42
43 filenames =os.listdir(angry)44 for filename infilenames:45 print(filename)46 dataSet[i] = getFeature(angry + '/' +filename)47 labels.append('angry')48 i += 1
49
50 filenames =os.listdir(sorrowful)51 for filename infilenames:52 print(filename)53 dataSet[i] = getFeature(sorrowful + '/' +filename)54 labels.append('sorrowful')55 i += 1
56
57 filenames =os.listdir(relaxed)58 for filename infilenames:59 print(filename)60 dataSet[i] = getFeature(relaxed + '/' +filename)61 labels.append('relaxed')62 i += 1
63
64
65 returndataSet, labels66
67 #欧几里得距离计算相关度68 def kNNClassify(features, dataSet, k, labels):69 numSamples = dataSet.shape[0]70 t = np.tile(features, (numSamples , 1))71
72
73
74 diffVal = t -dataSet #向量操作75
76 squareDiffVal = diffVal ** 2
77 squareDist = np.sum(squareDiffVal,1)78 distance = squareDist ** 0.5
79
80 #对相关度进行排序,相关度由大到小(数值由小到大)81 sortedDistIndices =np.argsort(distance)82
83 classCount ={}84 for i inrange(k):85
86 voteLabel =labels[sortedDistIndices[i]]87 classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
88
89 maxCount = 0
90 ansKey =None91 for key, value inclassCount.items():92 if value >maxCount:93 ansKey =key94 maxCount =value95 returnansKey96
97 #保存文件98 def saveData(dataSet):99 np.savetxt(r'./musicF/dataSet.txt', dataSet)100
101 #从文件中加载数据集并返回102 def loadDataFromFile():103 return np.loadtxt(r'./musicF/dataSet.txt')104
105 #保存标签到文件106 def saveLabels(labels):107 f = open('./musicF/labels.txt','w', encoding="gbk")108 f.write(' '.join(labels))109 f.close()110
111
112 #读取标签数据113 def loadLabels():114 f = open('./musicF/labels.txt','r', encoding="gbk")115 labelsString =f.read()116 f.close()117 labels = labelsString.split(' ')118 returnlabels119
120
121 def classify(path):122 features =getFeature(path)123 #读取数据124 dataSet =loadDataFromFile()125 labels =loadLabels()126 ans = kNNClassify(features, dataSet, 7, labels)127 returnans128
129 def main():130 path = r'./musicF/test/CMJ - 告白之夜(纯音乐)(Cover:Ayasa绚沙).mp3'
131 audio =MP3(path)132 print('音乐时长为:',audio.info.length)133 features =getFeature(path)134 print(features.shape)135
136 dataSet, labels =loadDataSet()137 #保存数据138 saveData(dataSet)139 saveLabels(labels)140
141 # #读取数据142 # dataSet =loadDataFromFile()143 # labels =loadLabels()144
145 ans = kNNClassify(features, dataSet, 7, labels)146 print('labels =', ans)147
148 def addData():149 dataSet, labels =loadDataSet()150 #保存数据151 saveData(dataSet)152 saveLabels(labels)153
154 if __name__ == '__main__':155 #addData()156 main()