diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 562d902..cdfac9e 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -25,6 +25,7 @@ jobs: run: | python -m pip install --upgrade pip pip install build + pip install -r requirements.txt pip install -r requirements_dev.txt - name: Run tests diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index bdfcbcd..466fd1a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -24,6 +24,7 @@ jobs: run: | python -m pip install --upgrade pip pip install build + pip install -r requirements.txt pip install -r requirements_dev.txt - name: Run tests diff --git a/.gitignore b/.gitignore index 8f2a47b..3eae1d6 100644 --- a/.gitignore +++ b/.gitignore @@ -135,4 +135,4 @@ dmypy.json /test test.ipynb dummy.py -.DS_Store \ No newline at end of file +.DS_Store diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5d7cf48..dc06eee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,3 +12,8 @@ repos: rev: 5.13.2 hooks: - id: isort + + - repo: https://github.com/psf/black + rev: 24.8.0 + hooks: + - id: black diff --git a/LICENSE b/LICENSE index 7fc2b34..a0f1f87 100644 --- a/LICENSE +++ b/LICENSE @@ -25,4 +25,4 @@ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MANIFEST.in b/MANIFEST.in index 887ea7b..dca749c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ include README.md include LICENSE recursive-include wnb *.py -recursive-include tests *.py \ No newline at end of file +recursive-include tests *.py diff --git a/README.md b/README.md index 5068885..abf9713 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-wnb logo +wnb logo
General and weighted naive Bayes classifiers
@@ -7,10 +7,10 @@
-![Lastest Release](https://img.shields.io/badge/release-v0.2.6-green) +![Lastest Release](https://img.shields.io/badge/release-v0.2.7-green) [![PyPI Version](https://img.shields.io/pypi/v/wnb)](https://pypi.org/project/wnb/) ![Python Versions](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)
-![GitHub Workflow Status (build)](https://github.com/msamsami/weighted-naive-bayes/actions/workflows/python-publish.yml/badge.svg) +![GitHub Workflow Status (build)](https://github.com/msamsami/wnb/actions/workflows/python-publish.yml/badge.svg) ![PyPI License](https://img.shields.io/pypi/l/wnb) [![PyPi Downloads](https://static.pepy.tech/badge/wnb)](https://pepy.tech/project/wnb) @@ -26,14 +26,35 @@ The issue with the well-known implementations of the naive Bayes algorithm (such Although naive Bayes has many advantages such as simplicity and interpretability, its conditional independence assumption rarely holds true in real-world applications. In order to alleviate its conditional independence assumption, many attribute weighting naive Bayes (WNB) approaches have been proposed. Most of the proposed methods involve computationally demanding optimization problems that do not allow for controlling the model's bias due to class imbalance. Minimum Log-likelihood Difference WNB (MLD-WNB) is a novel weighting approach that optimizes the weights according to the Bayes optimal decision rule and includes hyperparameters for controlling the model's bias. **WNB** library provides an efficient implementation of gaussian MLD-WNB. ## Installation -The easiest way to install the **wnb** library is by using `pip`: -``` +This library is shipped as an all-in-one module implementation with minimalistic dependencies and requirements. Furthermore, it fully **adheres to Scikit-learn API** ❤️. + +### Prerequisites +Ensure that Python 3.8 or higher is installed on your machine before installing **WNB**. + +### PyPi +```bash pip install wnb ``` -This library is shipped as an all-in-one module implementation with minimalistic dependencies and requirements. Furthermore, it fully **adheres to Scikit-learn API** ❤️. + +### Poetry +```bash +poetry add wnb +``` + +### GitHub +```bash +# Clone the repository +git clone https://github.com/msamsami/wnb.git + +# Navigate into the project directory +cd wnb + +# Install the package +pip install . +``` ## Getting started ⚡️ -Here, we show how you can use the library to train general and weighted naive Bayes classifiers. +Here, we show how you can use the library to train general and weighted naive Bayes classifiers. ### General naive Bayes @@ -114,13 +135,14 @@ These benchmarks highlight the potential of WNB classifiers to provide better pe The benchmark scripts used to obtain these results can be found under _tests/benchmarks/_ directory. ## Tests -To run the tests, make sure to clone the repository and install the development requirements: -``` +To run the tests, make sure to clone the repository and install the development requirements in addition to base requirements: +```bash +pip install -r requirements.txt pip install -r requirements_dev.txt ``` Then, run pytest: -``` +```bash pytest ``` @@ -129,7 +151,7 @@ You can support the project in the following ways: ⭐ Star WNB on GitHub (click the star button in the top right corner) -💡 Provide your feedback or propose ideas in the [Issues section](https://github.com/msamsami/weighted-naive-bayes/issues) +💡 Provide your feedback or propose ideas in the [Issues section](https://github.com/msamsami/wnb/issues) 📰 Post about WNB on LinkedIn or other platforms @@ -144,6 +166,6 @@ If you utilize this repository, please consider citing it with: year = {2023}, publisher = {GitHub}, journal = {GitHub repository}, - howpublished = {\url{https://github.com/msamsami/weighted-naive-bayes}}, + howpublished = {\url{https://github.com/msamsami/wnb}}, } -``` \ No newline at end of file +``` diff --git a/pyproject.toml b/pyproject.toml index d2b6fd0..372d993 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,10 +41,14 @@ dependencies = [ "typing-extensions>=4.8.0", ] +[project.urls] +Homepage = "https://github.com/msamsami/wnb" +Source = "https://github.com/msamsami/wnb" + [project.optional-dependencies] dev = [ "pytest>=7.0.0", - "black>=24.4.2", + "black==24.8.0", "tqdm>=4.65.0", "pre-commit>=3.7.1", "isort==5.13.2", diff --git a/requirements.txt b/requirements.txt index 1931e01..37a7b29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ pandas>=1.4.1 numpy<2.0.0 scipy>=1.8.0 scikit-learn>=1.0.2 -typing-extensions>=4.8.0 \ No newline at end of file +typing-extensions>=4.8.0 diff --git a/requirements_dev.txt b/requirements_dev.txt index 0ac3e3e..974c318 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,10 +1,5 @@ -pandas>=1.4.1 -numpy<2.0.0 -scipy>=1.8.0 -scikit-learn>=1.0.2 -typing-extensions>=4.8.0 pytest>=7.0.0 -black>=24.4.2 +black==24.8.0 tqdm>=4.65.0 pre-commit>=3.7.1 -isort==5.13.2 \ No newline at end of file +isort==5.13.2 diff --git a/setup.cfg b/setup.cfg index df0bb57..5c5d5d5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,14 +3,14 @@ name = wnb version = attr: wnb.__version__ author = Mehdi Samsami author_email = mehdisamsami@live.com -url = https://github.com/msamsami/weighted-naive-bayes +url = https://github.com/msamsami/wnb description = Python library for the implementations of general and weighted naive Bayes (WNB) classifiers. long_description = file: README.md long_description_content_type = text/markdown license = BSD license_file = LICENSE keywords = python, bayes, naive bayes, classifier, probabilistic -classifiers = +classifiers = Intended Audience :: Science/Research Intended Audience :: Developers Topic :: Scientific/Engineering @@ -38,7 +38,7 @@ install_requires = [options.extras_require] dev = pytest>=7.0.0 - black>=24.4.2 + black==24.8.0 tqdm>=4.65.0 pre-commit>=3.7.1 isort==5.13.2 @@ -47,5 +47,5 @@ dev = test = pytest [tool:pytest] -filterwarnings = +filterwarnings = ignore diff --git a/setup.py b/setup.py index 4ac2932..1f3cd0c 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ author="Mehdi Samsami", author_email="mehdisamsami@live.com", license="BSD License", - url="https://github.com/msamsami/weighted-naive-bayes", + url="https://github.com/msamsami/wnb", long_description=codecs.open( path.join(path.abspath(path.dirname(__file__)), "README.md"), encoding="utf-8" ).read(), @@ -45,7 +45,7 @@ extras_require={ "dev": [ "pytest>=7.0.0", - "black>=24.4.2", + "black==24.8.0", "tqdm>=4.65.0", "pre-commit>=3.7.1", "isort==5.13.2", diff --git a/wnb/__init__.py b/wnb/__init__.py index 4de21e9..15ba537 100644 --- a/wnb/__init__.py +++ b/wnb/__init__.py @@ -2,11 +2,11 @@ Python library for the implementations of general and weighted naive Bayes (WNB) classifiers. """ -__version__ = "0.2.6" +__version__ = "0.2.7" __author__ = "Mehdi Samsami" -from ._base import ContinuousDistMixin, DiscreteDistMixin +from .base import ContinuousDistMixin, DiscreteDistMixin from .enums import Distribution from .gnb import GeneralNB from .gwnb import GaussianWNB diff --git a/wnb/_typing.py b/wnb/_typing.py index 91c6a21..932f7d4 100644 --- a/wnb/_typing.py +++ b/wnb/_typing.py @@ -5,7 +5,7 @@ import pandas as pd from scipy.sparse import spmatrix -from ._base import ContinuousDistMixin, DiscreteDistMixin +from .base import ContinuousDistMixin, DiscreteDistMixin from .enums import Distribution __all__ = ["MatrixLike", "ArrayLike", "Int", "Float", "DistibutionLike"] diff --git a/wnb/_base.py b/wnb/base.py similarity index 100% rename from wnb/_base.py rename to wnb/base.py diff --git a/wnb/dist.py b/wnb/dist.py index efde13c..b5e4c81 100644 --- a/wnb/dist.py +++ b/wnb/dist.py @@ -4,7 +4,7 @@ from scipy.special import beta, gamma from scipy.stats import chi2 -from ._base import ContinuousDistMixin, DiscreteDistMixin +from .base import ContinuousDistMixin, DiscreteDistMixin from .enums import Distribution as D __all__ = [ diff --git a/wnb/gnb.py b/wnb/gnb.py index f5013ef..d61452e 100644 --- a/wnb/gnb.py +++ b/wnb/gnb.py @@ -14,15 +14,13 @@ from sklearn.utils.validation import check_is_fitted from typing_extensions import Self -from ._base import DistMixin from ._typing import ArrayLike, DistibutionLike, Float, MatrixLike +from .base import DistMixin from .dist import NonNumericDistributions from .enums import Distribution from .utils import get_dist_class, is_dist_supported -__all__ = [ - "GeneralNB", -] +__all__ = ["GeneralNB"] class GeneralNB(ClassifierMixin, BaseEstimator, metaclass=ABCMeta): diff --git a/wnb/gwnb.py b/wnb/gwnb.py index 7c95208..b333640 100644 --- a/wnb/gwnb.py +++ b/wnb/gwnb.py @@ -18,9 +18,7 @@ from ._typing import ArrayLike, Float, Int, MatrixLike -__all__ = [ - "GaussianWNB", -] +__all__ = ["GaussianWNB"] class GaussianWNB(ClassifierMixin, BaseEstimator, metaclass=ABCMeta): diff --git a/wnb/utils.py b/wnb/utils.py index 486e917..8d50009 100644 --- a/wnb/utils.py +++ b/wnb/utils.py @@ -1,8 +1,8 @@ import contextlib from typing import Optional -from ._base import DistMixin from ._typing import DistibutionLike +from .base import DistMixin from .dist import AllDistributions from .enums import Distribution @@ -11,8 +11,7 @@ def is_dist_supported(dist: DistibutionLike) -> bool: with contextlib.suppress(TypeError): - issubclass(dist, DistMixin) - return True + return issubclass(dist, DistMixin) if ( isinstance(dist, Distribution) @@ -26,8 +25,8 @@ def is_dist_supported(dist: DistibutionLike) -> bool: def get_dist_class(name_or_type: DistibutionLike) -> Optional[DistMixin]: with contextlib.suppress(TypeError): - issubclass(name_or_type, DistMixin) - return name_or_type + if issubclass(name_or_type, DistMixin): + return name_or_type if isinstance(name_or_type, Distribution) or name_or_type in Distribution.__members__.values(): return AllDistributions[name_or_type]