From: Matt Corallo Date: Sat, 23 Nov 2024 16:11:46 +0000 (+0000) Subject: Break out averages for channels we had no data for X-Git-Url: http://git.bitcoin.ninja//?a=commitdiff_plain;h=1e53941f68200bb5aee4ee11e9e3fb99ab6d9432;p=ln-routing-replay Break out averages for channels we had no data for --- diff --git a/src/main.rs b/src/main.rs index 545432b..d776c11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,10 @@ pub struct State<'a> { success_result_count: u64, failure_loss_sum: f64, failure_result_count: u64, + no_data_success_loss_sum: f64, + no_data_success_result_count: u64, + no_data_failure_loss_sum: f64, + no_data_failure_result_count: u64, } /// Creates a new [`State`] before any probe results are processed. @@ -25,6 +29,10 @@ pub fn do_setup<'a>(graph: &'a NetworkGraph) -> State { success_result_count: 0, failure_loss_sum: 0.0, failure_result_count: 0, + no_data_success_loss_sum: 0.0, + no_data_success_result_count: 0, + no_data_failure_loss_sum: 0.0, + no_data_failure_result_count: 0, } } @@ -45,32 +53,44 @@ pub fn process_probe_result(network_graph: ReadOnlyNetworkGraph, result: ProbeRe for hop in result.channels_with_sufficient_liquidity.iter() { // You can get additional information about the channel from the network_graph: let _chan = network_graph.channels().get(&hop.short_channel_id).unwrap(); + let mut no_data = false; let mut model_probability = state.scorer.historical_estimated_payment_success_probability(hop.short_channel_id, &hop.dst_node_id, hop.amount_msat, &Default::default()) - .unwrap_or_else(|| + .unwrap_or_else(|| { + no_data = true; // If LDK doesn't have sufficient historical state it will fall back to (roughly) the live model. state.scorer .live_estimated_payment_success_probability(hop.short_channel_id, &hop.dst_node_id, hop.amount_msat, &Default::default()) .expect("We should have some estimated probability, even without history data") - ); + }); if model_probability < 0.01 { model_probability = 0.01; } state.success_loss_sum -= model_probability.log2(); state.success_result_count += 1; + if no_data { + state.no_data_success_loss_sum -= model_probability.log2(); + state.no_data_success_result_count += 1; + } } if let Some(hop) = &result.channel_that_rejected_payment { // You can get additional information about the channel from the network_graph: let _chan = network_graph.channels().get(&hop.short_channel_id).unwrap(); + let mut no_data = false; let mut model_probability = state.scorer.historical_estimated_payment_success_probability(hop.short_channel_id, &hop.dst_node_id, hop.amount_msat, &Default::default()) - .unwrap_or_else(|| + .unwrap_or_else(|| { + no_data = true; // If LDK doesn't have sufficient historical state it will fall back to (roughly) the live model. state.scorer .live_estimated_payment_success_probability(hop.short_channel_id, &hop.dst_node_id, hop.amount_msat, &Default::default()) .expect("We should have some estimated probability, even without history data") - ); + }); if model_probability > 0.99 { model_probability = 0.99; } state.failure_loss_sum -= (1.0 - model_probability).log2(); state.failure_result_count += 1; + if no_data { + state.no_data_failure_loss_sum -= (1.0 - model_probability).log2(); + state.no_data_failure_result_count += 1; + } } // Update the model with the information we learned @@ -102,10 +122,27 @@ pub fn process_probe_result(network_graph: ReadOnlyNetworkGraph, result: ProbeRe /// This is run after all probe results have been processed, and should be used for printing /// results or any required teardown. pub fn results_complete(state: State) { - // We break out log-loss for failure and success hops as there are substantially more - // succeeding hops than there are failing hops. - println!("Avg success log-loss {}", state.success_loss_sum / (state.success_result_count as f64)); - println!("Avg failure log-loss {}", state.failure_loss_sum / (state.failure_result_count as f64)); + // We break out log-loss for failure and success hops and print averages between the two + // (rather than in aggregate) as there are substantially more succeeding hops than there are + // failing hops. + let no_data_suc = state.no_data_success_loss_sum / (state.no_data_success_result_count as f64); + let no_data_fail = state.no_data_failure_loss_sum / (state.no_data_failure_result_count as f64); + println!("Avg no-data success log-loss {}", no_data_suc); + println!("Avg no-data failure log-loss {}", no_data_fail); + println!("Avg no-data success+failure log-loss {}", (no_data_suc + no_data_fail) / 2.0); + println!(); + let avg_hist_suc = (state.success_loss_sum - state.no_data_success_loss_sum) / ((state.success_result_count - state.no_data_success_result_count) as f64); + let avg_hist_fail = (state.failure_loss_sum - state.no_data_failure_loss_sum) / ((state.failure_result_count - state.no_data_failure_result_count) as f64); + println!("Avg historical data success log-loss {}", avg_hist_suc); + println!("Avg historical data failure log-loss {}", avg_hist_fail); + println!("Avg hist data suc+fail average log-loss {}", (avg_hist_suc + avg_hist_fail) / 2.0); + println!(); + let avg_suc = state.success_loss_sum / (state.success_result_count as f64); + let avg_fail = state.failure_loss_sum / (state.failure_result_count as f64); + println!("Avg success log-loss {}", avg_suc); + println!("Avg failure log-loss {}", avg_fail); + println!("Avg success+failure average log-loss {}", (avg_suc + avg_fail) / 2.0); + println!(); let loss_sum = state.success_loss_sum + state.failure_loss_sum; let result_count = state.success_result_count + state.failure_result_count; println!("Avg log-loss {}", loss_sum / (result_count as f64));