Skip to main content

balance is a Python package offering a simple workflow and methods for dealing with biased data samples when looking to infer from them to some target population of interest.

Project description

balance_logo_horizontal

balance: a python package for balancing biased data samples

Current Release Python 3.9+ Build & Test Coverage CodeQL Deploy Website Release DOI Downloads

[!NOTE] balance is currently in beta and is actively supported. Follow us on github.

What is balance?

balance is a Python package offering a simple workflow and methods for dealing with biased data samples when looking to infer from them to some population of interest.

Biased samples often occur in survey statistics when respondents present non-response bias or survey suffers from sampling bias (that are not missing completely at random). A similar issue arises in observational studies when comparing the treated vs untreated groups, and in any data that suffers from selection bias.

Under the missing at random assumption (MAR), bias in samples could sometimes be (at least partially) mitigated by relying on auxiliary information (a.k.a.: "covariates" or "features") that is present for all items in the sample, as well as present in a sample of items from the population. For example, if we want to infer from a sample of respondents to some survey, we may wish to adjust for non-response using demographic information such as age, gender, education, etc. This can be done by weighing the sample to the population using auxiliary information.

The package is intended for researchers who are interested in balancing biased samples, such as the ones coming from surveys, using a Python package. This need may arise by survey methodologists, demographers, UX researchers, market researchers, and generally data scientists, statisticians, and machine learners.

More about the methodological background can be found in Sarig, T., Galili, T., & Eilat, R. (2023). balance – a Python package for balancing biased data samples.

Installation

Requirements

You need Python 3.9, 3.10, 3.11, 3.12, 3.13, or 3.14 to run balance. balance can be built and run from Linux, OSX, and Windows.

The required Python dependencies are:

REQUIRES = [
    # Numpy and pandas: carefully versioned for binary compatibility
    "numpy>=1.21.0,<2.0; python_version<'3.12'",
    "numpy>=1.24.0; python_version>='3.12'",
    "pandas>=1.5.0,<2.4.0; python_version<'3.12'",
    "pandas>=2.0.0; python_version>='3.12'",
    # Scientific stack
    "scipy>=1.7.0,<1.14.0; python_version<'3.12'",
    "scipy>=1.11.0; python_version>='3.12'",
    "scikit-learn>=1.0.0,<1.4.0; python_version<'3.12'",
    "scikit-learn>=1.3.0; python_version>='3.12'",
    "ipython",
    "patsy",
    "seaborn",
    "plotly",
    "matplotlib",
    "statsmodels",
    "session-info",
]

See setup.py or pyproject.toml for more details.

Installing balance

Installing via PyPi

We recommend installing balance from PyPi via pip for the latest stable version:

python -m pip install balance

Installation will use Python wheels from PyPI, available for OSX, Linux, and Windows.

Installing from Source/Git

You can install the latest (bleeding edge) version from Git:

python -m pip install git+https://github.com/facebookresearch/balance.git

Alternatively, if you have a local clone of the repo:

cd balance
python -m pip install .

Or using dev-dependencies:

cd balance
python -m pip install .[dev]

Getting started

balance's workflow in high-level

The core workflow in balance deals with fitting and evaluating weights to a sample. For each unit in the sample (such as a respondent to a survey), balance fits a weight that can be (loosely) interpreted as the number of people from the target population that this respondent represents. This aims to help mitigate the coverage and non-response biases, as illustrated in the following figure.

total_survey_error_img

The weighting of survey data through balance is done in the following main steps:

  1. Loading data of the respondents of the survey.
  2. Loading data about the target population we would like to correct for.
  3. Diagnostics of the sample covariates so to evaluate whether weighting is needed.
  4. Adjusting the sample to the target.
  5. Evaluation of the results.
  6. Use the weights for producing population level estimations.
  7. Saving the output weights.

You can see a step-by-step description (with code) of the above steps in the General Framework page.

Code example of using balance

You may run the following code to play with balance's basic workflow (these are snippets taken from the quickstart tutorial):

We start by loading data, and adjusting it:

from balance import load_data, Sample

# load simulated example data
target_df, sample_df = load_data()

# Import sample and target data into a Sample object
sample = Sample.from_frame(sample_df, outcome_columns=["happiness"])
target = Sample.from_frame(target_df)

# Set the target to be the target of sample
sample_with_target = sample.set_target(target)

# Check basic diagnostics of sample vs target before adjusting:
# sample_with_target.covars().plot()

You can read more on evaluation of the pre-adjusted data in the Pre-Adjustment Diagnostics page.

Next, we adjust the sample to the population by fitting balancing survey weights:

# Using ipw to fit survey weights
adjusted = sample_with_target.adjust()

You can read more on adjustment process in the Adjusting Sample to Population page.

The above code gets us an adjusted object with weights. We can evaluate the benefit of the weights to the covariate balance, for example by running:

print(adjusted.summary())
    # Covar ASMD reduction: 62.3%, design effect: 2.249
    # Covar ASMD (7 variables):0.335 -> 0.126
    # Model performance: Model proportion deviance explained: 0.174

adjusted.covars().plot(library = "seaborn", dist_type = "kde")

And get:

We can also check the impact of the weights on the outcome using:

# For the outcome:
print(adjusted.outcomes().summary())
    # 1 outcomes: ['happiness']
    # Mean outcomes:
    #             happiness
    # source
    # self        54.221388
    # unadjusted  48.392784
    #
    # Response rates (relative to number of respondents in sample):
    #    happiness
    # n     1000.0
    # %      100.0
adjusted.outcomes().plot()

You can read more on evaluation of the post-adjusted data in the Evaluating and using the adjustment weights page.

Finally, the adjusted data can be downloaded using:

adjusted.to_download()  # Or:
# adjusted.to_csv()

To see a more detailed step-by-step code example with code output prints and plots (both static and interactive), please go over to the tutorials section.

Implemented methods for adjustments

balance currently implements various adjustment methods. Click the links to learn more about each:

  1. Logistic regression using L1 (LASSO) penalization.
  2. Covariate Balancing Propensity Score (CBPS).
  3. Post-stratification.
  4. Raking.

Implemented methods for diagnostics/evaluation

For diagnostics the main tools (comparing before, after applying weights, and the target population) are:

  1. Plots
    1. barplots
    2. density plots (for weights and covariances)
    3. qq-plots
  2. Statistical summaries
    1. Weights distributions
      1. Kish's design effect
      2. Main summaries (mean, median, variances, quantiles)
    2. Covariate distributions
      1. Absolute Standardized Mean Difference (ASMD). For continuous variables, it is Cohen's d. Categorical variables are one-hot encoded, Cohen's d is calculated for each category and ASMD for a categorical variable is defined as Cohen's d, average across all categories.

You can read more on evaluation of the post-adjusted data in the Evaluating and using the adjustment weights page.

Other resources

More details

Getting help, submitting bug reports and contributing code

You are welcome to:

Citing balance

Sarig, T., Galili, T., & Eilat, R. (2023). balance – a Python package for balancing biased data samples. https://arxiv.org/abs/2307.06024

@misc{sarig2023balance,
      title={balance - a Python package for balancing biased data samples},
      author={Tal Sarig and Tal Galili and Roee Eilat},
      year={2023},
      eprint={2307.06024},
      archivePrefix={arXiv},
      primaryClass={stat.CO}
}

License

The balance package is licensed under the MIT license, and all the documentation on the site (including text and images) is under CC-BY.

News

You can follow updates on our:

Acknowledgements / People

The balance package is actively maintained by people from the Central Applied Science team (in Menlo Park and Tel Aviv), by Wesley Lee, Tal Sarig, and Tal Galili.

The balance package was (and is) developed by many people, including: Roee Eilat, Tal Galili, Daniel Haimovich, Kevin Liou, Steve Mandala, Adam Obeng (author of the initial internal Meta version), Tal Sarig, Luke Sonnet, Sean Taylor, Barak Yair Reif, Soumyadip Sarkar, and others. If you worked on balance in the past, please email us to be added to this list.

The balance package was open-sourced by Tal Sarig, Tal Galili and Steve Mandala in late 2022.

Branding created by Dana Beaty, from the Meta AI Design and Marketing Team. For logo files, see here.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

balance-0.15.0.tar.gz (9.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

balance-0.15.0-py3-none-any.whl (195.5 kB view details)

Uploaded Python 3

File details

Details for the file balance-0.15.0.tar.gz.

File metadata

  • Download URL: balance-0.15.0.tar.gz
  • Upload date:
  • Size: 9.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for balance-0.15.0.tar.gz
Algorithm Hash digest
SHA256 38a594aa041009929eb00611ed0222624d76e5d54ddf1f2d6d1b087070eb9b02
MD5 ed82366de4bd7c0f3779defc2d60dc00
BLAKE2b-256 54b1c6c4fba95cb5ee1693a40d91dc1240ca59f13c584830ef41194ebdfe69b8

See more details on using hashes here.

File details

Details for the file balance-0.15.0-py3-none-any.whl.

File metadata

  • Download URL: balance-0.15.0-py3-none-any.whl
  • Upload date:
  • Size: 195.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for balance-0.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 58126d706dca75627a8c148bfaa81d92375be6315c66b3b8cc8d4f36d7f57300
MD5 87ba462476d583a08edea5dd9a4a216a
BLAKE2b-256 e8768b6491f69448ce856a207b818c1256f024c7ddebe5e9bb79a4e641d1a9c6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page