From a79769cb0108f5668459c8a46cec87da6d6393bb Mon Sep 17 00:00:00 2001 From: "Xavier C. Llano" Date: Tue, 9 Jun 2026 18:34:19 -0500 Subject: [PATCH] Fix estimator variance and allocation formulas --- AcATaMa/gui/accuracy_assessment_results.py | 22 ++++++++++++++-------- AcATaMa/utils/sampling_utils.py | 6 ++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/AcATaMa/gui/accuracy_assessment_results.py b/AcATaMa/gui/accuracy_assessment_results.py index 560c6c0..df83b18 100644 --- a/AcATaMa/gui/accuracy_assessment_results.py +++ b/AcATaMa/gui/accuracy_assessment_results.py @@ -35,6 +35,18 @@ def rf(fv, r=5): return round(fv, r) +def post_stratified_variance_table(error_matrix): + return [ + [ + cell_count * (1 - cell_count / total_row) / (total_row - 1) + if total_row not in [0, 1] + else np.nan + for cell_count in row + ] + for total_row, row in zip([sum(r) for r in error_matrix], error_matrix, strict=True) + ] + + @error_handler def get_html(accu_asse): ########################################################################### @@ -637,10 +649,7 @@ def get_html(accu_asse): # the error for post-stratified if accu_asse.estimator == "Simple/systematic post-stratified estimator": - ui_table = [ - [(1 - i / total_row) ** 2 * i / (total_row - 1) if total_row not in [0, 1] else np.nan for i in row] - for total_row, row in zip([sum(r) for r in accu_asse.error_matrix], accu_asse.error_matrix, strict=True) - ] + ui_table = post_stratified_variance_table(accu_asse.error_matrix) wi = [accu_asse.thematic_pixels_count[value] / total_pixels_classes for value in accu_asse.values] variance = [ ((1 - total_samples / total_pixels_classes) / total_samples) @@ -1038,10 +1047,7 @@ def export_to_csv(accu_asse, file_out, csv_separator, csv_decimal_separator): # the error for post-stratified if accu_asse.estimator == "Simple/systematic post-stratified estimator": - ui_table = [ - [(1 - i / total_row) ** 2 * i / (total_row - 1) if total_row not in [0, 1] else np.nan for i in row] - for total_row, row in zip([sum(r) for r in accu_asse.error_matrix], accu_asse.error_matrix, strict=True) - ] + ui_table = post_stratified_variance_table(accu_asse.error_matrix) wi = [accu_asse.thematic_pixels_count[value] / total_pixels_classes for value in accu_asse.values] variance = [ ((1 - total_samples / total_pixels_classes) / total_samples) diff --git a/AcATaMa/utils/sampling_utils.py b/AcATaMa/utils/sampling_utils.py index 2d24bdb..c8185cc 100644 --- a/AcATaMa/utils/sampling_utils.py +++ b/AcATaMa/utils/sampling_utils.py @@ -49,13 +49,15 @@ def get_num_samples_by_area_based_proportion(srs_table, total_std_error): total_pixel_count = float(sum(mask(srs_table["pixel_count"], srs_table["On"]))) ratio_pixel_count = [p_c / total_pixel_count for p_c in mask(srs_table["pixel_count"], srs_table["On"])] Si = [(float(ui) * (1 - float(ui))) ** 0.5 for ui in mask(srs_table["ui"], srs_table["On"])] - total_num_samples = (sum(rpc * si for rpc, si in zip(ratio_pixel_count, Si, strict=True)) / total_std_error) ** 2 + weighted_std_sum = sum(rpc * si for rpc, si in zip(ratio_pixel_count, Si, strict=True)) + total_num_samples = (weighted_std_sum / total_std_error) ** 2 num_samples = [] idx = 0 for item_enable in srs_table["On"]: if item_enable: - num_samples.append(str(round(ratio_pixel_count[idx] * total_num_samples))) + allocation_weight = ratio_pixel_count[idx] * Si[idx] / weighted_std_sum if weighted_std_sum > 0 else 0 + num_samples.append(str(round(allocation_weight * total_num_samples))) idx += 1 else: num_samples.append("0")