From 89c7366c4e81d71bb509888dd64db3bc7bb09c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana?= Date: Wed, 7 Dec 2022 01:27:28 +0100 Subject: [PATCH] Add python implementation of the algorithm --- fimdlp/main | Bin 0 -> 239361 bytes fimdlp/mdlp.py | 5 +- fimdlp/pyfimdlp.py | 142 ++++++++++++++++++++++++++++++++++++ fimdlp/tests/FImdlp_test.py | 10 +-- sample.py | 128 ++++++++++++++++---------------- 5 files changed, 212 insertions(+), 73 deletions(-) create mode 100755 fimdlp/main create mode 100644 fimdlp/pyfimdlp.py diff --git a/fimdlp/main b/fimdlp/main new file mode 100755 index 0000000000000000000000000000000000000000..5e9e630cced5788d2004e1c2f25be7dd724b98ee GIT binary patch literal 239361 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 term + + def num_classes(self, start, end): + n_classes = set() + for i in range(start, end): + n_classes.add( + self.y_[self.indices_[i]] if self.use_indices else self.y_[i] + ) + return len(n_classes) + + def get_candidate(self, start, end): + """Return the best cutpoint candidate for the given range. + + Parameters + ---------- + start : int + Start of the range. + end : int + End of the range. + + Returns + ------- + candidate : SimpleNamespace with attributes index and value + value == None if no candidate is found. + """ + candidate = SimpleNamespace() + candidate.value = None + minEntropy = float("inf") + for idx in range(start + 1, end): + condition = ( + self.y_[self.indices_[idx]] == self.y_[self.indices_[idx - 1]] + if self.use_indices + else self.y_[idx] == self.y_[idx - 1] + ) + if condition: + continue + entropy_left = self.entropy(start, idx) + entropy_right = self.entropy(idx, end) + entropy_cut = entropy_left + entropy_right + if entropy_cut < minEntropy: + minEntropy = entropy_cut + candidate.index = idx + if self.use_indices: + candidate.value = ( + self.X_[self.indices_[idx]] + + self.X_[self.indices_[idx - 1]] + ) / 2 + else: + candidate.value = (self.X_[idx] + self.X_[idx - 1]) / 2 + return candidate + + def entropy(self, start, end) -> float: + n_labels = end - start + if n_labels <= 1: + return 0 + if (start, end) in self.entropy_cache: + return self.entropy_cache[(start, end)] + if self.use_indices: + counts = np.bincount(self.y_[self.indices_[start:end]]) + else: + counts = np.bincount(self.y_[start:end]) + proportions = counts / n_labels + n_classes = np.count_nonzero(proportions) + if n_classes <= 1: + return 0 + entropy = 0.0 + # Compute standard entropy. + for prop in proportions: + if prop != 0.0: + entropy -= prop * log(prop, 2) + self.entropy_cache[(start, end)] = entropy + return entropy + + def information_gain(self, start, cut, end): + if (start, cut, end) in self.information_gain_cache: + return self.information_gain_cache[(start, cut, end)] + labels = end - start + if labels == 0: + return 0.0 + entropy = self.entropy(start, end) + card_left = cut - start + entropy_left = self.entropy(start, cut) + card_right = end - cut + entropy_right = self.entropy(cut, end) + result = ( + entropy + - (card_left / labels) * entropy_left + - (card_right / labels) * entropy_right + ) + self.information_gain_cache[(start, cut, end)] = result + return result diff --git a/fimdlp/tests/FImdlp_test.py b/fimdlp/tests/FImdlp_test.py index 08aff11..6d136ee 100644 --- a/fimdlp/tests/FImdlp_test.py +++ b/fimdlp/tests/FImdlp_test.py @@ -31,13 +31,9 @@ class FImdlpTest(unittest.TestCase): [0.75, 1.399999976158142, 1.5], ] self.assertListEqual(expected, clf.get_cut_points()) - self.assertListEqual( - ["feature_0", "feature_1", "feature_2", "feature_3"], clf.features_ - ) - self.assertEqual("class", clf.class_name_) - clf.fit(X, y, features=["a", "b", "c", "d"], class_name="class_name") - self.assertListEqual(["a", "b", "c", "d"], clf.features_) - self.assertEqual("class_name", clf.class_name_) + self.assertListEqual([0, 1, 2, 3], clf.features_) + clf.fit(X, y, features=[0, 2, 3]) + self.assertListEqual([0, 2, 3], clf.features_) def test_fit_Errors(self): clf = FImdlp() diff --git a/sample.py b/sample.py index e6e7525..3378203 100644 --- a/sample.py +++ b/sample.py @@ -61,69 +61,69 @@ data = load_iris() X = data.data y = data.target features = data.feature_names -# test = FImdlp() -# test.fit(X, y, features=features) -# test.transform(X) -# test.get_cut_points() -for proposal in [True, False]: - X = data.data - y = data.target - print("*** Proposal: ", proposal) - test = CFImdlp(debug=True, proposal=proposal) - test.fit(X[:, 0], y) - result = test.get_cut_points() - for item in result: - print( - f"Class={item['classNumber']} - ({item['start']:3d}, " - f"{item['end']:3d}) -> ({item['fromValue']:3.1f}, " - f"{item['toValue']:3.1f}]" - ) - print(test.get_discretized_values()) - print("+" * 40) - X = np.array( - [ - [5.1, 3.5, 1.4, 0.2], - [5.2, 3.0, 1.4, 0.2], - [5.3, 3.2, 1.3, 0.2], - [5.4, 3.1, 1.5, 0.2], - ] - ) - y = np.array([0, 0, 0, 1]) - print(test.fit(X[:, 0], y).transform(X[:, 0])) - result = test.get_cut_points() - for item in result: - print( - f"Class={item['classNumber']} - ({item['start']:3d}, {item['end']:3d})" - f" -> ({item['fromValue']:3.1f}, {item['toValue']:3.1f}]" - ) - print("*" * 40) -# print(Xs, ys) -# print("**********************") -# test = [(0, 3), (4, 4), (5, 5), (6, 8), (9, 9)] -# print(ys) -# for start, end in test: -# print("Testing ", start, end, ys[:end], ys[end:]) -# print("Information gain: ", information_gain(ys, ys[:end], ys[end:])) -# print(test.transform(X)) -# print(X) -# print(indices) -# print(np.array(X)[indices]) +test = FImdlp() +test.fit(X, y) +test.transform(X) +print(test.get_cut_points()) +# for proposal in [True, False]: +# X = data.data +# y = data.target +# print("*** Proposal: ", proposal) +# test = CFImdlp(debug=True, proposal=proposal) +# test.fit(X[:, 0], y) +# result = test.get_cut_points() +# for item in result: +# print( +# f"Class={item['classNumber']} - ({item['start']:3d}, " +# f"{item['end']:3d}) -> ({item['fromValue']:3.1f}, " +# f"{item['toValue']:3.1f}]" +# ) +# print(test.get_discretized_values()) +# print("+" * 40) +# X = np.array( +# [ +# [5.1, 3.5, 1.4, 0.2], +# [5.2, 3.0, 1.4, 0.2], +# [5.3, 3.2, 1.3, 0.2], +# [5.4, 3.1, 1.5, 0.2], +# ] +# ) +# y = np.array([0, 0, 0, 1]) +# print(test.fit(X[:, 0], y).transform(X[:, 0])) +# result = test.get_cut_points() +# for item in result: +# print( +# f"Class={item['classNumber']} - ({item['start']:3d}, {item['end']:3d})" +# f" -> ({item['fromValue']:3.1f}, {item['toValue']:3.1f}]" +# ) +# print("*" * 40) +# # print(Xs, ys) +# # print("**********************") +# # test = [(0, 3), (4, 4), (5, 5), (6, 8), (9, 9)] +# # print(ys) +# # for start, end in test: +# # print("Testing ", start, end, ys[:end], ys[end:]) +# # print("Information gain: ", information_gain(ys, ys[:end], ys[end:])) +# # print(test.transform(X)) +# # print(X) +# # print(indices) +# # print(np.array(X)[indices]) -# # k = test.cut_points(X[:, 0], y) -# # print(k) -# # k = test.cut_points_ant(X[:, 0], y) -# # print(k) -# # test.debug_points(X[:, 0], y) -# X = [5.7, 5.3, 5.2, 5.1, 5.0, 5.6, 5.1, 6.0, 5.1, 5.9] -# y = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] -# indices = [4, 3, 6, 8, 2, 1, 5, 0, 9, 7] -# clf = CFImdlp(debug=True, proposal=False) -# clf.fit(X, y) -# print(clf.get_cut_points()) -# y = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] -# # To check -# indices2 = np.argsort(X) -# Xs = np.array(X)[indices2] -# ys = np.array(y)[indices2] -kdd_JapaneseVowels +# # # k = test.cut_points(X[:, 0], y) +# # # print(k) +# # # k = test.cut_points_ant(X[:, 0], y) +# # # print(k) +# # # test.debug_points(X[:, 0], y) +# # X = [5.7, 5.3, 5.2, 5.1, 5.0, 5.6, 5.1, 6.0, 5.1, 5.9] +# # y = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] +# # indices = [4, 3, 6, 8, 2, 1, 5, 0, 9, 7] +# # clf = CFImdlp(debug=True, proposal=False) +# # clf.fit(X, y) +# # print(clf.get_cut_points()) +# # y = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] +# # # To check +# # indices2 = np.argsort(X) +# # Xs = np.array(X)[indices2] +# # ys = np.array(y)[indices2] +# kdd_JapaneseVowels