Browse Source

Migrate structures to pandas DataFrame, Complete visualization, Minor fixes and improvements

master
Apostolos Fanakis 6 years ago
parent
commit
ccf0ecf3ef
No known key found for this signature in database GPG Key ID: 56CE2DEDE9F1FB78
  1. 22
      classifier/feature_extraction/batch_feature_extractor.py
  2. 4
      classifier/feature_extraction/feature_extractor.py
  3. 22
      classifier/pipeline.py
  4. 0
      classifier/preprocessing/__init__.py
  5. 17
      classifier/preprocessing/data_preprocessing.py
  6. BIN
      classifier/preprocessing/dataset.npy
  7. BIN
      classifier/preprocessing/dataset.pkl
  8. BIN
      classifier/preprocessing/featureKeys.npy
  9. BIN
      classifier/preprocessing/target.npy
  10. 55
      classifier/test/accuracyWithoutFeature.py
  11. 0
      classifier/training/__init__.py
  12. BIN
      classifier/visualization/output/figure_1.png
  13. BIN
      classifier/visualization/output/figure_10.png
  14. BIN
      classifier/visualization/output/figure_11.png
  15. BIN
      classifier/visualization/output/figure_12.png
  16. BIN
      classifier/visualization/output/figure_13.png
  17. BIN
      classifier/visualization/output/figure_14.png
  18. BIN
      classifier/visualization/output/figure_15.png
  19. BIN
      classifier/visualization/output/figure_2.png
  20. BIN
      classifier/visualization/output/figure_3.png
  21. BIN
      classifier/visualization/output/figure_4.png
  22. BIN
      classifier/visualization/output/figure_5.png
  23. BIN
      classifier/visualization/output/figure_6.png
  24. BIN
      classifier/visualization/output/figure_7.png
  25. BIN
      classifier/visualization/output/figure_8.png
  26. BIN
      classifier/visualization/output/figure_9.png
  27. 35
      classifier/visualization/visualization.py

22
classifier/feature_extraction/batch_feature_extractor.py

@ -1,7 +1,8 @@
from os import listdir
from os.path import isfile, join
import multiprocessing as mp
from .feature_extractor import extractFeatures
import pandas as pd
from feature_extractor import extractFeatures
class bcolors:
BLUE = '\033[94m'
@ -13,18 +14,21 @@ class bcolors:
def batchExtract(audioFilesPath, featureFilesPath, sampleRate):
audioFiles = [file for file in listdir(audioFilesPath) if isfile(join(audioFilesPath, file))]
# Without multithreading
# for file in audioFiles:
# extractFeatures(audioFilesPath + file,
# featureFilesPath + file[0:file.rfind('.')] + '.json', int(sampleRate))
dataframesList = [None]*len(audioFiles)
pool = mp.Pool(processes = 8)
for file in audioFiles:
pool.apply(extractFeatures,args=(audioFilesPath + file,
featureFilesPath + file[0:file.rfind('.')] + '.json',int(sampleRate)))
pool = mp.Pool()
for process, file in enumerate(audioFiles):
dataframesList[process] = pool.apply_async(extractFeatures,args=(audioFilesPath + file,
featureFilesPath + file[0:file.rfind('.')] + '.json',int(sampleRate))).get()
pool.close()
pool.join()
joinedDataset = pd.concat(dataframesList)
print('Batch feature extraction finished successfully.')
return joinedDataset
# Prints a nice message to let the user know the module was imported
print(bcolors.BLUE + 'batch_feature_extractor loaded' + bcolors.ENDC)

4
classifier/feature_extraction/feature_extractor.py

@ -1,4 +1,6 @@
import essentia
import pandas as pd
import numpy as np
from essentia.standard import (MonoLoader, Windowing, Spectrum, MFCC,
ZeroCrossingRate, SpectralCentroidTime, RollOff, Flux, Envelope,
FlatnessSFX, LogAttackTime, StrongDecay, FlatnessDB, HFC,
@ -95,6 +97,8 @@ def extractFeatures(audio, outputPath, sampleRate):
YamlOutput(filename = outputPath, format = 'json', writeVersion = False)(pool)
return pd.DataFrame(np.array([pool[i] for i in pool.descriptorNames()]).T, columns = pool.descriptorNames())
def _4HzModulation(melEnergies, frameEnergy, sampleRate):
from scipy.signal import butter, sosfilt, sosfreqz
nyquist = 0.5 * sampleRate

22
classifier/pipeline.py

@ -1,24 +1,26 @@
import numpy as np
import pandas as pd
from feature_extraction.feature_extractor import extractFeatures
from feature_extraction.batch_feature_extractor import batchExtract
from preprocessing.data_preprocessing import arrayFromJSON, createSingleFeaturesArray, standardization, PCA
from preprocessing.data_preprocessing import arrayFromJSON, standardization, PCA
from training.model_training import simpleTrain, kFCrossValid
batchExtract('../dataset/music_wav/', 'feature_extraction/music_features/', 22050)
batchExtract('../dataset/speech_wav/', 'feature_extraction/speech_features/', 22050)
musicFeatures = batchExtract('../dataset/music_wav/', 'feature_extraction/music_features/', 22050)
musicFeatures = musicFeatures.assign(target=0)
speechFeatures = batchExtract('../dataset/speech_wav/', 'feature_extraction/speech_features/', 22050)
speechFeatures = speechFeatures.assign(target=1)
dataset, target, featureKeys = createSingleFeaturesArray(
'feature_extraction/music_features/',
'feature_extraction/speech_features/')
dataset = pd.concat([musicFeatures, speechFeatures])
target = dataset.pop('target').values
dataset = standardization(dataset)
# dataset = PCA(dataset)
print('Simple train accuracy achieved = ' + str(simpleTrain(dataset, target)))
kFCrossValid(dataset, target, model = 'svm')
clf = kFCrossValid(dataset, target, model = 'rndForest')
extractFeatures('compined.wav', 'featuresStream/tmp.json', 22050)
values = arrayFromJSON('featuresStream/tmp.json')[1]
values = standardization(values)
audioClass = clf.predict(values)
features = extractFeatures('compined.wav', 'tmp.json', 22050)
features = standardization(features)
audioClass = clf.predict(features)
print(audioClass)

0
classifier/preprocessing/__init__.py

17
classifier/preprocessing/data_preprocessing.py

@ -1,6 +1,7 @@
from os import listdir
from os.path import isfile, join
import numpy as np
import pandas as pd
import json
class bcolors:
@ -77,12 +78,10 @@ def PCA(dataset):
from sklearn.decomposition import PCA
print(bcolors.YELLOW + 'Running PCA' + bcolors.ENDC)
pca = PCA(n_components=15, svd_solver='full', whiten = True)
pca = PCA(n_components=10, svd_solver='full', whiten = True)
transformedDataset = pca.fit(dataset).transform(dataset)
# TODO: change the return value after the values of the parameters are decided
# and the feature selection is complete
return transformedDataset
return pca, transformedDataset
# Prints a nice message to let the user know the module was imported
print(bcolors.BLUE + 'feature_preprocessing loaded' + bcolors.ENDC)
@ -91,9 +90,9 @@ print(bcolors.BLUE + 'feature_preprocessing loaded' + bcolors.ENDC)
if __name__ == "__main__":
import sys
dataset, target, featureKeys = createSingleFeaturesArray(sys.argv[1], sys.argv[2])
newDataset = PCA(standardization(dataset))
scaledDataset = standardization(dataset)
print(bcolors.GREEN + 'Saving results to files' + bcolors.ENDC)
np.save('dataset.npy', newDataset)
np.save('target.npy', target)
np.save('featureKeys.npy', featureKeys)
print(bcolors.GREEN + 'Saving scaled results to file' + bcolors.ENDC)
datasetFrame = pd.DataFrame(scaledDataset, columns = featureKeys)
datasetFrame = datasetFrame.assign(target=target)
datasetFrame.to_pickle("./dataset.pkl")

BIN
classifier/preprocessing/dataset.npy

Binary file not shown.

BIN
classifier/preprocessing/dataset.pkl

Binary file not shown.

BIN
classifier/preprocessing/featureKeys.npy

Binary file not shown.

BIN
classifier/preprocessing/target.npy

Binary file not shown.

55
classifier/test/accuracyWithoutFeature.py

@ -1,55 +1,28 @@
import numpy as np
import pandas as pd
from sys import path
path.append('..')
from feature_extraction.batch_feature_extractor import batchExtract
from preprocessing.data_preprocessing import createSingleFeaturesArray, standardization
from classification_model_training.model_training import simpleTrain
from preprocessing.data_preprocessing import standardization
from training.model_training import simpleTrain
batchExtract('../../dataset/music_wav/', '../feature_extraction/music_features/', 22050)
batchExtract('../../dataset/speech_wav/', '../feature_extraction/speech_features/', 22050)
musicFeatures = batchExtract('../../dataset/music_wav/', '../feature_extraction/music_features/', 22050)
musicFeatures = musicFeatures.assign(target=0)
speechFeatures = batchExtract('../../dataset/speech_wav/', '../feature_extraction/speech_features/', 22050)
speechFeatures = speechFeatures.assign(target=1)
dataset, target, featureKeys = createSingleFeaturesArray(
'../feature_extraction/music_features/',
'../feature_extraction/speech_features/')
dataset = pd.concat([musicFeatures, speechFeatures])
target = dataset.pop('target').values
dataset = standardization(dataset)
dataset = pd.DataFrame(standardization(dataset), columns = dataset.columns.values)
wholeAccuracy = simpleTrain(dataset, target, 'svm')
print('Accuracy using whole dataset = ' + str(wholeAccuracy))
damages = np.zeros(featureKeys.size)
damages = np.zeros(dataset.columns.values.size)
for index, key in enumerate(featureKeys):
acc = simpleTrain(np.delete(dataset, index, axis=1), target, 'svm')
for index, key in enumerate(dataset.columns.values):
acc = simpleTrain(dataset.drop(key, axis=1), target, 'svm')
damages[index] = 100*(wholeAccuracy-acc)
print('Accuracy without ' + key + '\t= ' + str(acc) +
',\tdamage\t= ' + "%.2f" % damages[index] + '%')
# Accuracy using whole dataset = 0.951902893127681
# Accuracy without 4HzMod = 0.9456968148215752, damage = 0.62%
# Accuracy without Flat = 0.9523592224148946, damage = -0.05%
# Accuracy without HFC = 0.9526330199872228, damage = -0.07%
# Accuracy without LAtt = 0.9524504882723374, damage = -0.05%
# Accuracy without SC = 0.9520854248425664, damage = -0.02%
# Accuracy without SComp = 0.948160992972529, damage = 0.37%
# Accuracy without SDec = 0.9520854248425664, damage = -0.02%
# Accuracy without SEFlat = 0.9513552979830245, damage = 0.05%
# Accuracy without SF = 0.9492561832618417, damage = 0.26%
# Accuracy without SFlat = 0.9496212466916126, damage = 0.23%
# Accuracy without SLAtt = 0.9498950442639409, damage = 0.20%
# Accuracy without SR = 0.9523592224148946, damage = -0.05%
# Accuracy without SSDec = 0.9519941589851236, damage = -0.01%
# Accuracy without ZCR = 0.9500775759788264, damage = 0.18%
# Accuracy without mfcc0 = 0.9502601076937118, damage = 0.16%
# Accuracy without mfcc1 = 0.9510815004106964, damage = 0.08%
# Accuracy without mfcc10 = 0.9503513735511545, damage = 0.16%
# Accuracy without mfcc11 = 0.9492561832618417, damage = 0.26%
# Accuracy without mfcc12 = 0.9482522588299717, damage = 0.37%
# Accuracy without mfcc2 = 0.9446928903897052, damage = 0.72%
# Accuracy without mfcc3 = 0.9465182075385599, damage = 0.54%
# Accuracy without mfcc4 = 0.9470658026832162, damage = 0.48%
# Accuracy without mfcc5 = 0.9463356758236744, damage = 0.56%
# Accuracy without mfcc6 = 0.9452404855343616, damage = 0.67%
# Accuracy without mfcc7 = 0.9462444099662316, damage = 0.57%
# Accuracy without mfcc8 = 0.9490736515469563, damage = 0.28%
# Accuracy without mfcc9 = 0.9472483343981016, damage = 0.47%
',\tdamage\t= ' + "%.2f" % damages[index] + '%')

0
classifier/training/__init__.py

BIN
classifier/visualization/output/figure_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

BIN
classifier/visualization/output/figure_10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

BIN
classifier/visualization/output/figure_11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

BIN
classifier/visualization/output/figure_12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

BIN
classifier/visualization/output/figure_13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

BIN
classifier/visualization/output/figure_14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

BIN
classifier/visualization/output/figure_15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

BIN
classifier/visualization/output/figure_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

BIN
classifier/visualization/output/figure_3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

BIN
classifier/visualization/output/figure_4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

BIN
classifier/visualization/output/figure_5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

BIN
classifier/visualization/output/figure_6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

BIN
classifier/visualization/output/figure_7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

BIN
classifier/visualization/output/figure_8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

BIN
classifier/visualization/output/figure_9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

35
classifier/visualization/visualization.py

@ -4,14 +4,31 @@ import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
datasetArray = np.load('../preprocessing/dataset.npy')
target = np.load('../preprocessing/target.npy')
featureKeysVector = np.load('../preprocessing/featureKeys.npy')
dataset = pd.read_pickle('../preprocessing/dataset.pkl')
target = dataset.pop('target')
dataset = pd.DataFrame(datasetArray)
dataset.columns = featureKeysVector
# Feature evaluation
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel
sns.relplot(x="4HzMod", y="Flat", data=dataset[["4HzMod", "Flat"]], hue = target, style = target)
sns.jointplot(x="SLAtt", y="ZCR", data=dataset[["SLAtt", "ZCR"]]);
sns.pairplot(data=dataset[["SDec", "Flat", "mfcc2", "HFC"]]);
plt.show()
clf = ExtraTreesClassifier(n_estimators=1000)
clf = clf.fit(dataset, target)
model = SelectFromModel(clf, prefit=True, max_features = 6)
print('Retaining features:')
print(dataset.columns.values[model.get_support()])
reducedDataset = pd.DataFrame(model.transform(dataset),
columns = dataset.columns.values[model.get_support()])
# Every combination of the 6 best features with length equal to 4 features
import itertools
featureCombinations = itertools.combinations(range(6), 4)
for plotIndex, subset in enumerate(featureCombinations):
featurePlot = sns.pairplot(data=(reducedDataset.iloc[:, list(subset)]).assign(target=target),
hue='target', palette='Set1', vars=reducedDataset.columns.values[list(subset)]);
featurePlot.fig.savefig("output/figure_" + str(plotIndex+1) + ".png")
# sns.relplot(x="4HzMod", y="Flat", data=dataset[["4HzMod", "Flat"]], hue = target, style = target)
# sns.jointplot(x="SLAtt", y="ZCR", data=dataset[["SLAtt", "ZCR"]]);
# plt.show()

Loading…
Cancel
Save