380 lines
No EOL
17 KiB
Python
380 lines
No EOL
17 KiB
Python
# Re-importing necessary libraries
|
|
import json
|
|
import matplotlib.pyplot as plt
|
|
from collections import defaultdict
|
|
import numpy as np
|
|
import pandas as pd
|
|
import seaborn as sns
|
|
import matplotlib.colors as mcolors
|
|
import matplotlib.cm as cm
|
|
import matplotlib.ticker as ticker
|
|
|
|
# Simplified JSON data for demonstration
|
|
with open('gemla/round4.json', 'r') as file:
|
|
simplified_json_data = json.load(file)
|
|
|
|
# Function to traverse the tree to find a node id
|
|
def traverse_right_nodes(node):
|
|
if node is None:
|
|
return []
|
|
|
|
right_node = node.get("right")
|
|
left_node = node.get("left")
|
|
|
|
if right_node is None and left_node is None:
|
|
return []
|
|
elif right_node and left_node:
|
|
return [right_node] + traverse_right_nodes(left_node)
|
|
|
|
return []
|
|
|
|
# Getting most recent right graph
|
|
right_nodes = traverse_right_nodes(simplified_json_data[0])
|
|
|
|
# Heatmaps
|
|
# Data structure to store mutation rates, generations, and scores
|
|
mutation_rate_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
# Populate the dictionary with scores indexed by mutation rate and generation
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
minor_mutation_rate = node_val["minor_mutation_rate"]
|
|
generation = node_val["generation"]
|
|
# Ensure each score is associated with the correct generation
|
|
for gen_index, score_list in enumerate(scores):
|
|
for score in score_list.values():
|
|
mutation_rate_data[minor_mutation_rate][gen_index].append(score)
|
|
|
|
# Prepare data for heatmap
|
|
max_generation = max(max(gens.keys()) for gens in mutation_rate_data.values())
|
|
heatmap_data = np.full((len(mutation_rate_data), max_generation + 1), np.nan)
|
|
|
|
# Populate the heatmap data with average scores
|
|
mutation_rates = sorted(mutation_rate_data.keys())
|
|
for i, mutation_rate in enumerate(mutation_rates):
|
|
for generation in range(max_generation + 1):
|
|
scores = mutation_rate_data[mutation_rate][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the heatmap
|
|
df_heatmap = pd.DataFrame(
|
|
data=heatmap_data,
|
|
index=mutation_rates,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# Data structure to store major mutation rates, generations, and scores
|
|
major_mutation_rate_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
# Populate the dictionary with scores indexed by major mutation rate and generation
|
|
# This is assuming the structure to retrieve major_mutation_rate is similar to minor_mutation_rate
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
major_mutation_rate = node_val["major_mutation_rate"]
|
|
generation = node_val["generation"]
|
|
for gen_index, score_list in enumerate(scores):
|
|
for score in score_list.values():
|
|
major_mutation_rate_data[major_mutation_rate][gen_index].append(score)
|
|
|
|
# Prepare the heatmap data for major_mutation_rate similar to minor_mutation_rate
|
|
major_heatmap_data = np.full((len(major_mutation_rate_data), max_generation + 1), np.nan)
|
|
major_mutation_rates = sorted(major_mutation_rate_data.keys())
|
|
|
|
for i, major_rate in enumerate(major_mutation_rates):
|
|
for generation in range(max_generation + 1):
|
|
scores = major_mutation_rate_data[major_rate][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
major_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_major_heatmap = pd.DataFrame(
|
|
data=major_heatmap_data,
|
|
index=major_mutation_rates,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# crossbreed_segments
|
|
# Data structure to store major mutation rates, generations, and scores
|
|
crossbreed_segments_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
# Populate the dictionary with scores indexed by major mutation rate and generation
|
|
# This is assuming the structure to retrieve major_mutation_rate is similar to minor_mutation_rate
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
crossbreed_segments = node_val["crossbreed_segments"]
|
|
generation = node_val["generation"]
|
|
for gen_index, score_list in enumerate(scores):
|
|
for score in score_list.values():
|
|
crossbreed_segments_data[crossbreed_segments][gen_index].append(score)
|
|
|
|
# Prepare the heatmap data for crossbreed_segments similar to minor_mutation_rate
|
|
crossbreed_heatmap_data = np.full((len(crossbreed_segments_data), max_generation + 1), np.nan)
|
|
crossbreed_segments = sorted(crossbreed_segments_data.keys())
|
|
|
|
for i, crossbreed_segment in enumerate(crossbreed_segments):
|
|
for generation in range(max_generation + 1):
|
|
scores = crossbreed_segments_data[crossbreed_segment][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
crossbreed_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_crossbreed_heatmap = pd.DataFrame(
|
|
data=crossbreed_heatmap_data,
|
|
index=crossbreed_segments,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# mutation_weight_range
|
|
# Data structure to store major mutation rates, generations, and scores
|
|
mutation_weight_range_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
# Populate the dictionary with scores indexed by major mutation rate and generation
|
|
# This is assuming the structure to retrieve major_mutation_rate is similar to minor_mutation_rate
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
mutation_weight_range = node_val["mutation_weight_range"]
|
|
positive_extent = mutation_weight_range["end"]
|
|
negative_extent = -mutation_weight_range["start"]
|
|
mutation_weight_range = (positive_extent + negative_extent) / 2
|
|
generation = node_val["generation"]
|
|
for gen_index, score_list in enumerate(scores):
|
|
for score in score_list.values():
|
|
mutation_weight_range_data[mutation_weight_range][gen_index].append(score)
|
|
|
|
# Prepare the heatmap data for crossbreed_segments similar to minor_mutation_rate
|
|
mutation_weight_range_heatmap_data = np.full((len(mutation_weight_range_data), max_generation + 1), np.nan)
|
|
mutation_weight_ranges = sorted(mutation_weight_range_data.keys())
|
|
|
|
for i, mutation_weight_range in enumerate(mutation_weight_ranges):
|
|
for generation in range(max_generation + 1):
|
|
scores = mutation_weight_range_data[mutation_weight_range][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
mutation_weight_range_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_mutation_weight_range_heatmap = pd.DataFrame(
|
|
data=mutation_weight_range_heatmap_data,
|
|
index=mutation_weight_ranges,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# weight_initialization_range
|
|
# Data structure to store major mutation rates, generations, and scores
|
|
weight_initialization_range_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
# Populate the dictionary with scores indexed by major mutation rate and generation
|
|
# This is assuming the structure to retrieve major_mutation_rate is similar to minor_mutation_rate
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
weight_initialization_range = node_val["weight_initialization_range"]
|
|
positive_extent = weight_initialization_range["end"]
|
|
negative_extent = -weight_initialization_range["start"]
|
|
weight_initialization_range = (positive_extent + negative_extent) / 2
|
|
generation = node_val["generation"]
|
|
for gen_index, score_list in enumerate(scores):
|
|
for score in score_list.values():
|
|
weight_initialization_range_data[weight_initialization_range][gen_index].append(score)
|
|
|
|
# Prepare the heatmap data for crossbreed_segments similar to minor_mutation_rate
|
|
weight_initialization_range_heatmap_data = np.full((len(weight_initialization_range_data), max_generation + 1), np.nan)
|
|
weight_initialization_ranges = sorted(weight_initialization_range_data.keys())
|
|
|
|
for i, weight_initialization_range in enumerate(weight_initialization_ranges):
|
|
for generation in range(max_generation + 1):
|
|
scores = weight_initialization_range_data[weight_initialization_range][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
weight_initialization_range_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_weight_initialization_range_heatmap = pd.DataFrame(
|
|
data=weight_initialization_range_heatmap_data,
|
|
index=weight_initialization_ranges,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# weight_initialization_range_skew
|
|
# Data structure to store major mutation rates, generations, and scores
|
|
weight_initialization_range_skew_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
# Populate the dictionary with scores indexed by major mutation rate and generation
|
|
# This is assuming the structure to retrieve major_mutation_rate is similar to minor_mutation_rate
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
weight_initialization_range = node_val["weight_initialization_range"]
|
|
positive_extent = weight_initialization_range["end"]
|
|
negative_extent = -weight_initialization_range["start"]
|
|
weight_initialization_range_skew = (positive_extent - negative_extent) / 2
|
|
generation = node_val["generation"]
|
|
for gen_index, score_list in enumerate(scores):
|
|
for score in score_list.values():
|
|
weight_initialization_range_skew_data[weight_initialization_range_skew][gen_index].append(score)
|
|
|
|
# Prepare the heatmap data for crossbreed_segments similar to minor_mutation_rate
|
|
weight_initialization_range_skew_heatmap_data = np.full((len(weight_initialization_range_skew_data), max_generation + 1), np.nan)
|
|
weight_initialization_range_skews = sorted(weight_initialization_range_skew_data.keys())
|
|
|
|
for i, weight_initialization_range_skew in enumerate(weight_initialization_range_skews):
|
|
for generation in range(max_generation + 1):
|
|
scores = weight_initialization_range_skew_data[weight_initialization_range_skew][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
weight_initialization_range_skew_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_weight_initialization_range_skew_heatmap = pd.DataFrame(
|
|
data=weight_initialization_range_skew_heatmap_data,
|
|
index=weight_initialization_range_skews,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# Analyze number of neurons correlation to score
|
|
# We can get the number of neurons via node_val["nn_shapes"] which contains an array of maps
|
|
# Each map has a key for the individual id and a value which is an array of integers representing the number of neurons in each layer
|
|
# We can use the individual id to get the score from the scores array
|
|
# We then generate a density map of the number of neurons vs the score
|
|
neuron_number_score_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
nn_shapes = node_val["nn_shapes"]
|
|
# Both scores and nn_shapes are arrays where score is 1 less in length than nn_shapes (each index corresponds to a generation)
|
|
for gen_index, score in enumerate(scores):
|
|
for individual_id, nn_shape in nn_shapes[gen_index].items():
|
|
neuron_number = sum(nn_shape)
|
|
# check if score has a value for the individual id
|
|
if individual_id not in score:
|
|
continue
|
|
neuron_number_score_data[neuron_number][gen_index].append(score[individual_id])
|
|
|
|
# prepare the density map data
|
|
neuron_number_score_heatmap_data = np.full((len(neuron_number_score_data), max_generation + 1), np.nan)
|
|
neuron_numbers = sorted(neuron_number_score_data.keys())
|
|
|
|
for i, neuron_number in enumerate(neuron_numbers):
|
|
for generation in range(max_generation + 1):
|
|
scores = neuron_number_score_data[neuron_number][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
neuron_number_score_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_neuron_number_score_heatmap = pd.DataFrame(
|
|
data=neuron_number_score_heatmap_data,
|
|
index=neuron_numbers,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# Analyze number of layers correlation to score
|
|
nn_layers_score_data = defaultdict(lambda: defaultdict(list))
|
|
|
|
for node in right_nodes:
|
|
node_val = node["val"]["node"]
|
|
if node_val:
|
|
scores = node_val["scores"]
|
|
nn_shapes = node_val["nn_shapes"]
|
|
# Both scores and nn_shapes are arrays where score is 1 less in length than nn_shapes (each index corresponds to a generation)
|
|
for gen_index, score in enumerate(scores):
|
|
for individual_id, nn_shape in nn_shapes[gen_index].items():
|
|
layer_number = len(nn_shape)
|
|
# check if score has a value for the individual id
|
|
if individual_id not in score:
|
|
continue
|
|
nn_layers_score_data[layer_number][gen_index].append(score[individual_id])
|
|
|
|
# prepare the density map data
|
|
nn_layers_score_heatmap_data = np.full((len(nn_layers_score_data), max_generation + 1), np.nan)
|
|
nn_layers = sorted(nn_layers_score_data.keys())
|
|
|
|
for i, nn_layer in enumerate(nn_layers):
|
|
for generation in range(max_generation + 1):
|
|
scores = nn_layers_score_data[nn_layer][generation]
|
|
if scores: # Check if there are scores for this generation
|
|
nn_layers_score_heatmap_data[i, generation] = np.mean(scores)
|
|
|
|
# Creating a DataFrame for the major mutation rate heatmap
|
|
df_nn_layers_score_heatmap = pd.DataFrame(
|
|
data=nn_layers_score_heatmap_data,
|
|
index=nn_layers,
|
|
columns=range(max_generation + 1)
|
|
)
|
|
|
|
# print("Format: ", custom_formatter(0.123498761234, 0))
|
|
|
|
# Creating subplots
|
|
fig, axs = plt.subplots(2, 2, figsize=(20, 14)) # Creates a 3x2 grid of subplots
|
|
|
|
# Plotting the minor mutation rate heatmap
|
|
sns.heatmap(df_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs[0, 0])
|
|
# axs[0, 0].set_title('Minor Mutation Rate')
|
|
axs[0, 0].set_xlabel('Minor Mutation Rate')
|
|
axs[0, 0].set_ylabel('Generation')
|
|
axs[0, 0].invert_yaxis()
|
|
|
|
# Plotting the major mutation rate heatmap
|
|
sns.heatmap(df_major_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs[0, 1])
|
|
# axs[0, 1].set_title('Major Mutation Rate')
|
|
axs[0, 1].set_xlabel('Major Mutation Rate')
|
|
axs[0, 1].invert_yaxis()
|
|
|
|
# Plotting the crossbreed_segments heatmap
|
|
sns.heatmap(df_crossbreed_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs[1, 0])
|
|
# axs[1, 0].set_title('Crossbreed Segments')
|
|
axs[1, 0].set_xlabel('Crossbreed Segments')
|
|
axs[1, 0].set_ylabel('Generation')
|
|
axs[1, 0].invert_yaxis()
|
|
|
|
# Plotting the mutation_weight_range heatmap
|
|
sns.heatmap(df_mutation_weight_range_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs[1, 1])
|
|
# axs[1, 1].set_title('Mutation Weight Range')
|
|
axs[1, 1].set_xlabel('Mutation Weight Range')
|
|
axs[1, 1].invert_yaxis()
|
|
|
|
fig3, axs3 = plt.subplots(1, 2, figsize=(20, 14)) # Creates a 3x2 grid of subplots
|
|
|
|
# Plotting the weight_initialization_range heatmap
|
|
sns.heatmap(df_weight_initialization_range_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs3[0])
|
|
# axs[2, 0].set_title('Weight Initialization Range')
|
|
axs3[0].set_xlabel('Weight Initialization Range')
|
|
axs3[0].set_ylabel('Generation')
|
|
axs3[0].invert_yaxis()
|
|
|
|
# Plotting the weight_initialization_range_skew heatmap
|
|
sns.heatmap(df_weight_initialization_range_skew_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs3[1])
|
|
# axs[2, 1].set_title('Weight Initialization Range Skew')
|
|
axs3[1].set_xlabel('Weight Initialization Range Skew')
|
|
axs3[1].set_ylabel('Generation')
|
|
axs3[1].invert_yaxis()
|
|
|
|
# Creating a new window for the scatter plots
|
|
fig2, axs2 = plt.subplots(2, 1, figsize=(20, 14)) # Creates a 2x1 grid of subplots
|
|
|
|
# Plotting the neuron number vs score heatmap
|
|
sns.heatmap(df_neuron_number_score_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs2[1])
|
|
# axs[3, 1].set_title('Neuron Number vs. Score')
|
|
axs2[1].set_xlabel('Neuron Number')
|
|
axs2[1].set_ylabel('Generation')
|
|
axs2[1].invert_yaxis()
|
|
|
|
# Plotting the number of layers vs score heatmap
|
|
sns.heatmap(df_nn_layers_score_heatmap.T, cmap='viridis', fmt=".4g", cbar_kws={'label': 'Mean Score'}, ax=axs2[0])
|
|
# axs[3, 1].set_title('Number of Layers vs. Score')
|
|
axs2[0].set_xlabel('Number of Layers')
|
|
axs2[0].set_ylabel('Generation')
|
|
axs2[0].invert_yaxis()
|
|
|
|
# Display the plot
|
|
plt.tight_layout() # Adjusts the subplots to fit into the figure area.
|
|
plt.show() |