Repository: dpuenteramirez/Semisupervised-learning-and-instance-selection-methods (language: python)

Issue:
ICF results are 20% down of what is should be
Something in the implementation is wrong
ICF results are 20% down of what is should be
Something in the implementation is wrong
ICF results are 20% down of what is should be
Something in the implementation is wrong
ICF results are 20% down of what is should be
Something in the implementation is wrong
ICF results are 20% down of what is should be
Something in the implementation is wrong
ICF results are 20% down of what is should be
Something in the implementation is wrong


Discussion / hints:
Branch [issue-30-ICF_results_are_20%_down_of_what_is_should_be](https://github.com/dpr1005/Semisupervised-learning-and-instance-selection-methods/tree/issue-30-ICF_results_are_20%_down_of_what_is_should_be) created!
Branch [issue-30-ICF_results_are_20%_down_of_what_is_should_be](https://github.com/dpr1005/Semisupervised-learning-and-instance-selection-methods/tree/issue-30-ICF_results_are_20%_down_of_what_is_should_be) created!
Branch [issue-30-ICF_results_are_20%_down_of_what_is_should_be](https://github.com/dpr1005/Semisupervised-learning-and-instance-selection-methods/tree/issue-30-ICF_results_are_20%_down_of_what_is_should_be) created!
Branch [issue-30-ICF_results_are_20%_down_of_what_is_should_be](https://github.com/dpr1005/Semisupervised-learning-and-instance-selection-methods/tree/issue-30-ICF_results_are_20%_down_of_what_is_should_be) created!
Branch [issue-30-ICF_results_are_20%_down_of_what_is_should_be](https://github.com/dpr1005/Semisupervised-learning-and-instance-selection-methods/tree/issue-30-ICF_results_are_20%_down_of_what_is_should_be) created!
Branch [issue-30-ICF_results_are_20%_down_of_what_is_should_be](https://github.com/dpr1005/Semisupervised-learning-and-instance-selection-methods/tree/issue-30-ICF_results_are_20%_down_of_what_is_should_be) created!

Fix patch:
diff --git a/Instance Selection Algorithms/ENN.py b/Instance Selection Algorithms/ENN.py
index caf8e2a..124da5d 100644
--- a/Instance Selection Algorithms/ENN.py
+++ b/Instance Selection Algorithms/ENN.py
@@ -3,6 +3,9 @@
 # @Filename:    ENN.py
 # @Author:      Daniel Puente Ramírez
 # @Time:        16/11/21 17:14
+# @Version:     2.0
+
+import copy
 
 import numpy as np
 from sklearn.datasets import load_iris
@@ -22,47 +25,41 @@ def ENN(X, k):
     :param k: int: number of neighbors to evaluate.
     :return: the input dataset with the remaining samples.
     """
+    size = len(X['data'])
+    samples = list(X['data'])
+    targets = X['target']
+    S = copy.deepcopy(X)
+    to_remove = []
 
-    y = X.target
-    data = []
-    target = []
-    for index in range(len(X['data'])):
-        classes = {}
-
-        possible_neighbors = zip(np.delete(X['data'], index),
-                                 np.delete(y, index))
-        distances_neighbors = []
-        for sample, sample_class in possible_neighbors:
-            euc = np.linalg.norm(X['data'][index] - sample)
-            distances_neighbors.append([sample, sample_class, euc])
+    for index in range(size):
+        x_sample = samples[index]
+        other_samples = samples[:index] + samples[index + 1:]
 
-        distances_neighbors.sort(key=lambda x: x[2])
-        neighbors_classes = distances_neighbors[:k]
-        for _, neigh, _ in neighbors_classes:
-            try:
-                classes[neigh] += 1
-            except KeyError:
-                classes[neigh] = 0
+        distances = []
+        for dis_index in range(len(other_samples)):
+            y_sample = samples[dis_index]
+            y_target = targets[dis_index]
+            distances.append([np.linalg.norm(x_sample - y_sample), y_target])
 
-        if max(classes, key=classes.get) == y[index]:
-            data.append(X['data'][index])
-            target.append(X['target'][index])
+        distances.sort(key=lambda x: x[0])
 
-    X['data'] = np.array(data)
-    X['target'] = target
+        closest_clases = [x[1] for x in distances[:k]]
 
-    return X
+        counts = np.bincount(closest_clases)
+        closest_class = np.argmax(counts)
 
+        if closest_class != targets[index]:
+            to_remove.append(index)
 
-def main():
-    data = load_iris()
-    n_samples = len(data['data'])
-    k = 3
-    S = ENN(X=data, k=k)
+    S['data'] = np.delete(S['data'], to_remove, axis=0)
+    S['target'] = np.delete(S['target'], to_remove, axis=0)
 
-    print(f"{n_samples - len(S['data'])} samples deleted.")
-    grafica_2D(S)
+    return S
 
 
 if __name__ == '__main__':
-    main()
+    iris = load_iris()
+    print(f'Input samples: {len(iris.data)}')
+    S = ENN(iris, 3)
+    print(f'Output samples: {len(S.data)}')
+    grafica_2D(S)
diff --git a/Instance Selection Algorithms/ICF.py b/Instance Selection Algorithms/ICF.py
index e480a9f..1302f7d 100644
--- a/Instance Selection Algorithms/ICF.py
+++ b/Instance Selection Algorithms/ICF.py
@@ -3,8 +3,9 @@
 # @Filename:    ICF.py
 # @Author:      Daniel Puente Ramírez
 # @Time:        23/11/21 09:37
+# @Version:     2.0
 
-import sys
+from sys import maxsize
 
 import numpy as np
 from sklearn.datasets import load_iris
@@ -20,7 +21,7 @@ def __delete_multiple_element__(list_object, indices):
             list_object.pop(idx)
 
 
-def __coverage__(dat, tar):
+def __coverage__(T):
     """
     Inner method that performs the coverage and reachability of T.
     :param dat: samples of T
@@ -29,41 +30,53 @@ def __coverage__(dat, tar):
     samples that it can cover. And reachable for each sample the samples that
     are able to reach it.
     """
-    one_class = True if len(np.unique(tar)) == 1 else False
-    cov = [[None if not one_class else i] for i in range(len(dat))]
-    reachable = [[None if not one_class else i] for i in range(len(dat))]
-    if one_class:
-        return cov, reachable
-
-    matrix_distances = [[sys.maxsize for _ in range(len(dat))]
-                        for _ in range(len(dat))]
-
-    for index in range(len(tar)):
-        for index2 in range(index, len(tar)):
-            euc = np.linalg.norm(dat[index] - dat[index2])
-            matrix_distances[index][index2] = euc
-            matrix_distances[index2][index] = euc
-
-    closest_enemy = [[None, None] for _ in range(len(dat))]
-    for index, row in enumerate(matrix_distances):
-        x_class = tar[index]
-        enemies = np.where(tar != x_class)[0]
-        closest_enemy[index] = [enemies[0], matrix_distances[index][enemies[0]]]
-        for enemy in enemies[1:]:
-            if matrix_distances[index][enemy] < closest_enemy[index][1]:
-                closest_enemy[index] = [enemy, matrix_distances[index][enemy]]
-
-    for index, row in enumerate(matrix_distances):
-        x_class = tar[index]
-        allies = np.where(tar == x_class)[0]
-        for ally in allies:
-            if matrix_distances[index][ally] < closest_enemy[index][1]:
-                cov[index].append(ally)
-                reachable[ally].append(index)
-    cov = [[i for i in val if i] for val in cov]
-    reachable = [[i for i in val if i] for val in reachable]
-
-    return cov, reachable
+    size = len(T.data)
+    matrix_distances = np.zeros([size, size])
+    distances_to_enemies = []
+    sol = []
+
+    for sample in range(size):
+        distance_to_closest_enemy = maxsize
+        x_sample = T['data'][sample]
+        x_target = T['target'][sample]
+        for other_sample in range(size):
+            y_sample = T['data'][other_sample]
+            y_target = T['target'][other_sample]
+            distance = np.linalg.norm(x_sample - y_sample)
+            matrix_distances[sample][other_sample] = distance
+            # Si son enemigas, nos quedamos con la distancia
+            if x_target != y_target and distance < distance_to_closest_enemy:
+                distance_to_closest_enemy = distance
+        distances_to_enemies.append(distance_to_closest_enemy)
+
+    for sample in range(size):
+        x_coverage = []
+        x_target = T['target'][sample]
+        distance_to_closest_enemy = distances_to_enemies[sample]
+        for other_sample in range(size):
+            if sample == other_sample:
+                continue
+            y_target = T['target'][other_sample]
+            if x_target == y_target:
+                distance_between_samples = matrix_distances[sample][
+                    other_sample]
+                if distance_between_samples < distance_to_closest_enemy:
+                    x_coverage.append(other_sample)
+        sol.append([x_coverage])
+
+    for sample in range(size):
+        reachable = []
+        x_target = T['target'][sample]
+        for other_sample in range(size):
+            y_target = T['target'][other_sample]
+            if sample != other_sample and x_target == y_target:
+                # if x_target == y_target:
+                coverage = sol[other_sample][0]
+                if sample in coverage:
+                    reachable.append(other_sample)
+        sol[sample].append(reachable)
+
+    return sol
 
 
 def ICF(X):
@@ -80,29 +93,32 @@ def ICF(X):
     :param X: dataset with scikit-learn structure.
     :return: the input dataset with the remaining samples.
     """
-    S = ENN(X=X, k=3)
 
-    data = list(S['data'])
-    target = list(S['target'])
-    progress = True
-    while progress:
+    TS = ENN(X=X, k=3)
 
-        coverage, reachable = __coverage__(data, target)
+    while True:
+        data = list(TS['data'])
+        target = list(TS['target'])
+
+        cov_reach = __coverage__(TS)
 
         progress = False
-        remove_indexes = []
-        for index, instance in enumerate(zip(data, target)):
-            (dat, tar) = instance
-            if abs(len(reachable[index])) > abs(len(coverage[index])):
-                remove_indexes.append(index)
+        removable_indexes = []
+        for index in range(len(cov_reach)):
+            (x_cov, x_reach) = cov_reach[index]
+            if len(x_reach) > len(x_cov):
+                removable_indexes.append(index)
                 progress = True
-        __delete_multiple_element__(data, remove_indexes)
-        __delete_multiple_element__(target, remove_indexes)
 
-    S['data'] = np.array(data)
-    S['target'] = target
+        __delete_multiple_element__(data, removable_indexes)
+        __delete_multiple_element__(target, removable_indexes)
+        TS['data'] = data
+        TS['target'] = target
+        if not progress:
+            break
 
-    return S
+    TS['data'] = np.array(TS['data'])
+    return TS
 
 
 def main():


Test patch:
diff --git a/Instance Selection Algorithms/test_implementation/test_KNNClassifier.csv b/Instance Selection Algorithms/test_implementation/test_KNNClassifier.csv
index 5a82c98..1d4c428 100644
--- a/Instance Selection Algorithms/test_implementation/test_KNNClassifier.csv
+++ b/Instance Selection Algorithms/test_implementation/test_KNNClassifier.csv
@@ -1,10 +1,10 @@
 dataset,ENN,CNN,RNN,ICF,MSS
-03_contraceptive_norm,0.43991542562971137,0.46710332781761355,0.46710332781761355,0.41546240117668687,0.47320279463136605
-04_yeast_norm,0.4864910212225648,0.5141347723562489,0.5020179575548703,0.3780065300199528,0.5269363323054598
-05_winequality-red_norm,0.535314465408805,0.5190880503144655,0.4834119496855346,0.4108805031446541,0.5491155660377358
-07_titanic_norm,0.576958041958042,0.5656375976964212,0.5656375976964212,0.6050987248046071,0.32303784450843276
-08_segment_norm,0.8692640692640693,0.8753246753246753,0.7848484848484848,0.7402597402597403,0.9398268398268398
-14_banana_norm,0.8822641509433963,0.8733962264150944,0.8683018867924529,0.6298113207547169,0.8826415094339622
-15_phoneme_norm,0.8144023413431916,0.8491798452796604,0.8145752036694736,0.6432196891901143,0.8726802218114602
-16_page-blocks_norm,0.9004003255981532,0.9477334899051229,0.9477334899051229,0.6589406050254206,0.9563221420088338
-17_texture_norm,0.9167272727272727,0.8721818181818182,0.8110909090909091,0.8127272727272727,0.9798181818181818
\ No newline at end of file
+03_contraceptive_norm,0.43991542562971137,0.46710332781761355,0.46710332781761355,0.43856867071152783,0.47320279463136605
+04_yeast_norm,0.4864910212225648,0.5141347723562489,0.5020179575548703,0.52184835842553964,0.5269363323054598
+05_winequality-red_norm,0.535314465408805,0.5190880503144655,0.4834119496855346,0.52588443396226416,0.5491155660377358
+07_titanic_norm,0.576958041958042,0.5656375976964212,0.5656375976964212,0.4661929247223365,0.32303784450843276
+08_segment_norm,0.8692640692640693,0.8753246753246753,0.7848484848484848,0.9043290043290044,0.9398268398268398
+14_banana_norm,0.8822641509433963,0.8733962264150944,0.8683018867924529,0.8152830188679245,0.8826415094339622
+15_phoneme_norm,0.8144023413431916,0.8491798452796604,0.8145752036694736,0.8260231395906073,0.8726802218114602
+16_page-blocks_norm,0.9004003255981532,0.9477334899051229,0.9477334899051229,0.958748115133642,0.9563221420088338
+17_texture_norm,0.9167272727272727,0.8721818181818182,0.8110909090909091,0.9247272727272728,0.9798181818181818
\ No newline at end of file
diff --git a/Instance Selection Algorithms/testing.py b/Instance Selection Algorithms/testing.py
index 0fe13b3..7876a5b 100644
--- a/Instance Selection Algorithms/testing.py
+++ b/Instance Selection Algorithms/testing.py
@@ -21,7 +21,7 @@
 
 from CNN import CNN
 from ENN import ENN
-from ICF import ICF
+from ICF_V2 import ICF
 from MSS import MSS
 from RNN import RNN
 
@@ -30,14 +30,14 @@ def main():
     datasets = next(walk('../datasets'), (None, None, []))[2]
     datasets.sort()
     header = ['dataset', 'ENN', 'CNN', 'RNN', 'ICF', 'MSS']
-    csv_path = 'testing_output_cross-validation-KNN.csv'
+    csv_path = 'testing_output_cross-validation-KNN19122021.csv'
     with open(csv_path, 'w') as save:
         w = csv.writer(save)
         w.writerow(header)
         save.close()
     acc = []
     random_state = 0x1122021
-    kf = KFold(n_splits=10, shuffle=True, random_state=random_state)
+    kf = KFold(n_splits=2, shuffle=True, random_state=random_state)
 
     for path in datasets[0:10]:
         name = path.split('.')[0]
@@ -48,14 +48,14 @@ def main():
         results_dataset = __evaluate__(dataset=d1, kf=kf)
         acc.append(current_dataset + results_dataset)
 
-        with open(csv_path, 'a') as save:
-            w = csv.writer(save)
-            w.writerows(acc)
-            save.close()
+    with open(csv_path, 'a') as save:
+        w = csv.writer(save)
+        w.writerows(acc)
+        save.close()
 
 
 def __evaluate__(dataset, kf):
-    algorithms = [ENN, CNN, RNN, ICF, MSS]
+    algorithms = [ICF]#[ENN, CNN, RNN, ICF, MSS]
     current_dataset = []
     for algorithm in algorithms:
         avg = []
@@ -80,7 +80,8 @@ def __evaluate__(dataset, kf):
 
 def __train_and_predict__(data_alg, data):
     # mod_td = DecisionTreeClassifier(max_depth=10, random_state=1)
-    mod_td = KNeighborsClassifier(n_neighbors=3)
+    mod_td = KNeighborsClassifier(n_neighbors=12, algorithm='brute', p=2,
+                                  n_jobs=-1)
     mod_td.fit(data_alg['data'], data_alg['target'])
     prediction = mod_td.predict(data['data'])
     accuracy = metrics.accuracy_score(prediction, data['target'])