1

I'm building a basic speaker recognizer with the GMM toolkit from sklearn. I have 3 classes, for each class I have a classifier. In the testing stage, the GMM for the speaker with the highest probability should be selected and the program should return the predicted class for each test sample. I want to vary the number of mixture components and set n_components=4 in this example code. If I use 4 mixture components the output of my classifier will either be 0, 1, 2 or 3. If I use 3 mixture components, it will be 0, 1 or 2. I have the feeling that the classifier returns the predicted mixture component instead of the whole GMM. But I want it to predict the class: 1, 2 or 3.

Here is my code:

import numpy as np
from sklearn.mixture import GMM

#set path
path="path"

class_names = [1,2,3]

covs =  ['spherical', 'diag', 'tied', 'full']

training_data = {1: np.loadtxt(path+"/01_train_debug.data"), 2:  np.loadtxt(path+"/02_train_debug.data"), 3: np.loadtxt(path+"/03_train_debug.data")}

print "Training models"
models = {}
for c in class_names:
    # make a GMM for each of the classes in class_names
    models[c] = dict((covar_type,GMM(n_components=4,
                    covariance_type=covar_type, init_params='wmc',n_init=1, n_iter=20))
                   for covar_type in covs)


for cov in covs:
    for c in class_names:
            models[c][cov].fit(training_data[c])

#define test set
test01 = np.loadtxt(path+"/01_test_debug.data")
test02 = np.loadtxt(path+"/02_test_debug.data")
test03 = np.loadtxt(path+"/03_test_debug.data")

testing_data = {1: test01, 2: test02, 3: test03}

probs = {}

print "Calculating Probabilities"

for c in class_names:
    probs[c] = {}
    for cov in covs:
        probs[c][cov] = {}
        for p in class_names:
            probs[c][cov] = models[p][cov].predict(testing_data[c])


for c in class_names:
    print c
    for cov in covs:
        print "   ",cov,
        for p in class_names:
            print p, probs,
        print 

Is my assumption from above correct or do I have a logical error in my code? Is there a way to solve this in sklearn? Thanks in advance for your help!

Ray
  • 2,472
  • 18
  • 22
Kaly
  • 3,289
  • 4
  • 24
  • 25

1 Answers1

3

In your code, the first time you the keys of the models dict are covariance types and the second time the keys are class names. I misread your code, sorry.

Edit: if you want the per-sample likelihood of the data under a fitted GMM models you should use the score_samples method. The predict method does not return probabilities but component assignments instead.

Also GMM by default is non supervised model. If you want to build a supervised model out of a bunch GMM models, you should probably wrap it as an estimator class that wraps them and implement the fit / predict API to be able to estimate its accuracy via cross validation and adjust the hyper parameter values by grid search. Pull request #2468 is implementing something like this. It it's merged in time it might get included in the next scikit-learn release (0.15 that should come out early 2014).

ogrisel
  • 39,309
  • 12
  • 116
  • 125
  • Thanks! I used the score_samples method initially but wasn't sure how to calculate a confusion matrix from the results. Will switch back and give it a try! – Kaly Dec 16 '13 at 09:37
  • You have to take the class that matches the model with the highest score for each sample. – ogrisel Dec 16 '13 at 09:51
  • @ogrisel hi, I was wondering if you could have a look at a similar problem in my [post](https://stackoverflow.com/questions/63414169/how-can-implement-em-gmm-in-python) Thanks in advance. – Mario Aug 14 '20 at 13:58