{"id":15039468,"url":"https://github.com/scikit-learn-contrib/boruta_py","last_synced_at":"2026-10-19T12:02:08.684Z","repository":{"id":37430766,"uuid":"50732993","full_name":"scikit-learn-contrib/boruta_py","owner":"scikit-learn-contrib","description":"Python implementations of the Boruta all-relevant feature selection method.","archived":false,"fork":false,"pushed_at":"2025-11-13T04:00:49.000Z","size":192,"stargazers_count":1632,"open_issues_count":48,"forks_count":264,"subscribers_count":34,"default_branch":"master","last_synced_at":"2026-10-17T20:08:52.974Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scikit-learn-contrib.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-01-30T16:25:26.000Z","updated_at":"2026-10-14T06:03:41.000Z","dependencies_parsed_at":"2022-07-14T09:22:17.859Z","dependency_job_id":"65449aef-15cd-4947-bd00-a1d3f71644a1","html_url":"https://github.com/scikit-learn-contrib/boruta_py","commit_stats":{"total_commits":75,"total_committers":24,"mean_commits":3.125,"dds":0.7733333333333333,"last_synced_commit":"92e4b4e1c3ee115a8e1997a8b4a25f8e5090236c"},"previous_names":["danielhomola/boruta_py"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/scikit-learn-contrib/boruta_py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-learn-contrib%2Fboruta_py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-learn-contrib%2Fboruta_py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-learn-contrib%2Fboruta_py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-learn-contrib%2Fboruta_py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scikit-learn-contrib","download_url":"https://codeload.github.com/scikit-learn-contrib/boruta_py/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-learn-contrib%2Fboruta_py/sbom","scorecard":{"id":319848,"data":{"date":"2025-08-11","repo":{"name":"github.com/scikit-learn-contrib/boruta_py","commit":"3c9eac3bdcc9d7cce0c01cd866b33f5c2eae98d4"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.9,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/scikit-learn-contrib/boruta_py/publish-to-pypi.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/scikit-learn-contrib/boruta_py/publish-to-pypi.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/scikit-learn-contrib/boruta_py/publish-to-pypi.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/publish-to-pypi.yml:28","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":8,"reason":"Found 21/25 approved changesets -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/publish-to-pypi.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish-to-pypi.yml:15"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.3 not signed: https://api.github.com/repos/scikit-learn-contrib/boruta_py/releases/18054537","Warn: release artifact 0.3 does not have provenance: https://api.github.com/repos/scikit-learn-contrib/boruta_py/releases/18054537"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T01:06:47.666Z","repository_id":37430766,"created_at":"2025-08-18T01:06:47.666Z","updated_at":"2025-08-18T01:06:47.666Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38335562,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-17T02:00:06.547Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T20:42:57.314Z","updated_at":"2026-10-19T12:02:08.317Z","avatar_url":"https://github.com/scikit-learn-contrib.png","language":"Python","funding_links":[],"categories":["Feature Engineering","Libraries (Python)"],"sub_categories":["Feature Selection"],"readme":"# boruta_py #\n\n[![License](https://img.shields.io/github/license/scikit-learn-contrib/boruta_py)](https://github.com/scikit-learn-contrib/boruta_py/blob/master/LICENSE)\n[![PyPI version](https://badge.fury.io/py/Boruta.svg)](https://badge.fury.io/py/Boruta)\n[![Anaconda-Server Badge](https://anaconda.org/conda-forge/boruta_py/badges/version.svg)](https://anaconda.org/conda-forge/boruta_py)\n\nThis project hosts Python implementations of the [Boruta all-relevant feature selection method](https://www.jstatsoft.org/article/view/v036i11).\n\n[Related blog post](https://danielhomola.com/feature%20selection/phd/borutapy-an-all-relevant-feature-selection-method/)\n\n\n## How to install ##\n\nInstall with `pip`:\n\n```shell\npip install Boruta\n```\n\nor with `conda`:\n\n```shell\nconda install -c conda-forge boruta_py\n```\n\n## Dependencies ##\n\n* numpy\n* scipy\n* scikit-learn\n\n## How to use ##\n\nDownload, import and do as you would with any other scikit-learn method:\n* fit(X, y)\n* transform(X)\n* fit_transform(X, y)\n\n## Description ##\n\nPython implementations of the Boruta R package.\n\nThis implementation tries to mimic the scikit-learn interface, so use fit,\ntransform or fit_transform, to run the feature selection.\n\nFor more, see the docs of these functions, and the examples below.\n\n[Original code](https://gitlab.com/mbq/Boruta) and method was authored by Miron B. Kursa.\n\nBoruta is an all relevant feature selection method, while most other are\nminimal optimal; this means it tries to find all features carrying\ninformation usable for prediction, rather than finding a possibly compact\nsubset of features on which some classifier has a minimal error.\n\nWhy bother with all relevant feature selection?\nWhen you try to understand the phenomenon that made your data, you should\ncare about all factors that contribute to it, not just the bluntest signs\nof it in context of your methodology (yes, minimal optimal set of features\nby definition depends on your classifier choice).\n\n\n## What's different in BorutaPy? ##\n\nIt is the original R package recoded in Python with a few added extra features.\nSome improvements include:  \n\n* Faster run times, thanks to scikit-learn\n\n* Scikit-learn like interface\n\n* Compatible with any ensemble method from scikit-learn\n\n* Automatic n_estimator selection\n\n* Ranking of features\n\n* Feature importances are derived from Gini impurity instead of RandomForest R package's MDA. \n\nFor more details, please check the top of the docstring.\n\nWe highly recommend using pruned trees with a depth between 3-7.\n\nAlso, after playing around a lot with the original code I identified a few areas\nwhere the core algorithm could be improved/altered to make it less strict and\nmore applicable to biological data, where the Bonferroni correction might be\noverly harsh.\n\n__Percentile as threshold__  \nThe original method uses the maximum of the shadow features as a threshold in\ndeciding which real feature is doing better than the shadow ones. This could be\noverly harsh.\n\nTo control this, I added the perc parameter, which sets the\npercentile of the shadow features' importances, the algorithm uses as the\nthreshold. The default of 100 which is equivalent to taking the maximum as the\nR version of Boruta does, but it could be relaxed. Note, since this is the\npercentile, it changes with the size of the dataset. With several thousands of\nfeatures it isn't as stringent as with a few dozens at the end of a Boruta run.\n\n\n__Two step correction for multiple testing__  \nThe correction for multiple testing was relaxed by making it a two step\nprocess, rather than a harsh one step Bonferroni correction.\n\nWe need to correct firstly because in each iteration we test a number of\nfeatures against the null hypothesis (does a feature perform better than\nexpected by random). For this the Bonferroni correction is used in the original\ncode which is known to be too stringent in such scenarios (at least for\nbiological data), and also the original code corrects for n features, even if\nwe are in the 50th iteration where we only have k\u003c\u003cn features left. For this\nreason the first step of correction is the widely used Benjamini Hochberg FDR.\n\nFollowing that however we also need to account for the fact that we have been\ntesting the same features over and over again in each iteration with the\nsame test. For this scenario the Bonferroni is perfect, so it is applied by\ndividing the p-value threshold with the current iteration index.\n\nIf this two step correction is not required, the two_step parameter has to be\nset to False, then (with perc=100) BorutaPy behaves exactly as the R version.\n\n## Parameters ##\n\n__estimator__ : object\n   \u003e A supervised learning estimator, with a 'fit' method that returns the\n   \u003e feature_importances_ attribute. Important features must correspond to\n   \u003e high absolute values in the feature_importances_.\n\n__n_estimators__ : int or string, default = 1000\n   \u003e If int sets the number of estimators in the chosen ensemble method.\n   \u003e If 'auto' this is determined automatically based on the size of the\n   \u003e dataset. The other parameters of the used estimators need to be set\n   \u003e with initialisation.\n\n__perc__ : int, default = 100\n   \u003e Instead of the max we use the percentile defined by the user, to pick\n   \u003e our threshold for comparison between shadow and real features. The max\n   \u003e tends to be too stringent. This provides a finer control over this. The\n   \u003e lower perc is the more false positives will be picked as relevant but\n   \u003e also the less relevant features will be left out. The usual trade-off.\n   \u003e The default is essentially the vanilla Boruta corresponding to the max.\n\n__alpha__ : float, default = 0.05\n   \u003e Level at which the corrected p-values will get rejected in both correction\n   steps.\n\n__two_step__ : Boolean, default = True\n  \u003e If you want to use the original implementation of Boruta with Bonferroni\n  \u003e correction only set this to False.\n\n__max_iter__ : int, default = 100\n   \u003e The number of maximum iterations to perform.\n\n__verbose__ : int, default=0\n   \u003e Controls verbosity of output.\n\n\n## Attributes ##\n\n**n_features_** : int\n   \u003e The number of selected features.\n\n**support_** : array of shape [n_features]\n   \u003e The mask of selected features - only confirmed ones are True.\n\n**support_weak_** : array of shape [n_features]\n  \u003e  The mask of selected tentative features, which haven't gained enough\n  \u003e  support during the max_iter number of iterations..\n\n**ranking_** : array of shape [n_features]\n  \u003e  The feature ranking, such that ``ranking_[i]`` corresponds to the\n  \u003e  ranking position of the i-th feature. Selected (i.e., estimated\n  \u003e  best) features are assigned rank 1 and tentative features are assigned\n  \u003e  rank 2.\n\n\n## Examples ##\n\n[![Open example notebook](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/https://raw.githubusercontent.com/scikit-learn-contrib/boruta_py/master/boruta/examples/Madalon_Data_Set.ipynb)\n[![Open example notebook](https://b.mineo.app/static/img/open_in_mineo.svg)](https://b.mineo.app/import/https://raw.githubusercontent.com/scikit-learn-contrib/boruta_py/master/boruta/examples/Madalon_Data_Set.ipynb)\n\n```python\nimport pandas as pd\nfrom sklearn.ensemble import RandomForestClassifier\nfrom boruta import BorutaPy\n\n# load X and y\n# NOTE BorutaPy accepts numpy arrays only, hence the .values attribute\nX = pd.read_csv('examples/test_X.csv', index_col=0).values\ny = pd.read_csv('examples/test_y.csv', header=None, index_col=0).values\ny = y.ravel()\n\n# define random forest classifier, with utilising all cores and\n# sampling in proportion to y labels\nrf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)\n\n# define Boruta feature selection method\nfeat_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=1)\n\n# find all relevant features - 5 features should be selected\nfeat_selector.fit(X, y)\n\n# check selected features - first 5 features are selected\nfeat_selector.support_\n\n# check ranking of features\nfeat_selector.ranking_\n\n# call transform() on X to filter it down to selected features\nX_filtered = feat_selector.transform(X)\n```\n\n## References ##\n\n1. Kursa M., Rudnicki W., \"Feature Selection with the Boruta Package\" Journal of Statistical Software, Vol. 36, Issue 11, Sep 2010\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscikit-learn-contrib%2Fboruta_py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscikit-learn-contrib%2Fboruta_py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscikit-learn-contrib%2Fboruta_py/lists"}