%matplotlib inline
import seaborn
import numpy, scipy, matplotlib.pyplot as plt, sklearn, librosa, urllib, IPython.display, stanford_mir
plt.rcParams['figure.figsize'] = (14,5)
We can appreciate why we need additional intelligence in our systems -- heuristics don't go very far in the world of complex audio signals. We'll be using scikit-learn's implementation of the k-NN algorithm for our work here. It proves be a straightforward and easy-to-use implementation. The steps and skills of working with one classifier will scale nicely to working with other, more complex classifiers.
Let's begin by loading some training data. We will use the following convenience function written for this workshop:
training_features, training_labels, scaler = stanford_mir.get_features(collection="drum_samples_train", download=False)
This function returns three outputs: a list of training feature vectors, each containing zero crossing rate and spectral centroid; the ground truth labels of the training data; and a scaler
object of type sklearn.preprocessing.MinMaxScaler
. scaler
simply scales every training feature vector such that the two features lie between -1 and 1.
Show the training labels. 0
is a kick drum, and 1
is a snare drum.
print training_labels
Show the training feature vectors.
print training_features
Plot the training data:
plt.scatter(training_features[:10,0], training_features[:10,1])
plt.scatter(training_features[10:,0], training_features[10:,1], color='r')
plt.xlabel('Zero Crossing Rate')
plt.ylabel('Spectral Centroid')
Compute features from a test data set of 30 kick drum samples and 30 snare drum samples. We will re-use the MinMaxScaler
used during training.
test_features, test_labels, _ = stanford_mir.get_features(collection="drum_samples_test", scaler=scaler, download=False)
Let's see how many test examples were loaded:
print test_features.shape
Show the test labels:
print test_labels
Plot the test feature vectors. Note that this uses the same scaling function used during training. Therefore, some test feature vectors may exceed the range [-1, 1].
plt.scatter(test_features[test_labels==0,0], test_features[test_labels==0,1])
plt.scatter(test_features[test_labels==1,0], test_features[test_labels==1,1], color='r')
plt.xlabel('Zero Crossing Rate')
plt.ylabel('Spectral Centroid')
Build a k-NN model for the snare drums using scikit.learn's KNeighborsClassifier class.
model = sklearn.neighbors.KNeighborsClassifier(n_neighbors=1)
To train a scikit-learn classifier, use the classifier object's fit
method:
model.fit(training_features, training_labels)
To test the classifier on a set of (test) feature vectors, use the predict
method:
predicted_labels = model.predict(test_features)
predicted_labels
Compute the number of true positives, true negatives, false positives, and false negatives:
tp = sum((test_labels == 1) & (predicted_labels == 1))
tn = sum((test_labels == 0) & (predicted_labels == 0))
fp = sum((test_labels == 0) & (predicted_labels == 1))
fn = sum((test_labels == 1) & (predicted_labels == 0))
print tp, tn, fp, fn
Evaluate the model accuracy on the test data.
model.score(test_features, test_labels)
Compute the recall score, and verify it is correct:
sklearn.metrics.recall_score(test_labels, predicted_labels)
recall = tp/float(tp+fn)
print recall
Compute the precision score, and verify:
sklearn.metrics.precision_score(test_labels, predicted_labels)
precision = tp/float(tp+fp)
print precision
Compute the F-measure, and verify:
sklearn.metrics.f1_score(test_labels, predicted_labels)
fmeasure = 2*recall*precision/float(recall+precision)
print fmeasure
Substitute the k-NN model with a different classifer, and repeat the above classification. For example:
#model = sklearn.svm.SVC()