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
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
An edge case is: the array you calculate covariance on only contains one element.
np.cov([0.5])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With