Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
72 changes: 37 additions & 35 deletions .github/workflows/ci_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,28 @@ name: CI checks
on:
pull_request:
branches: ["*"]
push:
branches: [ master ]

jobs:
code-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Checkout
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Set up Python
run: uv python install

- name: Install
run: |
pip install .[dev]
uv sync --dev

- name: Unit-tests with coverage
run: |
pytest --cov=./ --cov-report=xml
uv run pytest --cov=./ --cov-report=xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
Expand All @@ -28,29 +33,22 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dev dependencies
run: |
pip install .[dev]
- uses: pre-commit/action@v3.0.1
- name: Checkout
uses: actions/checkout@v4

run_lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dev dependencies
run: |
pip install .[dev]
- name: Run linting
shell: bash
run: |
bash scripts/ci_checks.sh
- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Set up Python
run: uv python install

- name: Install
run: |
uv sync --dev

- name: Run pre-commit hooks
run: |
uv run pre-commit run --all-files

unit-tests:
runs-on: ${{ matrix.os }}
Expand All @@ -59,14 +57,18 @@ jobs:
python-version: ['3.9', '3.10', '3.11', '3.12']
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
- name: Checkout
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install
run: |
pip install .[dev]
uv sync --dev

- name: Unit-tests with coverage
run: |
pytest tests/
uv run pytest tests/
19 changes: 11 additions & 8 deletions .github/workflows/upload_pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ jobs:
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install
run: |
pip install .[dev]
- name: Checkout
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Set up Python
run: uv python install

- name: Create package
run: |
python3 -m build
uv build

- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
12 changes: 1 addition & 11 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,7 @@ repos:
hooks:
- id: ruff
args: [ --fix ]

- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black

- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- id: ruff-format

- repo: local
hooks:
Expand All @@ -31,4 +22,3 @@ repos:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: requirements-txt-fixer
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12.11
12 changes: 6 additions & 6 deletions denstream/den_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ def _cluster_evaluate(self, iteration: int) -> None:
if len(self.label_metrics_list) > 0:
metrics += self._compute_label_metrics(predicted_labels)
if len(self.no_label_metrics_list) > 0:
# Checking that we have atleast two clusters (exluding outlier clusters, i.e. label=-1).
# Checking that we have at-least two clusters (excluding outlier clusters, i.e. label=-1).
if len(set(predicted_labels[predicted_labels != -1])) > 1:
metrics += self._compute_no_label_metric(predicted_labels)
else:
Expand All @@ -318,7 +318,7 @@ def _cluster_evaluate(self, iteration: int) -> None:
else:
self.metrics_results.append({"iteration": iteration, "metrics": None})

def _request_clustering(self) -> FloatArrayType:
def _request_clustering(self) -> IntArrayType:
"""
Clustering based on self.model for the p-micro-clusters.

Expand All @@ -328,14 +328,14 @@ def _request_clustering(self) -> FloatArrayType:
if len(self.p_micro_clusters) > 0:
center_array = np.concatenate([c.center for c in self.p_micro_clusters], axis=0)
else:
return np.empty(0, dtype=np.float32)
return np.empty(0, dtype=np.int32)

# TODO: Should the new clusters be connected? I.e. if micro-cluster 1 and 2 and connected, should they be merged
local_model = sklearn.base.clone(self.model)
predicted_labels: FloatArrayType = local_model.fit_predict(center_array)
predicted_labels: IntArrayType = local_model.fit_predict(center_array)
return predicted_labels

def _compute_label_metrics(self, predicted_labels: FloatArrayType) -> List[MetricsDict]:
def _compute_label_metrics(self, predicted_labels: IntArrayType) -> List[MetricsDict]:
"""
Compute the label metrics given the predicted labels.

Expand All @@ -362,7 +362,7 @@ def _compute_label_metrics(self, predicted_labels: FloatArrayType) -> List[Metri
results.append(result_dict)
return results

def _compute_no_label_metric(self, predicted_labels: FloatArrayType) -> List[MetricsDict]:
def _compute_no_label_metric(self, predicted_labels: IntArrayType) -> List[MetricsDict]:
"""
Compute the no-label metrics given the predicted labels.

Expand Down
12 changes: 6 additions & 6 deletions denstream/preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ def __init__(self, dim: Tuple[int, ...], eps: float = 1e-10):
"""

self.dim = dim
self.mean = np.zeros(self.dim)
self.mean = np.zeros(self.dim, dtype=np.float32)

self.variance = np.zeros(self.dim)
self.sse = np.zeros(self.dim)
self.variance = np.zeros(self.dim, dtype=np.float32)
self.sse = np.zeros(self.dim, dtype=np.float32)

self.num_data_points = 0
self.eps = eps
self.num_data_points = np.float32(0.0)
self.eps = np.float32(eps)

def update_statistics(self, x: FloatArrayType) -> None:
"""
Expand All @@ -37,7 +37,7 @@ def update_statistics(self, x: FloatArrayType) -> None:
:return:
"""

self.num_data_points += 1
self.num_data_points += np.float32(1.0)

old_mean = self.mean
self.mean = self.mean + (x - self.mean) / self.num_data_points
Expand Down
2 changes: 1 addition & 1 deletion denstream/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def fading_function(lambd: float, time: IntArrayType) -> FloatArrayType:
:return: The calculated fading array.
"""

return np.power(2, -lambd * time, dtype=np.float32)
return np.power(2, -lambd * time, dtype=np.float32) # type: ignore


def numpy_cf1(x: FloatArrayType, fading_array: FloatArrayType) -> FloatArrayType:
Expand Down
11 changes: 5 additions & 6 deletions examples/user_guide.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@
"T = np.concatenate([t_1, t_2, t_3, t_4], axis=0).astype(int)\n",
"\n",
"# Sorting data s.t. they come in time order.\n",
"idx = np.argsort(T, axis=0).reshape(T.shape[0],)\n",
"idx = np.argsort(T, axis=0).reshape(\n",
" T.shape[0],\n",
")\n",
"X = X[idx, :]\n",
"Y = Y[idx, :]\n",
"T = T[idx, :]"
Expand Down Expand Up @@ -161,11 +163,8 @@
"source": [
"def generator(X, Y, T):\n",
" for i in range(0, X.shape[0]):\n",
" yield {\n",
" \"time\": int(T[i, :]),\n",
" \"feature_array\": X[i, :].reshape((1, X.shape[1])),\n",
" \"label\": int(Y[i, :])\n",
" }\n",
" yield {\"time\": int(T[i, :]), \"feature_array\": X[i, :].reshape((1, X.shape[1])), \"label\": int(Y[i, :])}\n",
"\n",
"\n",
"gen = generator(X, Y, T)\n",
"\n",
Expand Down
37 changes: 14 additions & 23 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools>=61.0", "wheel>=0.37.1"]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "denstream"
version = "0.1.1"
version = "0.1.4"
description = "Implementation of the DenStream algorithm"
readme = "README.md"
requires-python = ">=3.9, <3.13"
requires-python = ">=3.9, <3.14"
authors = [
{name = "MrParosk"}
]

dependencies = [
"numba>=0.56.2",
"numpy>=1.23,<3.0",
"numba>=0.56",
"numpy>=2.0",
"scikit-learn>=1.0",
"typing-extensions>=4.14.0",
]

[project.optional-dependencies]

[dependency-groups]
dev = [
"black==24.10.0",
"isort==5.13.2",
"mypy==1.13.0",
"pre-commit==4.0.1",
"pytest==8.3.3",
"pytest-cov==6.0.0",
"ruff==0.7.3",
"build==1.2.2",
"twine==5.1.1",
"mypy>=1.16.0",
"pre-commit>=4.2.0",
"pytest>=8.4.0",
"pytest-cov>=6.2.0",
"ruff>=0.12.0",
]

[tool.mypy]
Expand All @@ -39,12 +37,5 @@ exclude = [
"tests"
]

[tool.black]
line-length = 128

[tool.isort]
line_length = 128
profile = "black"

[tool.ruff]
line-length = 128
15 changes: 0 additions & 15 deletions scripts/ci_checks.sh

This file was deleted.

Loading