Skip to content

Ml module#182

Closed
anathema-git wants to merge 6 commits intomasterfrom
ml_module
Closed

Ml module#182
anathema-git wants to merge 6 commits intomasterfrom
ml_module

Conversation

@anathema-git
Copy link
Collaborator

No description provided.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds an ML module to the HypEx framework, introducing advanced covariate adjustment methods for variance reduction in A/B testing. It includes CUPED (Controlled Experiments Using Pre-Experiment Data) and CUPAC (Covariate-Updated Pre-Analysis Correction) implementations.

Key changes:

  • Added DataGenerator class with support for time correlations and various distributions
  • Implemented CUPEDTransformer for classic covariate adjustment
  • Created CUPACExecutor with automatic model selection for advanced adjustment
  • Updated ABTest class to support both CUPED and CUPAC parameters

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
hypex/utils/tutorial_data_creation.py Added DataGenerator class for synthetic data with time correlations and covariate structures
hypex/utils/enums.py Added "ml" enum value for ML-related experiment data
hypex/transformers/cuped.py New CUPEDTransformer for variance reduction using pre-experiment covariates
hypex/ml/cupac.py New CUPACExecutor with automatic model selection for advanced covariate adjustment
hypex/ab.py Updated ABTest to support CUPED and CUPAC parameters with mutual exclusion
hypex/experiments/base.py Modified experiment execution to properly handle transformer sequences
Comments suppressed due to low confidence (1)

hypex/ab.py:1

  • There are extra closing parentheses on lines 90 and 91. The first closing parenthesis on line 90 closes the Multitest constructor, but there's an additional closing parenthesis on line 91 that doesn't have a matching opening parenthesis.
from __future__ import annotations

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +136 to +138
def __init__(
self,
cupac_features: Dict[str, list],
key: Any = "",
models: Optional[Dict[str, Any]] = None,
n_folds: int = 5,
random_state: Optional[int] = None,
):
super().__init__(target_role=TargetRole(), key=key)
self.cupac_features = cupac_features
self.models = models
self.n_folds = n_folds
self.random_state = random_state
self.best_model = None
self.best_model_name = None
self.best_score = None
self.variance_reduction = None
self.feature_importances_ = None
self.is_fitted = False
self.model_results_ = {}

Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This __init__ method is duplicated at lines 31-46. The class has two identical initialization methods which will cause the second one to override the first, leading to inconsistent behavior.

Suggested change
def __init__(
self,
cupac_features: Dict[str, list],
key: Any = "",
models: Optional[Dict[str, Any]] = None,
n_folds: int = 5,
random_state: Optional[int] = None,
):
super().__init__(target_role=TargetRole(), key=key)
self.cupac_features = cupac_features
self.models = models
self.n_folds = n_folds
self.random_state = random_state
self.best_model = None
self.best_model_name = None
self.best_score = None
self.variance_reduction = None
self.feature_importances_ = None
self.is_fitted = False
self.model_results_ = {}

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +69
if self.transformer:
experiment_data = deepcopy(data)
for transformer in self.transformer:
experiment_data = transformer.execute(experiment_data)
else:
experiment_data = data


Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code assumes self.transformer is iterable, but the Experiment class constructor accepts transformer: bool | None. This will cause a TypeError when trying to iterate over a boolean value.

Suggested change
if self.transformer:
experiment_data = deepcopy(data)
for transformer in self.transformer:
experiment_data = transformer.execute(experiment_data)
else:
experiment_data = data
experiment_data = deepcopy(data) if self.transformer else data
for transformer in self.transformer:
experiment_data = transformer.execute(experiment_data)

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,49 @@

Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file starts with an empty line which is unnecessary and inconsistent with other files in the codebase.

Suggested change

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3



Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file starts with three empty lines which is unnecessary and inconsistent with other files in the codebase.

Suggested change

Copilot uses AI. Check for mistakes.
@@ -1,3 +1,5 @@

Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file starts with an empty line which is unnecessary and inconsistent with other files in the codebase.

Suggested change

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants