Skip to content

Commit

Permalink
Added the ability to calculate all criteria using one model (#192)
Browse files Browse the repository at this point in the history
* Added the ability to calculate all criteria using one model

* Improved implementation of MCO tasks
  • Loading branch information
LebedevIlyaG committed May 15, 2024
1 parent a12ad34 commit d33eade
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 35 deletions.
21 changes: 11 additions & 10 deletions examples/Machine_learning/SVC/_2D/Problems/mco_breast_cancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ def __init__(self, X, y, X_train, y_train):

self.known_optimum = np.ndarray(shape=(1,), dtype=Trial)

def calculate(self, point: Point, function_value: FunctionValue) -> FunctionValue:
def calculateAllFunction(self, point: Point, function_values: np.ndarray(shape=(1), dtype=FunctionValue)) -> \
np.ndarray(shape=(1), dtype=FunctionValue):
"""
Вычисление значения выбранной функции в заданной точке.
:param point: координаты точки испытания, в которой будет вычислено значение функции
:param function_value: объект, определяющий номер функции в задаче и хранящий значение функции
:return: вычисленное значение функции в точке point
:param function_values: массив объектов, определяющих номера функций в задаче и хранящий значения функций
:return: массив вычисленных значений функций в точке point
"""
result: np.double = 0
x = point.float_variables

svc_c = 10 ** x[0]
Expand All @@ -58,10 +58,11 @@ def calculate(self, point: Point, function_value: FunctionValue) -> FunctionValu
classifier_obj = SVC(C=svc_c, gamma=gamma)
classifier_obj.fit(self.X_train, self.y_train)

if function_value.functionID == 0: # OBJECTIV 1
result = - cross_val_score(classifier_obj, self.X, self.y, n_jobs=4, scoring='precision').mean()
elif function_value.functionID == 1: # OBJECTIV 2
result = - cross_val_score(classifier_obj, self.X, self.y, n_jobs=4, scoring='recall').mean()
# OBJECTIV 1
function_values[0].value = - cross_val_score(classifier_obj, self.X, self.y, n_jobs=4,
scoring='precision').mean()
# OBJECTIV 2
function_values[1].value = - cross_val_score(classifier_obj, self.X, self.y, n_jobs=4,
scoring='recall').mean()

function_value.value = result
return function_value
return function_values
2 changes: 1 addition & 1 deletion iOpt/method/mco_method_evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def calculate_functionals(self, point: SearchDataItem) -> SearchDataItem:

for i in range(self.task.problem.number_of_objectives):
point.function_values[number_of_constraints + i] = FunctionValue(FunctionType.OBJECTIV, i)
point = self.task.calculate(point, number_of_constraints + i)
point = self.task.calculate(point, -1)

point = self.task.calculate(point, -1, TypeOfCalculation.CONVOLUTION)
point.set_index(number_of_constraints)
Expand Down
16 changes: 12 additions & 4 deletions iOpt/method/mco_optim_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,18 @@ def calculate(self,
) -> SearchDataItem:
"""Compute selected function by number."""
if calculation_type == TypeOfCalculation.FUNCTION:
data_item.function_values[self.perm[function_index]] = \
self.problem.calculate(data_item.point, data_item.function_values[self.perm[function_index]])
if not np.isfinite(data_item.function_values[self.perm[function_index]].value):
raise Exception("Infinity values")
if function_index == -1: # Calculate all criteria
data_item.function_values = self.problem.calculateAllFunction(data_item.point,
data_item.function_values)
for i in range(self.problem.number_of_objectives):
if not np.isfinite(data_item.function_values[self.perm[self.problem.number_of_constraints +
i]].value):
raise Exception("Infinity values")
else:
data_item.function_values[self.perm[function_index]] = \
self.problem.calculate(data_item.point, data_item.function_values[self.perm[function_index]])
if not np.isfinite(data_item.function_values[self.perm[function_index]].value):
raise Exception("Infinity values")

elif calculation_type == TypeOfCalculation.CONVOLUTION:
data_item = self.convolution.calculate_convolution(data_item, self.min_value, self.max_value)
Expand Down
17 changes: 15 additions & 2 deletions iOpt/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,27 @@ def __init__(self):

self.known_optimum: np.ndarray(shape=(1), dtype=Trial) = []

@abstractmethod
def calculate(self, point: Point, function_value: FunctionValue) -> FunctionValue:
"""
Calculate a function at a given point.
For any new problem statement that inherits from :class:`Problem`, this method should be overloaded
:return: Calculated value of the function."""
pass
function_value.value = 0;
return function_value

def calculateAllFunction(self, point: Point, function_values: np.ndarray(shape=(1), dtype=FunctionValue)) -> \
np.ndarray(shape=(1), dtype=FunctionValue):
"""
Calculate all functions at a given point.
For any new problem statement that inherits from :class:`Problem`, this method should be overloaded
:return: Calculated values of the functions."""
for i in range(self.number_of_objectives):
function_values[i].value = self.calculate(point, function_values[i])

return function_values


# @abstractmethod
def get_name(self):
Expand Down
28 changes: 10 additions & 18 deletions problems/mco_test1.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,20 @@ def __init__(self):
self.upper_bound_of_float_variables = np.ndarray(shape=(self.number_of_float_variables,), dtype=np.double)
self.upper_bound_of_float_variables.fill(1)


self.known_optimum = np.ndarray(shape=(1,), dtype=Trial)



def calculate(self, point: Point, function_value: FunctionValue) -> FunctionValue:
def calculateAllFunction(self, point: Point, function_values: np.ndarray(shape=(1), dtype=FunctionValue)) -> \
np.ndarray(shape=(1), dtype=FunctionValue):
"""
Вычисление значения выбранной функции в заданной точке.
Calculate all function at a given point.
For any new problem statement that inherits from :class:`Problem`, this method should be overloaded
:param point: координаты точки испытания, в которой будет вычислено значение функции
:param function_value: объект, определяющий номер функции в задаче и хранящий значение функции
:return: Вычисленное значение функции в точке point
"""
result: np.double = 0
:return: Calculated values of the functions."""
x = point.float_variables

if function_value.functionID == 0: # OBJECTIV 1
result = np.double((x[0]-1)*x[1]*x[1]+1)
elif function_value.functionID == 1: # OBJECTIV 2
result = np.double(x[1])

function_value.value = result
return function_value

# OBJECTIVE 1
function_values[0].value = np.double((x[0] - 1) * x[1] * x[1] + 1)
# OBJECTIVE 2
function_values[1].value = np.double(x[1])

return function_values

0 comments on commit d33eade

Please sign in to comment.