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

4
classifier/feature_extraction/feature_extractor.py

@ -1,4 +1,6 @@
import essentia import essentia
import pandas as pd
import numpy as np
from essentia.standard import (MonoLoader, Windowing, Spectrum, MFCC, from essentia.standard import (MonoLoader, Windowing, Spectrum, MFCC,
ZeroCrossingRate, SpectralCentroidTime, RollOff, Flux, Envelope, ZeroCrossingRate, SpectralCentroidTime, RollOff, Flux, Envelope,
FlatnessSFX, LogAttackTime, StrongDecay, FlatnessDB, HFC, FlatnessSFX, LogAttackTime, StrongDecay, FlatnessDB, HFC,
@ -95,6 +97,8 @@ def extractFeatures(audio, outputPath, sampleRate):
YamlOutput(filename = outputPath, format = 'json', writeVersion = False)(pool) 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): def _4HzModulation(melEnergies, frameEnergy, sampleRate):
from scipy.signal import butter, sosfilt, sosfreqz from scipy.signal import butter, sosfilt, sosfreqz
nyquist = 0.5 * sampleRate nyquist = 0.5 * sampleRate

22
classifier/pipeline.py

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

0
classifier/preprocessing/__init__.py

17
classifier/preprocessing/data_preprocessing.py

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

53
classifier/test/accuracyWithoutFeature.py

@ -1,55 +1,28 @@
import numpy as np import numpy as np
import pandas as pd
from sys import path from sys import path
path.append('..') path.append('..')
from feature_extraction.batch_feature_extractor import batchExtract from feature_extraction.batch_feature_extractor import batchExtract
from preprocessing.data_preprocessing import createSingleFeaturesArray, standardization from preprocessing.data_preprocessing import standardization
from classification_model_training.model_training import simpleTrain from training.model_training import simpleTrain
batchExtract('../../dataset/music_wav/', '../feature_extraction/music_features/', 22050) musicFeatures = batchExtract('../../dataset/music_wav/', '../feature_extraction/music_features/', 22050)
batchExtract('../../dataset/speech_wav/', '../feature_extraction/speech_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( dataset = pd.concat([musicFeatures, speechFeatures])
'../feature_extraction/music_features/', target = dataset.pop('target').values
'../feature_extraction/speech_features/')
dataset = standardization(dataset) dataset = pd.DataFrame(standardization(dataset), columns = dataset.columns.values)
wholeAccuracy = simpleTrain(dataset, target, 'svm') wholeAccuracy = simpleTrain(dataset, target, 'svm')
print('Accuracy using whole dataset = ' + str(wholeAccuracy)) 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): for index, key in enumerate(dataset.columns.values):
acc = simpleTrain(np.delete(dataset, index, axis=1), target, 'svm') acc = simpleTrain(dataset.drop(key, axis=1), target, 'svm')
damages[index] = 100*(wholeAccuracy-acc) damages[index] = 100*(wholeAccuracy-acc)
print('Accuracy without ' + key + '\t= ' + str(acc) + print('Accuracy without ' + key + '\t= ' + str(acc) +
',\tdamage\t= ' + "%.2f" % damages[index] + '%') ',\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%

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 import seaborn as sns
sns.set() sns.set()
datasetArray = np.load('../preprocessing/dataset.npy') dataset = pd.read_pickle('../preprocessing/dataset.pkl')
target = np.load('../preprocessing/target.npy') target = dataset.pop('target')
featureKeysVector = np.load('../preprocessing/featureKeys.npy')
dataset = pd.DataFrame(datasetArray) # Feature evaluation
dataset.columns = featureKeysVector 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) clf = ExtraTreesClassifier(n_estimators=1000)
sns.jointplot(x="SLAtt", y="ZCR", data=dataset[["SLAtt", "ZCR"]]); clf = clf.fit(dataset, target)
sns.pairplot(data=dataset[["SDec", "Flat", "mfcc2", "HFC"]]);
plt.show() 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