2828 "model" : [],
2929 "model_dim" : [],
3030 "ret_k" : [],
31- "recall@k " : [],
32- "ndcg@k " : [],
33- "f1@k " : [],
31+ "recall" : [],
32+ "ndcg" : [],
33+ "f1" : [],
3434 "precision" : [],
3535 "algorithm" : [],
3636 "ef_construction" : [],
3737 "ef_runtime" : [],
3838 "m" : [],
3939 "distance_metric" : [],
4040 "vector_data_type" : [],
41+ "objective_value" : [],
4142}
4243
4344
@@ -52,12 +53,13 @@ def update_metric_row(trial_settings: TrialSettings, trial_metrics: dict):
5253 METRICS ["vector_data_type" ].append (trial_settings .index_settings .vector_data_type )
5354 METRICS ["model" ].append (trial_settings .embedding .model )
5455 METRICS ["model_dim" ].append (trial_settings .embedding .dim )
55- METRICS ["recall@k " ].append (trial_metrics ["recall" ])
56- METRICS ["ndcg@k " ].append (trial_metrics ["ndcg" ])
56+ METRICS ["recall" ].append (trial_metrics ["recall" ])
57+ METRICS ["ndcg" ].append (trial_metrics ["ndcg" ])
5758 METRICS ["precision" ].append (trial_metrics ["precision" ])
58- METRICS ["f1@k " ].append (trial_metrics ["f1" ])
59+ METRICS ["f1" ].append (trial_metrics ["f1" ])
5960 METRICS ["total_indexing_time" ].append (trial_metrics ["total_indexing_time" ])
6061 METRICS ["avg_query_time" ].append (trial_metrics ["avg_query_time" ])
62+ METRICS ["objective_value" ].append (trial_metrics ["objective_value" ])
6163
6264
6365def persist_metrics (
@@ -70,17 +72,30 @@ def persist_metrics(
7072 client .json ().set (f"study:{ study_id } " , Path .root_path (), METRICS )
7173
7274
75+ def norm_metric (value : float ):
76+ """Normalize a metric value using 1/(1+value) formula.
77+
78+ Handles edge cases:
79+ - When value is -1, returns a large positive number (infinity equivalent)
80+ - When value is very negative, returns a large positive number
81+ - When value is very positive, returns a small positive number
82+ """
83+ if value == - 1 :
84+ # Return a large positive number to represent "infinity" for optimization
85+ return 1000.0
86+ return 1 / (1 + value )
87+
88+
7389def cost_fn (metrics : dict , weights : dict ):
7490 objective = 0
7591 for key in metrics :
76- objective += weights .get (key , 0 ) * metrics [key ]
92+ if key == "avg_query_time" or key == "total_indexing_time" :
93+ objective += weights .get (key , 0 ) * - norm_metric (metrics [key ])
94+ else :
95+ objective += weights .get (key , 0 ) * metrics [key ]
7796 return objective
7897
7998
80- def norm_metric (value : float ):
81- return 1 / (1 + value )
82-
83-
8499def objective (trial , study_config , redis_url , corpus_processor , search_method_map ):
85100
86101 # optimizer will select hyperparameters from available option in study_config
@@ -152,19 +167,19 @@ def objective(trial, study_config, redis_url, corpus_processor, search_method_ma
152167 search_method_output = search_fn (search_input )
153168
154169 trial_metrics = utils .eval_trial_metrics (qrels , search_method_output .run )
155- trial_metrics ["total_indexing_time" ] = - (total_indexing_time )
156- trial_metrics ["avg_query_time" ] = - (
157- utils .get_query_time_stats (search_method_output .query_metrics .query_times )[
158- "avg_query_time"
159- ]
170+ trial_metrics ["total_indexing_time" ] = total_indexing_time
171+ trial_metrics ["avg_query_time" ] = utils .get_query_time_stats (
172+ search_method_output .query_metrics .query_times
173+ )["avg_query_time" ]
174+
175+ trial_metrics ["objective_value" ] = cost_fn (
176+ trial_metrics , study_config .optimization_settings .metric_weights .model_dump ()
160177 )
161178
162179 # save results as we go in case of failure
163180 persist_metrics (redis_url , trial_settings , trial_metrics , study_config .study_id )
164181
165- return cost_fn (
166- trial_metrics , study_config .optimization_settings .metric_weights .model_dump ()
167- )
182+ return trial_metrics ["objective_value" ]
168183
169184
170185def run_bayes_study (
0 commit comments