i think i've done this shit RMSE: 0.64 !!!!

This commit is contained in:
2025-11-07 01:44:59 +03:00
parent cfae423f11
commit 74e02df205
3 changed files with 38 additions and 125 deletions

View File

@@ -7,7 +7,6 @@ from numpy.typing import NDArray
from gp import Chromosome
from gp.crossovers import crossover_subtree
from gp.fitness import (
HuberFitness,
MAEFitness,
MSEFitness,
NRMSEFitness,
@@ -26,12 +25,13 @@ from gp.population import ramped_initialization
from gp.primitive import Const, Var
from gp.selection import roulette_selection, tournament_selection
NUM_VARS = 9
NUM_VARS = 8
TEST_POINTS = 10000
MAX_DEPTH = 15
MAX_DEPTH = 10
MAX_GENERATIONS = 200
np.random.seed(17)
random.seed(17)
SEED = 17
np.random.seed(SEED)
random.seed(SEED)
X = np.random.uniform(-5.536, 5.536, size=(TEST_POINTS, NUM_VARS))
# axes = [np.linspace(-5.536, 5.536, TEST_POINTS) for _ in range(NUM_VARS)]
# X = np.array(np.meshgrid(*axes)).T.reshape(-1, NUM_VARS)
@@ -40,25 +40,6 @@ operations = [SQUARE, SIN, COS, EXP, ADD, SUB, MUL, DIV, POW]
terminals = [Var(f"x{i}") for i in range(1, NUM_VARS + 1)]
# def target_function(x: NDArray[np.float64]) -> NDArray[np.float64]:
# """
# f(x) = x1 + x2 + sin(x1)
# x имеет форму (n_samples, n_vars)
# """
# x1 = x[:, 0]
# x2 = x[:, 1]
# return x1 + x2 + np.sin(x1) + np.sin(x2) + np.exp(-x1) + np.cos(x2)
# def target_function(x: NDArray[np.float64]) -> NDArray[np.float64]:
# """
# Простая тестовая функция: сумма косинусов всех переменных.
# f(x) = sum_i cos(x_i)
# x имеет форму (n_samples, n_vars)
# """
# return np.sum(x, axis=1)
def target_function(x: NDArray[np.float64]) -> NDArray[np.float64]:
"""
Векторизованная версия функции:
@@ -72,23 +53,16 @@ def target_function(x: NDArray[np.float64]) -> NDArray[np.float64]:
return np.sum(prefix_sums, axis=1)
# def target_function(x: NDArray[np.float64]) -> NDArray[np.float64]:
# """
# Rastrigin function.
# f(x) = 10 * n + sum(x_i^2 - 10 * cos(2πx_i))
# x: shape (n_samples, n_vars)
# """
# n = x.shape[1]
# return 10 * n + np.sum(x**2 - 10 * np.cos(2 * np.pi * x), axis=1)
# fitness_function = MSEFitness(target_function, lambda: X)
# fitness = HuberFitness(target_function, lambda: X, delta=1.0)
# fitness_function = HuberFitness(target_function, lambda: X, delta=0.5)
# fitness_function = PenalizedFitness(
# target_function, lambda: X, base_fitness=fitness, lambda_=0.003
# target_function, lambda: X, base_fitness=fitness, lambda_=0.1
# )
# fitness_function = NRMSEFitness(target_function, lambda: X)
fitness_function = RMSEFitness(target_function, lambda: X)
# fitness_function = PenalizedFitness(
# target_function, lambda: X, base_fitness=fitness, lambda_=0.003
# target_function, lambda: X, base_fitness=fitness_function, lambda_=0.0001
# )
@@ -98,14 +72,6 @@ def adaptive_mutation(
max_generations: int,
max_depth: int,
) -> Chromosome:
"""Адаптивная мутация.
Меняет вероятность типов мутации по ходу эволюции:
- Ранняя фаза (<30%): 70% grow, 30% shrink
- Средняя фаза (3070%): 40% grow, 60% shrink
- Поздняя фаза (>=70%): 20% grow, 80% shrink
"""
r = random.random()
if r < 0.4:
@@ -118,57 +84,25 @@ def adaptive_mutation(
return shrink_mutation(chromosome)
# def adaptive_mutation(
# chromosome: Chromosome,
# generation: int,
# max_generations: int,
# max_depth: int,
# ) -> Chromosome:
# """Адаптивная мутация.
# Меняет вероятность типов мутации по ходу эволюции:
# - Ранняя фаза (<30%): 70% grow, 30% shrink
# - Средняя фаза (3070%): 40% grow, 60% shrink
# - Поздняя фаза (>=70%): 20% grow, 80% shrink
# """
# # Вычисляем прогресс в диапазоне [0, 1]
# if max_generations <= 0:
# progress = 0.0
# else:
# progress = min(1.0, max(0.0, generation / max_generations))
# r = random.random()
# # Определяем тип мутации
# if progress < 0.3:
# do_grow = r < 0.7
# elif progress < 0.7:
# do_grow = r < 0.4
# else:
# do_grow = r < 0.2
# # Выполняем выбранную мутацию
# if do_grow:
# return grow_mutation(chromosome, max_depth=max_depth)
# return shrink_mutation(chromosome)
init_population = ramped_initialization(
20, [i for i in range(MAX_DEPTH - 9, MAX_DEPTH + 1)], terminals, operations
)
print("Population size:", len(init_population))
config = GARunConfig(
fitness_func=fitness_function,
crossover_fn=lambda p1, p2: crossover_subtree(p1, p2, max_depth=8),
crossover_fn=lambda p1, p2: crossover_subtree(p1, p2, max_depth=MAX_DEPTH),
mutation_fn=lambda chrom, gen_num: adaptive_mutation(
chrom, gen_num, MAX_GENERATIONS, MAX_DEPTH
),
# selection_fn=roulette_selection,
selection_fn=lambda p, f: tournament_selection(p, f, k=3),
init_population=ramped_initialization(
10, [4, 5, 6, 6, 7, 7, 8, 9, 10, 11], terminals, operations
),
seed=17,
pc=0.9,
pm=0.3,
elitism=10,
init_population=init_population,
seed=SEED,
pc=0.85,
pm=0.15,
elitism=15,
max_generations=MAX_GENERATIONS,
log_every_generation=True,
)
@@ -182,6 +116,7 @@ print(result.best_generation.best.root.to_str_tree())
print(f"Лучшее значение фитнеса: {result.best_generation.best_fitness:.6f}")
print(f"Количество поколений: {result.generations_count}")
print(f"Время выполнения: {result.time_ms:.2f} мс")
print("Population size:", len(init_population))
mse_fitness = MSEFitness(target_function, lambda: X)
print(f"MSE: {mse_fitness(result.best_generation.best):.6f}")
@@ -189,7 +124,5 @@ rmse_fitness = RMSEFitness(target_function, lambda: X)
print(f"RMSE: {rmse_fitness(result.best_generation.best):.6f}")
mae_fitness = MAEFitness(target_function, lambda: X)
print(f"MAE: {mae_fitness(result.best_generation.best):.6f}")
huber_fitness = HuberFitness(target_function, lambda: X, delta=1.0)
print(f"Huber: {huber_fitness(result.best_generation.best):.6f}")
nrmse_fitness = NRMSEFitness(target_function, lambda: X)
print(f"NRMSE: {nrmse_fitness(result.best_generation.best):.6f}")