Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mean of empty slice and Degrees of freedom <=0

This code below is suppose to run a bayes classifier for a full covariance gaussian (http://courses.ee.sun.ac.za/Pattern_Recognition_813/lectures/lecture03/node2.html), but I get two errors when I run the code. They are:

RuntimeWarning: Mean of empty slice.
  warnings.warn("Mean of empty slice.", RuntimeWarning)

and

RuntimeWarning: Degrees of freedom <= 0 for slice
  warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)

This is my code:

def modelFull(train, test):
    err_train = 0
    err_test = 0
    x_train = []
    x_test = []
    labels = []
    train_labels = []
    test_labels = []
    for i in train:
        x_train.append(i[:-1]/255)
        labels.append(i[-1])
        train_labels.append(i[-1])
    for i in test:
        x_test.append(i[:-1]/255)
        labels.append(i[-1])
        test_labels.append(i[-1])
    x_train = np.array(x_train)
    x_0 = []
    x_1 = []
    for i in train:
        if i[-1] == 0:
            x_0.append(i[:-1]/255)
        if i[-1] == 1:
            x_1.append(i[:-1]/255)
    x_0 = np.array(x_0)
    x_1 = np.array(x_1)
    p_0 = float(x_0.shape[0])/float((x_0.shape[0]+x_1.shape[0]))
    p_1 = float(x_1.shape[0])/float((x_0.shape[0]+x_1.shape[0]))
    train_x0_mean = x_0.mean(axis=0)
    train_x1_mean = x_1.mean(axis=0)
    cov_x0 = np.cov(np.transpose(x_0))
    cov_x1 = np.cov(np.transpose(x_1))
    cov_x0 = cov_x0 + np.eye(256) * .01
    cov_x1 = cov_x1 + np.eye(256) * .01
    det_x1_cov = -float(np.linalg.slogdet(cov_x1)[1])
    det_x0_cov = -float(np.linalg.slogdet(cov_x0)[1])
    train_results = []
    test_results = []
    for x in x_train:
        x0_minus_mu_T = np.transpose((x-train_x0_mean))
        x0_inverse = np.linalg.inv(cov_x0)
        x0_minus_mu = x-train_x0_mean
        x1_minus_mu_T = np.transpose((x-train_x1_mean))
        x1_inverse = np.linalg.inv(cov_x1)
        x1_minus_mu = x-train_x1_mean
        x_0_probability = det_x0_cov - (x0_minus_mu_T.dot(x0_inverse)).dot(x0_minus_mu)
        x_1_probability = det_x1_cov - (x1_minus_mu_T.dot(x1_inverse)).dot(x1_minus_mu)
        if (x_0_probability+np.log(p_0))/(x_1_probability+np.log(p_1)) < 1:
            train_results.append(1)
        else:
            train_results.append(0)
    for x in x_test:
        x0_minus_mu_T = np.transpose((x-train_x0_mean))
        x0_inverse = np.linalg.inv(cov_x0)
        x0_minus_mu = x-train_x0_mean
        x1_minus_mu_T = np.transpose((x-train_x1_mean))
        x1_inverse = np.linalg.inv(cov_x1)
        x1_minus_mu = x-train_x1_mean
        x_0_probability = det_x0_cov - (x0_minus_mu_T.dot(x0_inverse)).dot(x0_minus_mu)
        x_1_probability = det_x1_cov - (x1_minus_mu_T.dot(x1_inverse)).dot(x1_minus_mu)
        if (x_0_probability+np.log(p_0))/(x_1_probability+np.log(p_1)) < 1:
            test_results.append(1)
        else:
            test_results.append(0)

    train_correct = 0
    test_correct = 0
    for i in range(len(train_results)):
        if int(train_results[i]) == int(train_labels[i]):
            train_correct +=1

    for i in range(len(test_results)):
        if int(test_results[i]) == int(test_labels[i]):
            test_correct +=1

    err_train =  1-(float(test_correct)/ len(test_results))
    err_train =  1-(float(train_correct)/ len(train_results))

    return err_train, err_test
like image 355
user3002936 Avatar asked Apr 08 '17 22:04

user3002936


2 Answers

RuntimeWarning: Degrees of freedom <= 0 for slice

occurs when you use the wrong shape, e.g.:

import numpy as np

x = np.random.random([1000,1])
y = np.random.random([1000,1])
print(x.shape, y.shape)
# (1000, 1) (1000, 1)
t = np.cov(x, y) #RuntimeWarning
t = np.cov(x.T, y.T) #This works
like image 98
Martin Fesser Avatar answered Oct 20 '22 02:10

Martin Fesser


An edge case is: the array you calculate covariance on only contains one element.

np.cov([0.5])
like image 3
Chenlu Avatar answered Oct 20 '22 04:10

Chenlu