|
| 1 | +# ====================================================== |
| 2 | +# Copyright (C) 2020 repa1030 |
| 3 | +# This program and the accompanying materials |
| 4 | +# are made available under the terms of the MIT license. |
| 5 | +# ====================================================== |
| 6 | +from math import sqrt |
| 7 | +from math import pi |
| 8 | +from math import exp |
| 9 | +import operator |
| 10 | + |
| 11 | +class BayesGaussian(): |
| 12 | + |
| 13 | + # init |
| 14 | + def __init__(self, data_train, data_test, detection_classes): |
| 15 | + self.train_data = data_train |
| 16 | + self.test_data = data_test |
| 17 | + self.det_cl = detection_classes |
| 18 | + |
| 19 | + # calc mean of a list of numbers |
| 20 | + def mean(self, numbers): |
| 21 | + mean = sum(numbers) / float(len(numbers)) |
| 22 | + return mean |
| 23 | + |
| 24 | + # calc sigma of a list of numbers |
| 25 | + # sigma = sqrt( sum from i to N [ (x_i - x_mean)^2 ] / (N-1) ) |
| 26 | + def standard_devation(self, numbers): |
| 27 | + avg = self.mean(numbers) |
| 28 | + sum_num = 0.0 |
| 29 | + for x in numbers: |
| 30 | + sum_num = sum_num + ((x - avg) * (x - avg)) |
| 31 | + sig = sqrt(sum_num / float(len(numbers)-1)) |
| 32 | + return sig |
| 33 | + |
| 34 | + # calc mean, sigma and count in dataset |
| 35 | + # this function returns a list where mean, sigma, |
| 36 | + # and length of each class is represented |
| 37 | + def sum_dataset(self, dataset): |
| 38 | + summaries = [(self.mean(column), self.standard_devation(column), len(column)) for column in zip(*dataset)] |
| 39 | + # delete statistic for class variable |
| 40 | + del(summaries[0]) |
| 41 | + return summaries |
| 42 | + |
| 43 | + # split data in class and calc statistics |
| 44 | + # input is a unsorted dataset which will be sorted |
| 45 | + # in the first step in a dictionary (keys are the classes) |
| 46 | + # then the statistics for each class (mean, sigma and row count) |
| 47 | + # are calculated and the results are stored in a new dictionary "summaries" |
| 48 | + def sum_class(self, dataset): |
| 49 | + separated_dict = dict() |
| 50 | + for i in range(len(dataset)): |
| 51 | + vector = dataset[i] |
| 52 | + class_value = vector[0] |
| 53 | + if (class_value not in separated_dict): |
| 54 | + separated_dict[class_value] = list() |
| 55 | + separated_dict[class_value].append(vector) |
| 56 | + summaries = dict() |
| 57 | + for class_value, rows in separated_dict.items(): |
| 58 | + summaries[class_value] = self.sum_dataset(rows) |
| 59 | + return summaries |
| 60 | + |
| 61 | + # calc Gaussian probability distribution function for x |
| 62 | + # f(x) = (1 / sqrt(2 * PI) * sigma) * exp(-((x-mean)^2 / (2 * sigma^2))) |
| 63 | + def calc_probability(self, x, mean, sig): |
| 64 | + gauss = (1 / (sqrt(2 * pi) * sig)) * exp(-((x-mean)**2 / (2 * sig**2 ))) |
| 65 | + return gauss |
| 66 | + |
| 67 | + # calc probabilities of predicting each class for a given row (data) |
| 68 | + def calc_class_probabilities(self, summaries, row): |
| 69 | + total_rows = sum([summaries[label][0][2] for label in summaries]) |
| 70 | + probabilities = dict() |
| 71 | + # P(class|data) |
| 72 | + for class_value, class_summaries in summaries.items(): |
| 73 | + # P(class) |
| 74 | + probabilities[class_value] = summaries[class_value][0][2]/float(total_rows) |
| 75 | + i = 0 |
| 76 | + # P(data|class) = P(data1|class) * P(data2|class) * ... |
| 77 | + while i < len(class_summaries): |
| 78 | + mean, sig, count = class_summaries[i] |
| 79 | + probabilities[class_value] *= self.calc_probability(row[i+1], mean, sig) |
| 80 | + i += 1 |
| 81 | + return probabilities |
| 82 | + |
| 83 | + # prediction pipeline |
| 84 | + def predictClass(self): |
| 85 | + cnt_det = 0 |
| 86 | + cnt_all = len(self.test_data) |
| 87 | + sums = self.sum_class(self.train_data) |
| 88 | + for test in self.test_data: |
| 89 | + # get probabilities |
| 90 | + probabilities = self.calc_class_probabilities(sums, test) |
| 91 | + # search highest probability in dictionary |
| 92 | + highest_prob = 0 |
| 93 | + for key in probabilities: |
| 94 | + if (probabilities[key] > highest_prob): |
| 95 | + highest_prob = probabilities[key] |
| 96 | + pred = int(key) |
| 97 | + # display output |
| 98 | + dsp = 'Object class prediction: ' + str(int(pred)) + '\n' |
| 99 | + dsp = dsp + 'Object class ground truth: ' + str(int(test[0])) + '\n' |
| 100 | + cl_set = False |
| 101 | + for cl in self.det_cl: |
| 102 | + if pred in cl: |
| 103 | + pred_obj = cl[0] |
| 104 | + if test[0] in cl: |
| 105 | + gt_obj = cl[0] |
| 106 | + if gt_obj == pred_obj: |
| 107 | + dsp = dsp + 'This object was correctly classified as ' + gt_obj + '\n' |
| 108 | + cnt_det += 1 |
| 109 | + else: |
| 110 | + dsp = dsp + 'This object was falsely classified as ' + pred_obj + '\n' |
| 111 | + dsp = dsp + '####################' |
| 112 | + print(dsp) |
| 113 | + print('\nSummary Bayes: ' + str(cnt_det) + "/" + str(cnt_all) + ' objects are correctly classified.') |
0 commit comments