Skip to content

Commit

Permalink
add fast topo
Browse files Browse the repository at this point in the history
  • Loading branch information
kasyanovse committed Jan 17, 2024
1 parent 5e726e9 commit c3f9f9c
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
5 changes: 4 additions & 1 deletion fedot/core/operations/evaluation/common_preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from fedot.core.operations.evaluation.operation_implementations.data_operations.sklearn_transformations import \
ImputationImplementation, KernelPCAImplementation, NormalizationImplementation, PCAImplementation, \
PolyFeaturesImplementation, ScalingImplementation, FastICAImplementation
from fedot.core.operations.evaluation.operation_implementations.data_operations.topological.fast_topological_extractor import \
FastTopologicalFeaturesImplementation
from fedot.core.operations.evaluation.operation_implementations.data_operations.topological. \
topological_extractor import TopologicalFeaturesImplementation
from fedot.core.operations.operation_parameters import OperationParameters
Expand Down Expand Up @@ -47,7 +49,8 @@ class FedotPreprocessingStrategy(EvaluationStrategy):
'one_hot_encoding': OneHotEncodingImplementation,
'label_encoding': LabelEncodingImplementation,
'fast_ica': FastICAImplementation,
'topological_features': TopologicalFeaturesImplementation
'topological_features': TopologicalFeaturesImplementation,
'fast_topological_features': FastTopologicalFeaturesImplementation,
}

def __init__(self, operation_type: str, params: Optional[OperationParameters] = None):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import math
import sys
from itertools import chain
from multiprocessing import cpu_count
from typing import Optional

import numpy as np
from gph import ripser_parallel as ripser

from fedot.core.data.data import InputData, OutputData
from fedot.core.operations.evaluation.operation_implementations.data_operations.topological.point_cloud import \
TopologicalTransformation
from fedot.core.operations.evaluation.operation_implementations.data_operations.topological.topological import \
HolesNumberFeature, MaxHoleLifeTimeFeature, RelevantHolesNumber, AverageHoleLifetimeFeature, \
SumHoleLifetimeFeature, PersistenceEntropyFeature, SimultaneousAliveHolesFeature, \
AveragePersistenceLandscapeFeature, BettiNumbersSumFeature, RadiusAtMaxBNFeature, PersistenceDiagramsExtractor, \
TopologicalFeaturesExtractor
from fedot.core.operations.evaluation.operation_implementations.implementation_interfaces import \
DataOperationImplementation
from fedot.core.operations.operation_parameters import OperationParameters
from fedot.utilities.window_size_selector import WindowSizeSelector, WindowSizeSelectorMethodsEnum
from golem.utilities.utilities import determine_n_jobs


class FastTopologicalFeaturesImplementation(DataOperationImplementation):
def __init__(self, params: Optional[OperationParameters] = None):
super().__init__(params)
self.window_size = params.get('window_size')
self.points_count = params.get('points_count')
self.max_homology_dimension = 1
self.shapes = None

def fit(self, input_data: InputData):
if self.points_count == 0:
self.points_count = int(input_data.features.shape[1] * 0.33)

self.shapes = None

return self

def transform(self, input_data: InputData) -> OutputData:
topological_features = [self._extract_features(self._slice_by_window(data, self.points_count))
for data in input_data.features]

if self.shapes is None:
self.shapes = [max(x[dim].shape[0] for x in topological_features)
for dim in range(self.max_homology_dimension + 1)]

features = list()
for dim in range(self.max_homology_dimension + 1):
_features = np.zeros((len(topological_features), self.shapes[dim]))
for topo_features_num, topo_features in enumerate(topological_features):
if len(topo_features[dim]) > 0:
x = topo_features[dim][:, 1] - topo_features[dim][:, 0]
_features[topo_features_num, :len(x)] = x
features.append(_features)
features = np.concatenate(features, axis=1)
features[np.isinf(features) | (features < 0)] = 0

return features

def _extract_features(self, x):
x_processed = ripser(x,
maxdim=self.max_homology_dimension,
coeff=2,
metric='euclidean',
n_threads=1,
collapse_edges=False)["dgms"]
return x_processed

def _slice_by_window(self, data, window):
return [data[i:window + i] for i in range(data.shape[0] - window + 1)]
14 changes: 14 additions & 0 deletions fedot/core/repository/data/data_operation_repository.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,20 @@
"presets": [
"ts"
],
"input_type": "[DataTypesEnum.table]",
"output_type": "[DataTypesEnum.table]",
"tags": [
"non_applicable_for_ts",
"feature_space_transformation"
]
},
"fast_topological_features": {
"meta": "custom_ts_preprocessing",
"presets": [
"ts"
],
"input_type": "[DataTypesEnum.table]",
"output_type": "[DataTypesEnum.table]",
"tags": [
"non_applicable_for_ts",
"feature_space_transformation"
Expand Down
4 changes: 4 additions & 0 deletions fedot/core/repository/data/default_operation_params.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,9 @@
},
"topological_features": {
"n_jobs": -1
},
"fast_topological_features": {
"window_size": 0,
"points_count": 0
}
}

0 comments on commit c3f9f9c

Please sign in to comment.