edgepoint 3.5.0__tar.gz → 3.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {edgepoint-3.5.0 → edgepoint-3.5.2}/PKG-INFO +1 -1
  2. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/main.py +31 -18
  3. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint.egg-info/PKG-INFO +1 -1
  4. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint.egg-info/SOURCES.txt +0 -2
  5. {edgepoint-3.5.0 → edgepoint-3.5.2}/pyproject.toml +1 -1
  6. {edgepoint-3.5.0 → edgepoint-3.5.2}/setup.py +1 -1
  7. edgepoint-3.5.0/edgepoint/core_v1.py +0 -573
  8. edgepoint-3.5.0/edgepoint/main_old.py +0 -713
  9. {edgepoint-3.5.0 → edgepoint-3.5.2}/LICENSE +0 -0
  10. {edgepoint-3.5.0 → edgepoint-3.5.2}/README.md +0 -0
  11. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/__init__.py +0 -0
  12. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/aggregate_kfold_combos.py +0 -0
  13. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/aggregate_kfold_edges.py +0 -0
  14. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/core.py +0 -0
  15. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/run_kfold_find.py +0 -0
  16. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/run_kfold_search.py +0 -0
  17. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/sanity_check.py +0 -0
  18. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/split_router.py +0 -0
  19. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/stratified_folds.py +0 -0
  20. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/test_and_combo_val.py +0 -0
  21. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/train_combo.py +0 -0
  22. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/utils.py +0 -0
  23. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint/validations.py +0 -0
  24. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint.egg-info/dependency_links.txt +0 -0
  25. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint.egg-info/requires.txt +0 -0
  26. {edgepoint-3.5.0 → edgepoint-3.5.2}/edgepoint.egg-info/top_level.txt +0 -0
  27. {edgepoint-3.5.0 → edgepoint-3.5.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edgepoint
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Find the point in a numeric column above which a binary outcome becomes meaningfully and reliably better.
5
5
  Author: Henry
6
6
  License: MIT
@@ -510,6 +510,9 @@ def search(df, outcome_col="hit", min_coverage=10, show_progress=True, top_combo
510
510
  # fold (see test_and_combo_val's fold_combos_df filtering). Those
511
511
  # aren't "no data", they're "didn't qualify", so they're excluded
512
512
  # here rather than shown as _te NaN rows.
513
+ # A further baseline check runs after the merge: any combo whose
514
+ # train or test hit_rate falls below baseline_full is disqualified
515
+ # here too, see below.
513
516
  stage_start = time.time()
514
517
  if show_progress:
515
518
  _stage_header(5, TOTAL_STAGES, "Merge Combos (train vs test)")
@@ -519,12 +522,39 @@ def search(df, outcome_col="hit", min_coverage=10, show_progress=True, top_combo
519
522
  on=["combo_num", "combo"], how="inner", suffixes=("_tr", "_te"),
520
523
  )
521
524
  merged_combos_df = _add_final_score(merged_combos_df)
525
+
526
+ # Snapshot the count right after the inner merge (i.e. how many combos
527
+ # actually passed test validation), BEFORE the baseline filter below
528
+ # removes any rows. Needed purely so the Stage 5 print message can show
529
+ # test-validation survivors, baseline-disqualified, and final remaining
530
+ # as one coherent chain instead of leaving an unaccounted-for gap
531
+ # between top_combos_df's total and the post-baseline-filter count.
532
+ n_test_qualified = len(merged_combos_df)
533
+ if show_progress:
534
+ print(f"{n_test_qualified}/{len(top_combos_df)} combo(s) entered (passed test validation).")
535
+ print()
536
+
537
+ # Disqualify any combo whose train OR test hit_rate falls below
538
+ # baseline_full - a combo that can't beat "doing nothing" on even
539
+ # one side isn't a real edge, no blended final_score should be able
540
+ # to paper over that. hit_rate_tr/te arrive as formatted strings
541
+ # (see recommend()'s combo_summary_df), so cast to float to compare.
542
+ n_disqualified = 0
543
+ if baseline_full is not None and not merged_combos_df.empty:
544
+ hr_tr = merged_combos_df["hit_rate_tr"].astype(float)
545
+ hr_te = merged_combos_df["hit_rate_te"].astype(float)
546
+ below_baseline_mask = (hr_tr < baseline_full) | (hr_te < baseline_full)
547
+ n_disqualified = int(below_baseline_mask.sum())
548
+ merged_combos_df = merged_combos_df[~below_baseline_mask].reset_index(drop=True)
549
+
522
550
  merged_combos_df = merged_combos_df.sort_values("final_score", ascending=False).reset_index(drop=True)
523
551
 
524
552
  if show_progress:
525
553
  display_combos_df, combos_legend = _abbreviate_table(
526
554
  merged_combos_df, extra_drop_bases=("miss_rate", "gap")
527
555
  )
556
+ print(f"{n_disqualified}/{n_test_qualified} sliced (below baseline {baseline_full:.2f}) -> {len(merged_combos_df)} remain.")
557
+ print()
528
558
  print(f"=== MERGED COMBOS (train vs test, test-qualified only) - {len(merged_combos_df)}/{len(top_combos_df)} combo(s) ===")
529
559
  print()
530
560
  _print_legend(combos_legend)
@@ -545,21 +575,4 @@ def search(df, outcome_col="hit", min_coverage=10, show_progress=True, top_combo
545
575
  _stage_footer(stage_start, run_start)
546
576
  _complete(run_start)
547
577
 
548
- return edgepoints_df, top_combos
549
-
550
- """
551
- if __name__ == "__main__":
552
- rows, headers = MySql.Select(
553
- "SELECT * FROM bucket WHERE pick = %s",
554
- ("home_win",),
555
- headers=True
556
- )
557
- df = pd.DataFrame(rows, columns=headers)
558
-
559
- # Split ratio is auto-detected from row count inside search()'s
560
- # Stage 1 (via split_router.split_dataset). Nothing else changes.
561
- edgepoints_df, top_combos = search(
562
- df, outcome_col="hit", min_coverage=10, show_progress=True,
563
- top_combo_n=3,
564
- )
565
- """
578
+ return edgepoints_df, top_combos
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edgepoint
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Find the point in a numeric column above which a binary outcome becomes meaningfully and reliably better.
5
5
  Author: Henry
6
6
  License: MIT
@@ -6,9 +6,7 @@ edgepoint/__init__.py
6
6
  edgepoint/aggregate_kfold_combos.py
7
7
  edgepoint/aggregate_kfold_edges.py
8
8
  edgepoint/core.py
9
- edgepoint/core_v1.py
10
9
  edgepoint/main.py
11
- edgepoint/main_old.py
12
10
  edgepoint/run_kfold_find.py
13
11
  edgepoint/run_kfold_search.py
14
12
  edgepoint/sanity_check.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "edgepoint"
7
- version = "3.5.0"
7
+ version = "3.5.2"
8
8
  description = "Find the point in a numeric column above which a binary outcome becomes meaningfully and reliably better."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -5,7 +5,7 @@ long_description = (Path(__file__).parent / "README.md").read_text(encoding="utf
5
5
 
6
6
  setup(
7
7
  name="edgepoint",
8
- version="3.5.0",
8
+ version="3.5.2",
9
9
  author="Henry",
10
10
  description="Find where a metric, or combination of metrics, starts getting better while keeping the best coverage possible, then check if that holds on unseen data.",
11
11
  long_description=long_description,