diff --git a/examples/core/create_node.py b/examples/core/create_node.py index 9762939..4981fe8 100644 --- a/examples/core/create_node.py +++ b/examples/core/create_node.py @@ -1,15 +1,14 @@ import numpy as np - from opfython.core.node import Node # Defining an index idx = 0 # Defining a label -label = 0 +label = 1 # Defining an array of features features = np.asarray([2, 2.5, 1.5, 4]) # Creating a Node -n = Node(idx, label, features) \ No newline at end of file +n = Node(idx, label, features) diff --git a/examples/math/calculate_distances.py b/examples/math/calculate_distances.py index 0e0920f..e707b3e 100644 --- a/examples/math/calculate_distances.py +++ b/examples/math/calculate_distances.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.math.distance as d # Defining an array @@ -10,3 +9,5 @@ # Calculating their distance dist = d.euclidean_distance(x, y) + +print(dist) diff --git a/examples/math/general_purpose.py b/examples/math/general_purpose.py index 2a8ecb0..02d6bf3 100644 --- a/examples/math/general_purpose.py +++ b/examples/math/general_purpose.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.math.general as g # Defining a general purpose array diff --git a/examples/models/create_supervised_opf.py b/examples/models/create_supervised_opf.py index 957ed33..948b1d2 100644 --- a/examples/models/create_supervised_opf.py +++ b/examples/models/create_supervised_opf.py @@ -1,5 +1,4 @@ from opfython.models.supervised import SupervisedOPF # Creates a SupervisedOPF instance -opf = SupervisedOPF(distance='log_squared_euclidean', - pre_computed_distance=None) +opf = SupervisedOPF(distance='log_squared_euclidean', pre_computed_distance=None) diff --git a/examples/models/create_unsupervised_opf.py b/examples/models/create_unsupervised_opf.py index c4ca3da..ce1af9b 100644 --- a/examples/models/create_unsupervised_opf.py +++ b/examples/models/create_unsupervised_opf.py @@ -1,5 +1,4 @@ from opfython.models.unsupervised import UnsupervisedOPF # Creates an UnsupervisedOPF instance -opf = UnsupervisedOPF( - min_k=1, max_k=10, distance='log_squared_euclidean', pre_computed_distance=None) +opf = UnsupervisedOPF(min_k=1, max_k=10, distance='log_squared_euclidean', pre_computed_distance=None) diff --git a/examples/stream/load_file.py b/examples/stream/load_file.py index c9bca06..e8d1b09 100644 --- a/examples/stream/load_file.py +++ b/examples/stream/load_file.py @@ -1,10 +1,10 @@ import opfython.stream.loader as l # Loading a .csv file -csv = l.load_csv('data/sample.csv') +csv = l.load_csv('data/boat.csv') # Loading a .txt file -txt = l.load_txt('data/sample.txt') +txt = l.load_txt('data/boat.txt') # Loading a .json file -json = l.load_json('data/sample.json') +json = l.load_json('data/boat.json') diff --git a/examples/stream/parse_loaded_file.py b/examples/stream/parse_loaded_file.py index 0b02a1c..4eb7e5a 100644 --- a/examples/stream/parse_loaded_file.py +++ b/examples/stream/parse_loaded_file.py @@ -2,7 +2,7 @@ import opfython.stream.parser as p # Loading a .txt file to a numpy array -txt = l.load_txt('data/sample.txt') +txt = l.load_txt('data/boat.txt') # Parsing a pre-loaded numpy array X, Y = p.parse_loader(txt) diff --git a/opfython/core/heap.py b/opfython/core/heap.py index b7b407d..6bfaad4 100644 --- a/opfython/core/heap.py +++ b/opfython/core/heap.py @@ -179,10 +179,13 @@ def is_empty(self): return False def dad(self, i): - """Gathers the position of the dad's node. + """Gathers the position of the node's dad. + + Args: + i (int): Node's position. Returns: - The position of dad's node. + The position of node's dad. """ @@ -190,10 +193,13 @@ def dad(self, i): return int(((i - 1) / 2)) def left_son(self, i): - """Gathers the position of the left son's node. + """Gathers the position of the node's left son. + + Args: + i (int): Node's position. Returns: - The position of left son's node. + The position of node's left son """ @@ -201,10 +207,13 @@ def left_son(self, i): return int((2 * i + 1)) def right_son(self, i): - """Gathers the position of the right son's node. + """Gathers the position of the node's right son. + + Args: + i (int): Node's position. Returns: - The position of right son's node. + The position of node's right son. """ diff --git a/opfython/core/node.py b/opfython/core/node.py index 3493f91..90735da 100644 --- a/opfython/core/node.py +++ b/opfython/core/node.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.utils.constants as c import opfython.utils.exception as e import opfython.utils.logging as l @@ -157,7 +156,8 @@ def cost(self): @cost.setter def cost(self, cost): - if not (isinstance(cost, float) or isinstance(cost, int) or isinstance(cost, np.int32) or isinstance(cost, np.int64)): + if not (isinstance(cost, float) or isinstance(cost, int) + or isinstance(cost, np.int32) or isinstance(cost, np.int64)): raise e.TypeError('`cost` should be a float or integer') self._cost = cost @@ -172,7 +172,8 @@ def density(self): @density.setter def density(self, density): - if not (isinstance(density, float) or isinstance(density, int) or isinstance(density, np.int32) or isinstance(density, np.int64)): + if not (isinstance(density, float) or isinstance(density, int) + or isinstance(density, np.int32) or isinstance(density, np.int64)): raise e.TypeError('`density` should be a float or integer') self._density = density @@ -187,7 +188,8 @@ def radius(self): @radius.setter def radius(self, radius): - if not (isinstance(radius, float) or isinstance(radius, int) or isinstance(radius, np.int32) or isinstance(radius, np.int64)): + if not (isinstance(radius, float) or isinstance(radius, int) + or isinstance(radius, np.int32) or isinstance(radius, np.int64)): raise e.TypeError('`radius` should be a float or integer') self._radius = radius diff --git a/opfython/core/opf.py b/opfython/core/opf.py index 68eb33f..95073ad 100644 --- a/opfython/core/opf.py +++ b/opfython/core/opf.py @@ -1,7 +1,6 @@ import pickle import numpy as np - import opfython.math.distance as d import opfython.stream.loader as loader import opfython.utils.constants as c @@ -17,7 +16,8 @@ class OPF: """A basic class to define all common OPF-related methods. References: - J. P. Papa, A. X. Falcão and C. T. N. Suzuki. LibOPF: A library for the design of optimum-path forest classifiers (2015). + J. P. Papa, A. X. Falcão and C. T. N. Suzuki. + LibOPF: A library for the design of optimum-path forest classifiers (2015). """ @@ -47,7 +47,7 @@ def __init__(self, distance='log_squared_euclidean', pre_computed_distance=None) self.pre_computed_distance = True # Apply the distances matrix - self.pre_distances = self._read_distances(pre_computed_distance) + self._read_distances(pre_computed_distance) # If OPF should not use a pre-computed distance else: @@ -57,8 +57,7 @@ def __init__(self, distance='log_squared_euclidean', pre_computed_distance=None) # Marks the pre-distances property as None self.pre_distances = None - logger.debug( - f'Distance: {self.distance} | Pre-computed distance: {self.pre_computed_distance}.') + logger.debug(f'Distance: {self.distance} | Pre-computed distance: {self.pre_computed_distance}.') logger.info('Class created.') @property @@ -87,8 +86,12 @@ def distance(self): @distance.setter def distance(self, distance): - if distance not in ['bray_curtis', 'canberra', 'chi_squared', 'euclidean', 'gaussian', 'log_euclidean', 'log_squared_euclidean', 'manhattan', 'squared_chi_squared', 'squared_cord', 'squared_euclidean']: - raise e.TypeError('`distance` should be `bray_curtis`, `canberra`, `chi_squared`, `euclidean`, `gaussian`, `log_euclidean`, `log_squared_euclidean`, `manhattan`, `squared_chi_squared`, `squared_cord` or `squared_euclidean`') + if distance not in ['bray_curtis', 'canberra', 'chi_squared', 'euclidean', + 'gaussian', 'log_euclidean', 'log_squared_euclidean', + 'manhattan', 'squared_chi_squared', 'squared_cord', 'squared_euclidean']: + raise e.TypeError('`distance` should be `bray_curtis`, `canberra`, `chi_squared`, ' + '`euclidean`, `gaussian`, `log_euclidean`, `log_squared_euclidean`, ' + '`manhattan`, `squared_chi_squared`, `squared_cord` or `squared_euclidean`') self._distance = distance @@ -138,31 +141,28 @@ def pre_distances(self, pre_distances): self._pre_distances = pre_distances - def _read_distances(self, file_path): + def _read_distances(self, file_name): """Reads the distance between nodes from a pre-defined file. Args: - file_path (str): File to be loaded. - - Returns: - A matrix with pre-computed distances. + file_name (str): File to be loaded. """ logger.debug('Running private method: read_distances().') # Getting file extension - extension = file_path.split('.')[-1] + extension = file_name.split('.')[-1] # Check if extension is .csv if extension == 'csv': # If yes, call the method that actually loads csv - distances = loader.load_csv(file_path) + distances = loader.load_csv(file_name) # Check if extension is .txt elif extension == 'txt': # If yes, call the method that actually loads txt - distances = loader.load_txt(file_path) + distances = loader.load_txt(file_name) # If extension is not recognized else: @@ -176,7 +176,8 @@ def _read_distances(self, file_path): raise e.ValueError( 'Pre-computed distances could not been properly loaded') - return distances + # Apply the distances matrix to the property + self.pre_distances = distances def load(self, file_name): """Loads the object from a pickle encoding. diff --git a/opfython/core/subgraph.py b/opfython/core/subgraph.py index 5c5c247..f8eb947 100644 --- a/opfython/core/subgraph.py +++ b/opfython/core/subgraph.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.stream.loader as loader import opfython.stream.parser as p import opfython.utils.constants as c diff --git a/opfython/math/distance.py b/opfython/math/distance.py index 66d2858..b9ef4e9 100644 --- a/opfython/math/distance.py +++ b/opfython/math/distance.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.utils.constants as c diff --git a/opfython/math/general.py b/opfython/math/general.py index 0f8bbf9..f80a31c 100644 --- a/opfython/math/general.py +++ b/opfython/math/general.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.math.distance as d import opfython.utils.logging as l @@ -33,7 +32,7 @@ def confusion_matrix(labels, preds): # For every label and prediction for label, pred in zip(labels, preds): # Increments the corresponding cell from the confusion matrix - c_matrix[label-1][pred-1] += 1 + c_matrix[label - 1][pred - 1] += 1 return c_matrix @@ -93,10 +92,10 @@ def opf_accuracy(labels, preds): # If label is different from prediction if label != pred: # Increments the corresponding cell from the error matrix - errors[pred-1][0] += 1 + errors[pred - 1][0] += 1 # Increments the corresponding cell from the error matrix - errors[label-1][1] += 1 + errors[label - 1][1] += 1 # Calculating the float value of the true label errors errors[:, 1] /= counts @@ -145,7 +144,7 @@ def opf_accuracy_per_label(labels, preds): # If label is different from prediction if label != pred: # Increments the corresponding cell from the error array - errors[label-1] += 1 + errors[label - 1] += 1 # Calculating the float value of the true label errors errors /= counts diff --git a/opfython/models/knn_supervised.py b/opfython/models/knn_supervised.py index 7788290..541df14 100644 --- a/opfython/models/knn_supervised.py +++ b/opfython/models/knn_supervised.py @@ -1,7 +1,6 @@ import time import numpy as np - import opfython.math.general as g import opfython.utils.constants as c import opfython.utils.exception as e @@ -34,8 +33,7 @@ def __init__(self, max_k=1, distance='log_squared_euclidean', pre_computed_dista logger.info('Overriding class: OPF -> KNNSupervisedOPF.') # Override its parent class with the receiving arguments - super(KNNSupervisedOPF, self).__init__( - distance=distance, pre_computed_distance=pre_computed_distance) + super(KNNSupervisedOPF, self).__init__(distance, pre_computed_distance) # Defining the maximum `k` value for cutting the subgraph self.max_k = max_k @@ -171,9 +169,6 @@ def _learn(self, X_train, Y_train, X_val, Y_val): X_val (np.array): Array of validation features. Y_val (np.array): Array of validation labels. - Returns: - The best `k` value found over the validation set. - """ logger.info('Learning best `k` value ...') @@ -227,7 +222,8 @@ def _learn(self, X_train, Y_train, X_val, Y_val): # Destroy the arcs self.subgraph.destroy_arcs() - return best_k + # Applying the best k to the subgraph's property + self.subgraph.best_k = best_k def fit(self, X_train, Y_train, X_val, Y_val): """Fits data in the classifier. @@ -246,7 +242,7 @@ def fit(self, X_train, Y_train, X_val, Y_val): start = time.time() # Performing the learning process in order to find the best `k` value - self.subgraph.best_k = self._learn(X_train, Y_train, X_val, Y_val) + self._learn(X_train, Y_train, X_val, Y_val) # Creating arcs with the best `k` value self.subgraph.create_arcs( @@ -271,8 +267,7 @@ def fit(self, X_train, Y_train, X_val, Y_val): # Calculating training task time train_time = end - start - logger.info( - f'Classifier has been fitted with k = {self.subgraph.best_k}.') + logger.info(f'Classifier has been fitted with k = {self.subgraph.best_k}.') logger.info(f'Training time: {train_time} seconds.') def predict(self, X_test, verbose=False): @@ -330,20 +325,18 @@ def predict(self, X_test, verbose=False): neighbours_idx[best_k] = j # Gathers current `k` - current_k = best_k + cur_k = best_k # While current `k` is bigger than 0 and the `k` distance is smaller than `k-1` distance - while current_k > 0 and distances[current_k] < distances[current_k - 1]: + while cur_k > 0 and distances[cur_k] < distances[cur_k - 1]: # Swaps the distance from `k` and `k-1` - distances[current_k], distances[current_k - - 1] = distances[current_k - 1], distances[current_k] + distances[cur_k], distances[cur_k - 1] = distances[cur_k - 1], distances[cur_k] # Swaps the neighbours indexex from `k` and `k-1` - neighbours_idx[current_k], neighbours_idx[current_k - - 1] = neighbours_idx[current_k - 1], neighbours_idx[current_k] + neighbours_idx[cur_k], neighbours_idx[cur_k - 1] = neighbours_idx[cur_k - 1], neighbours_idx[cur_k] # Decrements `k` - current_k -= 1 + cur_k -= 1 # Defining the density as 0 density = 0.0 diff --git a/opfython/models/semi_supervised.py b/opfython/models/semi_supervised.py index 82b509f..fce2c76 100644 --- a/opfython/models/semi_supervised.py +++ b/opfython/models/semi_supervised.py @@ -1,7 +1,6 @@ import time import numpy as np - import opfython.utils.constants as c import opfython.utils.exception as e import opfython.utils.logging as l @@ -17,7 +16,8 @@ class SemiSupervisedOPF(SupervisedOPF): """A SemiSupervisedOPF which implements the semi-supervised version of OPF classifier. References: - W. P. Amorim, A. X. Falcão and M. H. Carvalho. Semi-supervised Pattern Classification Using Optimum-Path Forest. 27th SIBGRAPI Conference on Graphics, Patterns and Images (2014). + W. P. Amorim, A. X. Falcão and M. H. Carvalho. Semi-supervised Pattern Classification Using Optimum-Path Forest. + 27th SIBGRAPI Conference on Graphics, Patterns and Images (2014). """ @@ -33,8 +33,7 @@ def __init__(self, distance='log_squared_euclidean', pre_computed_distance=None) logger.info('Overriding class: SupervisedOPF -> SemiSupervisedOPF.') # Override its parent class with the receiving arguments - super(SemiSupervisedOPF, self).__init__( - distance=distance, pre_computed_distance=pre_computed_distance) + super(SemiSupervisedOPF, self).__init__(distance, pre_computed_distance) logger.info('Class overrided.') diff --git a/opfython/models/supervised.py b/opfython/models/supervised.py index 792cebe..15e505e 100644 --- a/opfython/models/supervised.py +++ b/opfython/models/supervised.py @@ -2,7 +2,6 @@ import time import numpy as np - import opfython.math.general as g import opfython.math.random as r import opfython.utils.constants as c @@ -19,7 +18,8 @@ class SupervisedOPF(OPF): """A SupervisedOPF which implements the supervised version of OPF classifier. References: - J. P. Papa, A. X. Falcão and C. T. N. Suzuki. Supervised Pattern Classification based on Optimum-Path Forest. International Journal of Imaging Systems and Technology (2009). + J. P. Papa, A. X. Falcão and C. T. N. Suzuki. Supervised Pattern Classification based on Optimum-Path Forest. + International Journal of Imaging Systems and Technology (2009). """ @@ -35,8 +35,7 @@ def __init__(self, distance='log_squared_euclidean', pre_computed_distance=None) logger.info('Overriding class: OPF -> SupervisedOPF.') # Override its parent class with the receiving arguments - super(SupervisedOPF, self).__init__( - distance=distance, pre_computed_distance=pre_computed_distance) + super(SupervisedOPF, self).__init__(distance, pre_computed_distance) logger.info('Class overrided.') @@ -99,8 +98,7 @@ def _find_prototypes(self): # If it is supposed to use pre-computed distances if self.pre_computed_distance: # Gathers the arc from the distances' matrix - weight = self.pre_distances[self.subgraph.nodes[p] - .idx][self.subgraph.nodes[q].idx] + weight = self.pre_distances[self.subgraph.nodes[p].idx][self.subgraph.nodes[q].idx] # If distance is supposed to be calculated else: @@ -190,8 +188,7 @@ def fit(self, X_train, Y_train): # Checks if we are using a pre-computed distance if self.pre_computed_distance: # Gathers the distance from the distance's matrix - weight = self.pre_distances[self.subgraph.nodes[p] - .idx][self.subgraph.nodes[q].idx] + weight = self.pre_distances[self.subgraph.nodes[p].idx][self.subgraph.nodes[q].idx] # If the distance is supposed to be calculated else: @@ -268,8 +265,7 @@ def predict(self, X_val): # Checks if we are using a pre-computed distance if self.pre_computed_distance: # Gathers the distance from the distance's matrix - weight = self.pre_distances[self.subgraph.nodes[k] - .idx][pred_subgraph.nodes[i].idx] + weight = self.pre_distances[self.subgraph.nodes[k].idx][pred_subgraph.nodes[i].idx] # If the distance is supposed to be calculated else: @@ -291,8 +287,7 @@ def predict(self, X_val): # Checks if we are using a pre-computed distance if self.pre_computed_distance: # Gathers the distance from the distance's matrix - weight = self.pre_distances[self.subgraph.nodes[l] - .idx][pred_subgraph.nodes[i].idx] + weight = self.pre_distances[self.subgraph.nodes[l].idx][pred_subgraph.nodes[i].idx] # If the distance is supposed to be calculated else: @@ -414,8 +409,10 @@ def learn(self, X_train, Y_train, X_val, Y_val, n_iterations=10): # If the node on that particular index is not a prototype if self.subgraph.nodes[j].status != c.PROTOTYPE: - # Swap the nodes + # Swap the input nodes X_train[j, :], X_val[e, :] = X_val[e, :], X_train[j, :] + + # Swap the target nodes Y_train[j], Y_val[e] = Y_val[e], Y_train[j] # Decrements the number of non-prototypes diff --git a/opfython/models/unsupervised.py b/opfython/models/unsupervised.py index 445649a..99b9cd9 100644 --- a/opfython/models/unsupervised.py +++ b/opfython/models/unsupervised.py @@ -1,7 +1,6 @@ import time import numpy as np - import opfython.utils.constants as c import opfython.utils.exception as e import opfython.utils.logging as l @@ -16,7 +15,9 @@ class UnsupervisedOPF(OPF): """An UnsupervisedOPF which implements the unsupervised version of OPF classifier. References: - L. M. Rocha, F. A. M. Cappabianco, A. X. Falcão. Data clustering as an optimum-path forest problem with applications in image analysis. International Journal of Imaging Systems and Technology (2009). + L. M. Rocha, F. A. M. Cappabianco, A. X. Falcão. + Data clustering as an optimum-path forest problem with applications in image analysis. + International Journal of Imaging Systems and Technology (2009). """ @@ -34,8 +35,7 @@ def __init__(self, min_k=1, max_k=1, distance='log_squared_euclidean', pre_compu logger.info('Overriding class: OPF -> UnsupervisedOPF.') # Override its parent class with the receiving arguments - super(UnsupervisedOPF, self).__init__( - distance=distance, pre_computed_distance=pre_computed_distance) + super(UnsupervisedOPF, self).__init__(distance, pre_computed_distance) # Defining the minimum `k` value for cutting the subgraph self.min_k = min_k @@ -425,20 +425,18 @@ def predict(self, X_val): neighbours_idx[best_k] = j # Gathers current `k` - current_k = best_k + cur_k = best_k # While current `k` is bigger than 0 and the `k` distance is smaller than `k-1` distance - while current_k > 0 and distances[current_k] < distances[current_k - 1]: + while cur_k > 0 and distances[cur_k] < distances[cur_k - 1]: # Swaps the distance from `k` and `k-1` - distances[current_k], distances[current_k - - 1] = distances[current_k - 1], distances[current_k] + distances[cur_k], distances[cur_k - 1] = distances[cur_k - 1], distances[cur_k] # Swaps the neighbours indexex from `k` and `k-1` - neighbours_idx[current_k], neighbours_idx[current_k - - 1] = neighbours_idx[current_k - 1], neighbours_idx[current_k] + neighbours_idx[cur_k], neighbours_idx[cur_k - 1] = neighbours_idx[cur_k - 1], neighbours_idx[cur_k] # Decrements `k` - current_k -= 1 + cur_k -= 1 # Defining the density as 0 density = 0.0 diff --git a/opfython/stream/loader.py b/opfython/stream/loader.py index e22b084..0137bf7 100644 --- a/opfython/stream/loader.py +++ b/opfython/stream/loader.py @@ -1,7 +1,6 @@ import json as j import numpy as np - import opfython.utils.logging as l logger = l.get_logger(__name__) diff --git a/opfython/stream/parser.py b/opfython/stream/parser.py index 4993587..72b828b 100644 --- a/opfython/stream/parser.py +++ b/opfython/stream/parser.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.utils.exception as e import opfython.utils.logging as l diff --git a/opfython/stream/splitter.py b/opfython/stream/splitter.py index 13ccda0..1250b4a 100644 --- a/opfython/stream/splitter.py +++ b/opfython/stream/splitter.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.utils.exception as e import opfython.utils.logging as l @@ -62,8 +61,7 @@ def split(X, Y, percentage=0.5, random_state=1): # Gathering two new sets from `Y` Y_1, Y_2 = Y[idx[:halt]], Y[idx[halt:]] - logger.debug( - f'X_1: {X_1.shape} | X_2: {X_2.shape} | Y_1: {Y_1.shape} | Y_2: {Y_2.shape}.') + logger.debug(f'X_1: {X_1.shape} | X_2: {X_2.shape} | Y_1: {Y_1.shape} | Y_2: {Y_2.shape}.') logger.info('Data splitted.') return X_1, X_2, Y_1, Y_2 @@ -94,8 +92,7 @@ def merge(X_1, X_2, Y_1, Y_2): # Checks if `X` and `Y` have the same size if X.shape[0] != Y.shape[0]: # If not, raises a SizeError - raise e.SizeError( - f'`(X_1, X_2)` and `(Y_1, Y_2)` should have the same amount of samples') + raise e.SizeError(f'`(X_1, X_2)` and `(Y_1, Y_2)` should have the same amount of samples') logger.debug(f'X: {X.shape} | Y: {Y.shape}.') logger.info('Data merged.') diff --git a/opfython/subgraphs/knn.py b/opfython/subgraphs/knn.py index 86c4f1c..ef6373d 100644 --- a/opfython/subgraphs/knn.py +++ b/opfython/subgraphs/knn.py @@ -1,5 +1,4 @@ import numpy as np - import opfython.utils.constants as c import opfython.utils.exception as e import opfython.utils.logging as l @@ -24,7 +23,7 @@ def __init__(self, X=None, Y=None, from_file=None): """ # Override its parent class with the receiving arguments - super(KNNSubgraph, self).__init__(X=X, Y=Y, from_file=from_file) + super(KNNSubgraph, self).__init__(X, Y, from_file) # Number of assigned clusters self.n_clusters = 0 @@ -88,7 +87,8 @@ def constant(self): @constant.setter def constant(self, constant): - if not (isinstance(constant, float) or isinstance(constant, int) or isinstance(constant, np.int32) or isinstance(constant, np.int64)): + if not (isinstance(constant, float) or isinstance(constant, int) + or isinstance(constant, np.int32) or isinstance(constant, np.int64)): raise e.TypeError('`constant` should be a float or integer') self._constant = constant @@ -103,7 +103,8 @@ def density(self): @density.setter def density(self, density): - if not (isinstance(density, float) or isinstance(density, int) or isinstance(density, np.int32) or isinstance(density, np.int64)): + if not (isinstance(density, float) or isinstance(density, int) + or isinstance(density, np.int32) or isinstance(density, np.int64)): raise e.TypeError('`density` should be a float or integer') self._density = density @@ -118,7 +119,8 @@ def min_density(self): @min_density.setter def min_density(self, min_density): - if not (isinstance(min_density, float) or isinstance(min_density, int) or isinstance(min_density, np.int32) or isinstance(min_density, np.int64)): + if not (isinstance(min_density, float) or isinstance(min_density, int) + or isinstance(min_density, np.int32) or isinstance(min_density, np.int64)): raise e.TypeError('`min_density` should be a float or integer') self._min_density = min_density @@ -133,7 +135,8 @@ def max_density(self): @max_density.setter def max_density(self, max_density): - if not (isinstance(max_density, float) or isinstance(max_density, int) or isinstance(max_density, np.int32) or isinstance(max_density, np.int64)): + if not (isinstance(max_density, float) or isinstance(max_density, int) + or isinstance(max_density, np.int32) or isinstance(max_density, np.int64)): raise e.TypeError('`max_density` should be a float or integer') self._max_density = max_density @@ -272,20 +275,18 @@ def create_arcs(self, k, distance_function, pre_computed_distance=False, pre_dis neighbours_idx[k] = j # Gathers current `k` - current_k = k + cur_k = k # While current `k` is bigger than 0 and the `k` distance is smaller than `k-1` distance - while current_k > 0 and distances[current_k] < distances[current_k - 1]: + while cur_k > 0 and distances[cur_k] < distances[cur_k - 1]: # Swaps the distance from `k` and `k-1` - distances[current_k], distances[current_k - - 1] = distances[current_k - 1], distances[current_k] + distances[cur_k], distances[cur_k - 1] = distances[cur_k - 1], distances[cur_k] # Swaps the neighbours indexex from `k` and `k-1` - neighbours_idx[current_k], neighbours_idx[current_k - - 1] = neighbours_idx[current_k - 1], neighbours_idx[current_k] + neighbours_idx[cur_k], neighbours_idx[cur_k - 1] = neighbours_idx[cur_k - 1], neighbours_idx[cur_k] # Decrements `k` - current_k -= 1 + cur_k -= 1 # Make sure that current node's radius is 0 self.nodes[i].radius = 0.0 @@ -337,8 +338,7 @@ def eliminate_maxima_height(self, height): # For every possible node for i in range(self.n_nodes): # Calculates its new cost - self.nodes[i].cost = np.maximum( - self.nodes[i].density - height, 0) + self.nodes[i].cost = np.maximum(self.nodes[i].density - height, 0) logger.debug('Maxima eliminated.') diff --git a/opfython/utils/constants.py b/opfython/utils/constants.py index c9d2139..eb943d1 100644 --- a/opfython/utils/constants.py +++ b/opfython/utils/constants.py @@ -4,7 +4,7 @@ # and any possible mathematical error EPSILON = 1e-10 -# When the agents are initialized, their fitness is defined as +# When the costs are initialized, their value are defined as # the maximum float value possible FLOAT_MAX = sys.float_info.max diff --git a/opfython/utils/converter.py b/opfython/utils/converter.py index 691895b..60a8d2a 100644 --- a/opfython/utils/converter.py +++ b/opfython/utils/converter.py @@ -2,7 +2,6 @@ import struct import numpy as np - import opfython.utils.logging as l logger = l.get_logger(__name__) diff --git a/opfython/utils/logging.py b/opfython/utils/logging.py index a156314..7416616 100644 --- a/opfython/utils/logging.py +++ b/opfython/utils/logging.py @@ -22,11 +22,11 @@ def get_console_handler(): return console_handler -def get_file_handler(): - """Gets a file handler to handle logging into files. +def get_timed_file_handler(): + """Gets a timed file handler to handle logging into files. Returns: - A handler to output information into files. + A handler to output information into timed files. """ @@ -56,7 +56,7 @@ def get_logger(logger_name): # Adds the desired handlers logger.addHandler(get_console_handler()) - logger.addHandler(get_file_handler()) + logger.addHandler(get_timed_file_handler()) # True or False for propagating logs logger.propagate = False diff --git a/tests/opfython/math/test_general.py b/tests/opfython/math/test_general.py index 0fa504f..e4f29c9 100644 --- a/tests/opfython/math/test_general.py +++ b/tests/opfython/math/test_general.py @@ -1,6 +1,7 @@ import pytest from opfython.math import general +from opfython.stream import loader, parser, splitter def test_confusion_matrix(): @@ -38,6 +39,16 @@ def test_opf_accuracy_per_label(): assert acc_per_label.shape == (2,) +def test_opf_pre_compute_distances(): + txt = loader.load_txt('data/boat.txt') + + X, Y = parser.parse_loader(txt) + + X_train, _, _, _ = splitter.split(X, Y, 0.5, 1) + + general.pre_compute_distance(X_train, 'boat_split_distances.txt', 'log_squared_euclidean') + + def test_purity(): labels = [1, 1, 2, 2] preds = [1, 1, 2, 2] diff --git a/tests/opfython/utils/test_logging.py b/tests/opfython/utils/test_logging.py index fb9edb4..880a508 100644 --- a/tests/opfython/utils/test_logging.py +++ b/tests/opfython/utils/test_logging.py @@ -8,7 +8,7 @@ def test_get_console_handler(): def test_get_file_handler(): - f = logging.get_file_handler() + f = logging.get_timed_file_handler() assert f != None