Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
69bf3dd
aan added
TonyKatkov89 Jul 1, 2025
daced5d
best split assembled correctly
TonyKatkov89 Jul 11, 2025
02de68b
tutorail updated, test added
TonyKatkov89 Jul 14, 2025
b50ec9c
tutorials
anastasiiafed24 Jul 17, 2025
c2d4dd8
tutorials fix
anastasiiafed24 Jul 17, 2025
b41fb39
started
TonyKatkov89 Jul 17, 2025
9b428a5
Merge pull request #179 from sb-ai-lab/dev/aan
TonyKatkov89 Jul 21, 2025
182042e
Merge branch 'dev/master' into dev/tutorials
anastasiiafed24 Jul 21, 2025
78cf3ca
upd
anastasiiafed24 Jul 21, 2025
b999c42
Merge pull request #180 from sb-ai-lab/dev/tutorials
anastasiiafed24 Jul 21, 2025
1c9e495
started
TonyKatkov89 Jul 23, 2025
5eedbd2
indexes displayed
TonyKatkov89 Jul 31, 2025
e9f121b
mantching n-neighbours added
TonyKatkov89 Aug 13, 2025
3f94ddd
Merge remote-tracking branch 'origin/dev/master' into dev/custom_weights
TonyKatkov89 Aug 28, 2025
8919e85
Merge pull request #181 from sb-ai-lab/dev/custom_weights
TonyKatkov89 Aug 28, 2025
12d2f1d
comment removed
TonyKatkov89 Sep 4, 2025
91e5793
updated groups assignment
TonyKatkov89 Sep 4, 2025
b0d4026
cleaned
TonyKatkov89 Sep 4, 2025
eb074d7
comments added
TonyKatkov89 Sep 9, 2025
4ac4b8d
Merge pull request #185 from sb-ai-lab/dev/custom_weights
TonyKatkov89 Sep 9, 2025
006a524
Merge remote-tracking branch 'origin/dev/custom_weights' into dev/cus…
TonyKatkov89 Sep 18, 2025
2e76ac5
Ml module
anathema-git Sep 18, 2025
f707bbf
custom_weights added
TonyKatkov89 Sep 18, 2025
8f749a6
matching fixed
TonyKatkov89 Sep 24, 2025
d39c87d
matching fixed
TonyKatkov89 Sep 24, 2025
b5b777a
Merge remote-tracking branch 'origin/dev/master' into dev/custom_weights
TonyKatkov89 Sep 24, 2025
a850ae6
fixes as per the comments
TonyKatkov89 Sep 25, 2025
e0925bb
one feature fix
TonyKatkov89 Sep 25, 2025
8bfd0c9
quality result fix
TonyKatkov89 Sep 25, 2025
1a0ab81
const_groups fix
TonyKatkov89 Sep 29, 2025
c5bea80
aa tutorial updated
TonyKatkov89 Sep 29, 2025
07c3894
old ab tutorial restored
TonyKatkov89 Sep 29, 2025
c22fd8d
first tests added
Sep 29, 2025
04251ca
matching tests
Sep 30, 2025
cdd5859
matching tests
Sep 30, 2025
9fa0223
matching tests
Sep 30, 2025
b9b359f
matching tutorial updated
TonyKatkov89 Sep 30, 2025
6797ce7
ab multitest fixed
TonyKatkov89 Sep 30, 2025
347d50c
without CausalInference
Oct 1, 2025
197fafc
CI n HypEx matching tests
Oct 2, 2025
64ba16f
CI n HypEx matching tests
Oct 2, 2025
5b4fac2
matching tests
Oct 7, 2025
9be4634
matching tests
Oct 7, 2025
b1e22ae
take method added
TonyKatkov89 Oct 8, 2025
11b716e
group fixed, atc broken
TonyKatkov89 Oct 8, 2025
20443c7
matching fully fixed
TonyKatkov89 Oct 9, 2025
e7f3699
const groups div by 0 fix
TonyKatkov89 Oct 9, 2025
7d3f589
Merge pull request #190 from sb-ai-lab/dev/matching_tests
Vigosya Oct 9, 2025
ea9008c
comments added, auto ks-test removed from ab
TonyKatkov89 Oct 13, 2025
8049b80
Merge remote-tracking branch 'origin/dev/master' into dev/custom_weights
TonyKatkov89 Oct 13, 2025
268aa06
matches indexes arrays moved to Dataset
TonyKatkov89 Oct 14, 2025
d5845a7
temp
TonyKatkov89 Oct 14, 2025
158ed04
update
TonyKatkov89 Oct 14, 2025
62d9b42
matching works
TonyKatkov89 Oct 14, 2025
b09817d
Merge pull request #187 from sb-ai-lab/dev/custom_weights
TonyKatkov89 Oct 30, 2025
1ebddd8
cupac v2 (#191)
anathema-git Nov 18, 2025
3869988
fix imports
anathema-git Nov 25, 2025
ea16ffd
add min_sample_size
anastasiiafed24 Dec 8, 2025
6fa2b5a
min_sample_size in extentions
anastasiiafed24 Dec 8, 2025
4a7fa1b
corrections
anastasiiafed24 Dec 8, 2025
7df6c67
min sample size in hypex
anastasiiafed24 Dec 10, 2025
cb408dc
rewrite min sample size
anastasiiafed24 Dec 18, 2025
fa013a6
cupac_advanced
anathema-git Dec 23, 2025
9856924
change calc and execute
anastasiiafed24 Dec 23, 2025
a3e5d00
corrections
anastasiiafed24 Dec 24, 2025
6b088df
Dev/matching fix n neighbours (#195)
TonyKatkov89 Dec 24, 2025
ac83283
Merge pull request #193 from sb-ai-lab/dev/min_sample_size
anastasiiafed24 Dec 25, 2025
cfb4982
new version prepared
TonyKatkov89 Dec 25, 2025
5de8f55
python version updated
TonyKatkov89 Dec 25, 2025
c2c8b0b
matching tests removed
TonyKatkov89 Dec 25, 2025
cced937
test data added
TonyKatkov89 Dec 25, 2025
744c965
ruff and black done
TonyKatkov89 Dec 25, 2025
ba7ba01
linters fixes
TonyKatkov89 Dec 25, 2025
27968c4
tox fixed
TonyKatkov89 Dec 25, 2025
4fcb5a1
tox fixed
TonyKatkov89 Dec 25, 2025
ca95277
tox fixed
TonyKatkov89 Dec 25, 2025
394923e
ci.yml updated
TonyKatkov89 Dec 25, 2025
0209e4c
ci.yml updated
TonyKatkov89 Dec 25, 2025
fdb514b
tox fixed
TonyKatkov89 Dec 25, 2025
9b2f024
tox fixed
TonyKatkov89 Dec 25, 2025
83d5103
tox fixed
TonyKatkov89 Dec 25, 2025
652d63c
tox fixed
TonyKatkov89 Dec 25, 2025
662ed63
tox fixed
TonyKatkov89 Dec 25, 2025
3277aa2
tox fixed
TonyKatkov89 Dec 25, 2025
0d3cd89
tox fixed
TonyKatkov89 Dec 25, 2025
3ec00d1
tox fixed
TonyKatkov89 Dec 25, 2025
1257801
tox fixed
TonyKatkov89 Dec 25, 2025
53d2346
tox fixed
TonyKatkov89 Dec 25, 2025
97302f3
tox fixed
TonyKatkov89 Dec 25, 2025
8217f58
tox fixed
TonyKatkov89 Dec 25, 2025
722aeb2
tox fixed
TonyKatkov89 Dec 25, 2025
f237eaa
tox fixed
TonyKatkov89 Dec 25, 2025
b805d22
tox fixed
TonyKatkov89 Dec 25, 2025
f06eb77
tox fixed
TonyKatkov89 Dec 25, 2025
c31cc6a
tox fixed
TonyKatkov89 Dec 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 69 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
os: [ubuntu-latest, macos-latest, windows-latest]
# Exclude Python 3.13 on Windows due to segmentation fault issues
exclude:
- os: windows-latest
python-version: "3.13"
steps:
- uses: actions/checkout@v4

Expand All @@ -27,19 +31,77 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y pkg-config gfortran g++
# Install OpenBLAS for scipy builds (needed for Python 3.13)
if [[ "${{ matrix.python-version }}" == "3.13" ]]; then
sudo apt-get install -y libopenblas-dev liblapack-dev
fi

- name: Install system dependencies (macOS)
if: matrix.os == 'macos-latest'
run: |
brew update
brew install pkg-config
# Install gcc, gfortran, and OpenBLAS for Python versions that need compilation
if [[ "${{ matrix.python-version }}" == "3.13" ]]; then
brew install gcc gfortran openblas
# Add Homebrew's bin directory to PATH to ensure gcc and gfortran are found
echo "$(brew --prefix)/bin" >> $GITHUB_PATH
fi

- name: Install dependencies for tox
run: |
python -m pip install --upgrade pip
pip install tox
pip install tox tox-gh-actions
pip install poetry
pip install pytest
poetry install --no-root --without dev

- name: Install project dependencies with retry
# Use poetry install with retry logic for network issues
shell: bash
run: |
# Try with system dependencies first, fall back to source if needed
poetry config virtualenvs.create true
poetry config virtualenvs.in-project false

# For Python 3.13, try to install with --no-build-isolation first
if [[ "${{ matrix.python-version }}" == "3.13" ]]; then
# Use environment variables to help with compilation
if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
export LDFLAGS="-L$(brew --prefix zlib)/lib"
export CPPFLAGS="-I$(brew --prefix zlib)/include"
fi

# Try to install with system site packages enabled for system libraries
poetry install --no-root --without dev --no-interaction || \
echo "First attempt failed, retrying with different options..."

# Fallback: try using pip directly with pre-compiled wheels where possible
python -m pip install --upgrade setuptools wheel

# For problematic packages, try to get pre-compiled wheels
if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
python -m pip install --only-binary :all: numpy scipy matplotlib || \
python -m pip install numpy scipy matplotlib --no-build-isolation
fi
else
poetry install --no-root --without dev --no-interaction
fi

- name: Run unit tests
run: tox -e py
shell: bash
env:
# For Python 3.13 compilation
NPY_DISTUTILS_APPEND_FLAGS: 1
run: |
# Use tox-gh-actions to select the right tox environment
tox

linters:
runs-on: ubuntu-latest # Линтеры и доки только на одной версии
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

Expand All @@ -51,7 +113,7 @@ jobs:
- name: Install dependencies for linters
run: |
python -m pip install --upgrade pip
pip install tox
pip install tox tox-gh-actions
pip install poetry
poetry install --no-root

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Diff-in-Diff) and CUPED methods, to rigorously test hypotheses and validate expe
- **Data Tests**: Incorporates SMD, KS, PSI, and Repeats tests to affirm the robustness of effect estimations.
- **Feature Selection**: Employs LGBM and Catboost feature selection to pinpoint the most impactful features for causal
analysis.
- **AB Testing Suite**: Features a suite of AB testing tools for comprehensive hypothesis evaluation.
- **AB Testing Suite**: Features a suite of AB testing tools for comprehensive hypothesis evaluation, including CUPED and CUPAC variance reduction methods with detailed reports.
- **Stratification support**: Stratify groups for nuanced analysis
- **Weights support**: Empower your analysis by assigning custom weights to features, enhancing the matching precision
to suit your specific research needs
Expand Down Expand Up @@ -150,9 +150,12 @@ data = Dataset(
test = ABTest() # Classic A/B test
test = ABTest(multitest_method="bonferroni") # A/Bn test with Bonferroni corrections
test = ABTest(additional_tests=['t-test', 'u-test', 'chi2-test']) # Use can choose tests
test = ABTest(cuped_features={'post_spends': 'pre_spends'}) # CUPED variance reduction
test = ABTest(cupac_features={'post_spends': ['pre_spends', 'feature1']}) # CUPAC variance reduction

result = test.execute(data)
result.resume # Resume of results
result.variance_reduction_report # Variance reduction report for CUPED/CUPAC
```
More about A/B test [here](https://github.com/sb-ai-lab/HypEx/tree/master/examples/tutorials/ABTestTutorial.ipynb)

Expand Down
38 changes: 19 additions & 19 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@
highlight_language = "python"

html_theme_options = {
'logo_only': False,
'prev_next_buttons_location': 'bottom',
'style_external_links': True,
'vcs_pageview_mode': 'blob',
'style_nav_header_background': '#2980B9',
"logo_only": False,
"prev_next_buttons_location": "bottom",
"style_external_links": True,
"vcs_pageview_mode": "blob",
"style_nav_header_background": "#2980B9",
# Toc options
'collapse_navigation': True,
'sticky_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False,
'globaltoc_collapse': True,
'globaltoc_maxdepth': 3,
"collapse_navigation": True,
"sticky_navigation": True,
"navigation_depth": 4,
"includehidden": True,
"titles_only": False,
"globaltoc_collapse": True,
"globaltoc_maxdepth": 3,
}

# Add any paths that contain custom static files (such as style sheets) here,
Expand All @@ -97,16 +97,16 @@
html_static_path = ["_static"]

html_css_files = [
'custom.css',
"custom.css",
]

html_show_sourcelink = False
html_sidebars = {
'**': [
'globaltoc.html',
'relations.html',
'sourcelink.html',
'searchbox.html',
"**": [
"globaltoc.html",
"relations.html",
"sourcelink.html",
"searchbox.html",
]
}

Expand All @@ -130,7 +130,7 @@
"ignore-module-all": True,
"show-inheritance": True,
"exclude-members": EXCLUDED_MEMBERS,
'inherited-members': False,
"inherited-members": False,
}

# order of members in docs, usefully for methods in class
Expand Down
56 changes: 29 additions & 27 deletions examples/experiments/performance_test/performance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ def __init__(self, fixed_data_params: dict | None = None):

@staticmethod
def _generate_synthetic_data(
n_columns: int,
n_rows: int,
n2c_ratio: float,
rs: int | None,
num_range: tuple,
n_categories: int,
n_columns: int,
n_rows: int,
n2c_ratio: float,
rs: int | None,
num_range: tuple,
n_categories: int,
) -> pd.DataFrame:
if rs is not None:
np.random.seed(rs)
Expand All @@ -72,11 +72,11 @@ def _generate_synthetic_data(
return pd.DataFrame(
np.hstack((numerical_data, categorical_data)),
columns=[f"num_col_{i}" for i in range(n_numerical)]
+ [f"cat_col_{i}" for i in range(n_categorical)],
+ [f"cat_col_{i}" for i in range(n_categorical)],
)

def create_dataset(
self, params: dict
self, params: dict
) -> tuple[Dataset, dict[str, int | tuple[int, int] | float]]:
all_params = self.fixed_data_params.copy()
all_params.update(params)
Expand All @@ -92,9 +92,9 @@ class ExperimentProfiler:
default_experiment_params: ClassVar[dict] = {"n_iterations": 10}

def __init__(
self,
fixed_experiment_params: dict | None = None,
experiment: type = AATest,
self,
fixed_experiment_params: dict | None = None,
experiment: type = AATest,
):
fixed_experiment_params = fixed_experiment_params or {}
self.fixed_experiment_params = self.default_experiment_params.copy()
Expand All @@ -116,12 +116,12 @@ class PerformanceTester:
resume: ClassVar[defaultdict] = defaultdict(dict)

def __init__(
self,
dataProfiler: DataProfiler,
experimentProfiler: ExperimentProfiler,
iterable_params: list | None = None,
use_memory: bool = True,
rewrite: bool = True,
self,
dataProfiler: DataProfiler,
experimentProfiler: ExperimentProfiler,
iterable_params: list | None = None,
use_memory: bool = True,
rewrite: bool = True,
):
self.dataProfiler = dataProfiler
self.experimentProfiler = experimentProfiler
Expand Down Expand Up @@ -153,14 +153,16 @@ def execute(self, file_name, analysis="onefactor"):
"analysis",
*list(self.experimentProfiler.fixed_experiment_params.keys()),
*list(self.dataProfiler.fixed_data_params.keys()),
"time", "M1", "M2"
"time",
"M1",
"M2",
]
writer.writerow(row_items)
with alive_bar(
self.get_number_params(),
bar="squares",
spinner="dots_waves2",
title=f"Analysis : {analysis}",
self.get_number_params(),
bar="squares",
spinner="dots_waves2",
title=f"Analysis : {analysis}",
) as bar:
for params, data, experiment in tqdm(self.get_params()):
combined_params = {**data[1], **experiment[1]}
Expand All @@ -184,7 +186,7 @@ def execute(self, file_name, analysis="onefactor"):
process.join()
monitor.join()

max_memory_mb = return_dict2["max_memory"] / 1024 ** 2
max_memory_mb = return_dict2["max_memory"] / 1024**2

with open(file_name, "a", newline="") as file:
writer = csv.writer(file)
Expand Down Expand Up @@ -234,14 +236,14 @@ def function_performance(self, func, param_dict, return_dict):

return_dict["results"] = [
exec_time,
memory_usage / 10 ** 6 if self.use_memory else None,
memory_usage / 10**6 if self.use_memory else None,
]


def performance_test_plot(
params: dict,
output_path: str,
title="The results of the one-factor performance test of the AA Test",
params: dict,
output_path: str,
title="The results of the one-factor performance test of the AA Test",
):
df = pd.read_csv(output_path)
df = df[df.analysis == "onefactor"]
Expand Down
Loading
Loading