i think i've done this shit RMSE: 0.64 !!!!
This commit is contained in:
@@ -77,32 +77,6 @@ class MAEFitness(BaseFitness):
|
||||
return float(np.mean(np.abs(predicted - true_values)))
|
||||
|
||||
|
||||
class HuberFitness(BaseFitness):
|
||||
"""Huber Loss (компромисс между MSE и MAE)"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
target_fn: TargetFunction,
|
||||
test_points_fn: TestPointsFn,
|
||||
delta: float = 1.0,
|
||||
):
|
||||
super().__init__(target_fn, test_points_fn)
|
||||
self.delta = delta
|
||||
|
||||
def fitness_fn(
|
||||
self,
|
||||
chromosome: Chromosome,
|
||||
predicted: NDArray[np.float64],
|
||||
true_values: NDArray[np.float64],
|
||||
) -> float:
|
||||
error = predicted - true_values
|
||||
mask = np.abs(error) <= self.delta
|
||||
squared = 0.5 * (error[mask] ** 2)
|
||||
linear = self.delta * (np.abs(error[~mask]) - 0.5 * self.delta)
|
||||
huber = np.concatenate([squared, linear])
|
||||
return float(np.mean(huber))
|
||||
|
||||
|
||||
class NRMSEFitness(BaseFitness):
|
||||
"""Нормализованный RMSE (масштаб-инвариантен)"""
|
||||
|
||||
@@ -128,12 +102,18 @@ class PenalizedFitness(BaseFitness):
|
||||
base_fitness: BaseFitness,
|
||||
lambda_: float = 0.001,
|
||||
depth_weight: float = 0.2,
|
||||
scale_penalty: bool | None = None,
|
||||
):
|
||||
super().__init__(target_fn, test_points_fn)
|
||||
self.base_fitness = base_fitness
|
||||
self.lambda_ = lambda_
|
||||
self.depth_weight = depth_weight
|
||||
|
||||
# Масштабировать штраф необязательно, если функция фитнеса нормализована
|
||||
if scale_penalty is None:
|
||||
scale_penalty = not isinstance(base_fitness, NRMSEFitness)
|
||||
self.scale_penalty = scale_penalty
|
||||
|
||||
def fitness_fn(
|
||||
self,
|
||||
chromosome: Chromosome,
|
||||
@@ -146,4 +126,8 @@ class PenalizedFitness(BaseFitness):
|
||||
depth = chromosome.root.get_depth()
|
||||
|
||||
penalty = self.lambda_ * (size + self.depth_weight * depth)
|
||||
|
||||
if self.scale_penalty:
|
||||
penalty *= base
|
||||
|
||||
return float(base + penalty)
|
||||
|
||||
@@ -42,29 +42,25 @@ def grow_mutation(chromosome: Chromosome, max_depth: int) -> Chromosome:
|
||||
def node_replacement_mutation(chromosome: Chromosome) -> Chromosome:
|
||||
"""Мутация замены операции (Node Replacement Mutation).
|
||||
|
||||
Выбирает случайный узел с операцией (arity > 0) и заменяет его
|
||||
на случайную другую операцию той же арности, сохраняя поддеревья.
|
||||
Выбирает случайный узел и заменяет его
|
||||
на случайную другую операцию той же арности или терминал, сохраняя поддеревья.
|
||||
|
||||
Если подходящей альтернативы нет — возвращает копию без изменений.
|
||||
"""
|
||||
chromosome = chromosome.copy()
|
||||
|
||||
operation_nodes = [n for n in chromosome.root.list_nodes() if n.value.arity > 0]
|
||||
if not operation_nodes:
|
||||
return chromosome
|
||||
|
||||
target_node = random.choice(operation_nodes)
|
||||
target_node = random.choice(chromosome.root.list_nodes())
|
||||
current_arity = target_node.value.arity
|
||||
|
||||
same_arity_ops = [
|
||||
same_arity = [
|
||||
op
|
||||
for op in chromosome.operations
|
||||
for op in list(chromosome.operations) + list(chromosome.terminals)
|
||||
if op.arity == current_arity and op != target_node.value
|
||||
]
|
||||
if not same_arity_ops:
|
||||
if not same_arity:
|
||||
return chromosome
|
||||
|
||||
new_operation = random.choice(same_arity_ops)
|
||||
new_operation = random.choice(same_arity)
|
||||
|
||||
target_node.value = new_operation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user