featm 0.5.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- featm-0.5.7/.gitattributes +9 -0
- featm-0.5.7/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- featm-0.5.7/.github/scripts/check_release.py +26 -0
- featm-0.5.7/.github/scripts/test_wheel.py +18 -0
- featm-0.5.7/.github/workflows/ci.yml +28 -0
- featm-0.5.7/.github/workflows/publish-pypi.yml +69 -0
- featm-0.5.7/.gitignore +19 -0
- featm-0.5.7/CHANGELOG.md +26 -0
- featm-0.5.7/CONTRIBUTING.md +35 -0
- featm-0.5.7/LICENSE +21 -0
- featm-0.5.7/MANIFEST.in +13 -0
- featm-0.5.7/PKG-INFO +299 -0
- featm-0.5.7/README.md +194 -0
- featm-0.5.7/THIRD_PARTY_NOTICES.md +16 -0
- featm-0.5.7/benchmarks/batch_equivalence_smoke.py +473 -0
- featm-0.5.7/benchmarks/distributed_dask_equivalence_smoke.py +183 -0
- featm-0.5.7/benchmarks/distributed_equivalence_smoke.py +85 -0
- featm-0.5.7/benchmarks/distributed_persistent_cluster_benchmark.py +158 -0
- featm-0.5.7/benchmarks/scaling_benchmark.py +159 -0
- featm-0.5.7/benchmarks/smoke_universe.py +156 -0
- featm-0.5.7/benchmarks/step5/__init__.py +6 -0
- featm-0.5.7/benchmarks/step5/catalog.py +55 -0
- featm-0.5.7/benchmarks/step5/engine_worker.py +91 -0
- featm-0.5.7/benchmarks/step5/fixtures.py +287 -0
- featm-0.5.7/benchmarks/step5/gen_environment_manifest.py +87 -0
- featm-0.5.7/benchmarks/step5/gen_gpu_provenance_bridge.py +113 -0
- featm-0.5.7/benchmarks/step5/gen_validation_results.py +552 -0
- featm-0.5.7/benchmarks/step5/provenance.py +236 -0
- featm-0.5.7/benchmarks/step5/recompute_gpu_crossover_summary.py +118 -0
- featm-0.5.7/benchmarks/step5/run_dask_crossover_benchmark.py +226 -0
- featm-0.5.7/benchmarks/step5/run_engine_benchmark.py +60 -0
- featm-0.5.7/benchmarks/step5/run_metadata_audit.py +150 -0
- featm-0.5.7/benchmarks/step5/run_real_dataset_family_bundle_redundancy.py +53 -0
- featm-0.5.7/benchmarks/step5/run_real_dataset_family_bundle_utility.py +116 -0
- featm-0.5.7/benchmarks/step5/run_real_dataset_utility.py +367 -0
- featm-0.5.7/benchmarks/step5/run_redundancy_analysis.py +112 -0
- featm-0.5.7/benchmarks/step5/run_regression_matrix.py +175 -0
- featm-0.5.7/benchmarks/step5/run_stateful_benchmark.py +244 -0
- featm-0.5.7/benchmarks/step5/run_system_benchmark.py +183 -0
- featm-0.5.7/benchmarks/step5/run_true_family_bundle_redundancy.py +123 -0
- featm-0.5.7/benchmarks/step5/run_true_family_bundle_utility.py +208 -0
- featm-0.5.7/benchmarks/step5/summarize.py +62 -0
- featm-0.5.7/benchmarks/step5/summarize_dask_crossover.py +70 -0
- featm-0.5.7/benchmarks/step5/summarize_engine.py +54 -0
- featm-0.5.7/benchmarks/step5/utility_probes.py +222 -0
- featm-0.5.7/benchmarks/step5/worker.py +259 -0
- featm-0.5.7/docs/API.md +63 -0
- featm-0.5.7/docs/ARCHITECTURE.md +213 -0
- featm-0.5.7/docs/BENCHMARKS.md +38 -0
- featm-0.5.7/docs/COMPATIBILITY.md +44 -0
- featm-0.5.7/docs/DISTRIBUTED.md +57 -0
- featm-0.5.7/docs/EXECUTION_REFERENCE.md +130 -0
- featm-0.5.7/docs/FEATURE_AUTHORING.md +412 -0
- featm-0.5.7/docs/FEATURE_UNIVERSE.md +638 -0
- featm-0.5.7/docs/GETTING_STARTED.md +129 -0
- featm-0.5.7/docs/INSTALLATION.md +82 -0
- featm-0.5.7/docs/PRACTICAL_EXAMPLES.md +76 -0
- featm-0.5.7/docs/RELEASE_TESTING.md +33 -0
- featm-0.5.7/docs/SCALING.md +76 -0
- featm-0.5.7/examples/README.md +18 -0
- featm-0.5.7/examples/audio_features.py +38 -0
- featm-0.5.7/examples/ecg_features.py +21 -0
- featm-0.5.7/examples/image_features.py +19 -0
- featm-0.5.7/examples/stateful_categories.py +19 -0
- featm-0.5.7/examples/time_series.py +9 -0
- featm-0.5.7/pyproject.toml +170 -0
- featm-0.5.7/scripts/build_gpu_validation_notebook.py +1012 -0
- featm-0.5.7/scripts/build_step4_dask_validation_notebook.py +474 -0
- featm-0.5.7/scripts/build_step5_gpu_crossover_notebook.py +393 -0
- featm-0.5.7/scripts/gen_feature_universe.py +57 -0
- featm-0.5.7/setup.cfg +4 -0
- featm-0.5.7/src/featm/__init__.py +86 -0
- featm-0.5.7/src/featm/cache.py +190 -0
- featm-0.5.7/src/featm/checkpoint.py +231 -0
- featm-0.5.7/src/featm/cli.py +141 -0
- featm-0.5.7/src/featm/contracts.py +93 -0
- featm-0.5.7/src/featm/distributed/__init__.py +25 -0
- featm-0.5.7/src/featm/distributed/checkpoint.py +541 -0
- featm-0.5.7/src/featm/distributed/contracts.py +99 -0
- featm-0.5.7/src/featm/distributed/dask_runtime.py +142 -0
- featm-0.5.7/src/featm/distributed/execution.py +1118 -0
- featm-0.5.7/src/featm/distributed/local.py +83 -0
- featm-0.5.7/src/featm/distributed/partition_provider.py +245 -0
- featm-0.5.7/src/featm/distributed/planner.py +80 -0
- featm-0.5.7/src/featm/distributed/runtime.py +61 -0
- featm-0.5.7/src/featm/engine.py +497 -0
- featm-0.5.7/src/featm/execution.py +1994 -0
- featm-0.5.7/src/featm/executor.py +145 -0
- featm-0.5.7/src/featm/extractor.py +353 -0
- featm-0.5.7/src/featm/features/__init__.py +27 -0
- featm-0.5.7/src/featm/features/_utils.py +498 -0
- featm-0.5.7/src/featm/features/audio/__init__.py +0 -0
- featm-0.5.7/src/featm/features/audio/full.py +302 -0
- featm-0.5.7/src/featm/features/event/__init__.py +0 -0
- featm-0.5.7/src/featm/features/event/full.py +96 -0
- featm-0.5.7/src/featm/features/geometry/triangulation.py +283 -0
- featm-0.5.7/src/featm/features/graph/__init__.py +0 -0
- featm-0.5.7/src/featm/features/graph/full.py +379 -0
- featm-0.5.7/src/featm/features/image/basic.py +66 -0
- featm-0.5.7/src/featm/features/image/full.py +394 -0
- featm-0.5.7/src/featm/features/information/__init__.py +0 -0
- featm-0.5.7/src/featm/features/information/full.py +150 -0
- featm-0.5.7/src/featm/features/manifold/__init__.py +0 -0
- featm-0.5.7/src/featm/features/manifold/full.py +63 -0
- featm-0.5.7/src/featm/features/matrix/__init__.py +0 -0
- featm-0.5.7/src/featm/features/matrix/full.py +56 -0
- featm-0.5.7/src/featm/features/multimodal/__init__.py +0 -0
- featm-0.5.7/src/featm/features/multimodal/full.py +60 -0
- featm-0.5.7/src/featm/features/pointcloud/__init__.py +0 -0
- featm-0.5.7/src/featm/features/pointcloud/full.py +168 -0
- featm-0.5.7/src/featm/features/sequence/__init__.py +0 -0
- featm-0.5.7/src/featm/features/sequence/full.py +128 -0
- featm-0.5.7/src/featm/features/signal/__init__.py +0 -0
- featm-0.5.7/src/featm/features/signal/full.py +249 -0
- featm-0.5.7/src/featm/features/spatial/__init__.py +0 -0
- featm-0.5.7/src/featm/features/spatial/full.py +109 -0
- featm-0.5.7/src/featm/features/tabular/categorical.py +27 -0
- featm-0.5.7/src/featm/features/tabular/datetime.py +66 -0
- featm-0.5.7/src/featm/features/tabular/full.py +404 -0
- featm-0.5.7/src/featm/features/tabular/interactions.py +41 -0
- featm-0.5.7/src/featm/features/tabular/numeric.py +70 -0
- featm-0.5.7/src/featm/features/text/__init__.py +0 -0
- featm-0.5.7/src/featm/features/text/full.py +317 -0
- featm-0.5.7/src/featm/features/timeseries/basic.py +110 -0
- featm-0.5.7/src/featm/features/timeseries/full.py +676 -0
- featm-0.5.7/src/featm/features/topology/__init__.py +0 -0
- featm-0.5.7/src/featm/features/topology/full.py +129 -0
- featm-0.5.7/src/featm/features/video/__init__.py +0 -0
- featm-0.5.7/src/featm/features/video/full.py +117 -0
- featm-0.5.7/src/featm/gpu/__init__.py +50 -0
- featm-0.5.7/src/featm/gpu/backend.py +248 -0
- featm-0.5.7/src/featm/gpu/cache.py +184 -0
- featm-0.5.7/src/featm/gpu/dispatch.py +596 -0
- featm-0.5.7/src/featm/gpu/exceptions.py +79 -0
- featm-0.5.7/src/featm/gpu/kernels/__init__.py +1 -0
- featm-0.5.7/src/featm/gpu/kernels/reductions.py +112 -0
- featm-0.5.7/src/featm/gpu/kernels/spectral.py +207 -0
- featm-0.5.7/src/featm/gpu/memory.py +211 -0
- featm-0.5.7/src/featm/gpu/registration.py +88 -0
- featm-0.5.7/src/featm/matrix.py +553 -0
- featm-0.5.7/src/featm/planner.py +99 -0
- featm-0.5.7/src/featm/registry.py +590 -0
- featm-0.5.7/src/featm/report.py +232 -0
- featm-0.5.7/src/featm/resources.py +412 -0
- featm-0.5.7/src/featm/sampling.py +146 -0
- featm-0.5.7/src/featm/schema.py +131 -0
- featm-0.5.7/src/featm/sources.py +736 -0
- featm-0.5.7/src/featm/state.py +749 -0
- featm-0.5.7/src/featm.egg-info/PKG-INFO +299 -0
- featm-0.5.7/src/featm.egg-info/SOURCES.txt +184 -0
- featm-0.5.7/src/featm.egg-info/dependency_links.txt +1 -0
- featm-0.5.7/src/featm.egg-info/entry_points.txt +2 -0
- featm-0.5.7/src/featm.egg-info/requires.txt +126 -0
- featm-0.5.7/src/featm.egg-info/top_level.txt +1 -0
- featm-0.5.7/tests/conftest.py +70 -0
- featm-0.5.7/tests/fixtures/registry_v0.1.0_names.json +551 -0
- featm-0.5.7/tests/test_audit2.py +593 -0
- featm-0.5.7/tests/test_audit3.py +597 -0
- featm-0.5.7/tests/test_audit4.py +671 -0
- featm-0.5.7/tests/test_audit5.py +486 -0
- featm-0.5.7/tests/test_cache.py +153 -0
- featm-0.5.7/tests/test_checkpoint_replay_history.py +264 -0
- featm-0.5.7/tests/test_checkpoint_state_budget_identity.py +110 -0
- featm-0.5.7/tests/test_core.py +245 -0
- featm-0.5.7/tests/test_distributed_checkpoint.py +727 -0
- featm-0.5.7/tests/test_distributed_dask.py +438 -0
- featm-0.5.7/tests/test_distributed_foundation.py +267 -0
- featm-0.5.7/tests/test_distributed_gpu.py +230 -0
- featm-0.5.7/tests/test_distributed_io.py +277 -0
- featm-0.5.7/tests/test_distributed_planner.py +102 -0
- featm-0.5.7/tests/test_distributed_state_merge.py +275 -0
- featm-0.5.7/tests/test_docs_consistency.py +78 -0
- featm-0.5.7/tests/test_execution.py +834 -0
- featm-0.5.7/tests/test_gpu_backend.py +135 -0
- featm-0.5.7/tests/test_gpu_dispatch.py +914 -0
- featm-0.5.7/tests/test_gpu_memory.py +200 -0
- featm-0.5.7/tests/test_gpu_metadata.py +113 -0
- featm-0.5.7/tests/test_matrix.py +152 -0
- featm-0.5.7/tests/test_sources.py +151 -0
- featm-0.5.7/tests/test_state.py +120 -0
- featm-0.5.7/tests/test_step5_benchmark_foundation.py +484 -0
- featm-0.5.7/tests/test_step5_measurement_harness_provenance.py +249 -0
- featm-0.5.7/tests/test_step5_provenance_gate_hardening.py +254 -0
- featm-0.5.7/tests/test_v055_correctness.py +323 -0
- featm-0.5.7/tests/test_v056_checkpoint_budget.py +215 -0
- featm-0.5.7/tests/test_v057_checkpoint_root.py +80 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: A minimal reproducer and environment details
|
|
4
|
+
title: ""
|
|
5
|
+
labels: ""
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Expected and actual behavior
|
|
10
|
+
|
|
11
|
+
Describe the selected feature/operation and its expected output.
|
|
12
|
+
|
|
13
|
+
## Minimal reproducer
|
|
14
|
+
|
|
15
|
+
Include executable code with synthetic input, explicit features and
|
|
16
|
+
`errors="raise"`. For `warn`/`skip`, also include the execution report and shape.
|
|
17
|
+
|
|
18
|
+
## Environment
|
|
19
|
+
|
|
20
|
+
FEATM version; Python version; OS/architecture; installed extras;
|
|
21
|
+
relevant dependency versions; input shape/dtypes; CPU/GPU/Dask configuration.
|
|
22
|
+
|
|
23
|
+
## Evidence
|
|
24
|
+
|
|
25
|
+
Paste the exception/traceback or report. Do not include tokens, personal data,
|
|
26
|
+
model weights or large datasets. A checkpoint issue may need a redacted manifest
|
|
27
|
+
and the steps that created it, not a binary artifact from an untrusted source.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Check built artifacts without importing the development package."""
|
|
2
|
+
import email,hashlib,json,sys,tarfile,tomllib,zipfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
root=Path(__file__).resolve().parents[2]
|
|
6
|
+
dist=Path(sys.argv[1]).resolve()
|
|
7
|
+
p=tomllib.loads((root/'pyproject.toml').read_text(encoding='utf-8'))['project']
|
|
8
|
+
assert p['name']=='featm' and p['version']=='0.5.7'
|
|
9
|
+
expected={'featm-0.5.7-py3-none-any.whl','featm-0.5.7.tar.gz'}
|
|
10
|
+
assert {f.name for f in dist.iterdir()}==expected
|
|
11
|
+
with zipfile.ZipFile(dist/'featm-0.5.7-py3-none-any.whl') as w,tarfile.open(dist/'featm-0.5.7.tar.gz') as t:
|
|
12
|
+
m=email.message_from_string(w.read('featm-0.5.7.dist-info/METADATA').decode('utf-8'))
|
|
13
|
+
s=email.message_from_string(t.extractfile('featm-0.5.7/PKG-INFO').read().decode('utf-8'))
|
|
14
|
+
assert m['Name']==s['Name']=='featm' and m['Version']==s['Version']=='0.5.7'
|
|
15
|
+
assert m.get_all('Requires-Dist')==s.get_all('Requires-Dist')
|
|
16
|
+
assert m['Requires-Python']==s['Requires-Python']==p['requires-python']
|
|
17
|
+
assert m.get_payload().replace('\r\n','\n').strip()==(root/'README.md').read_text(encoding='utf-8').strip()
|
|
18
|
+
licenses=[n for n in w.namelist() if n.endswith('/LICENSE')]
|
|
19
|
+
assert len(licenses)==1 and w.read(licenses[0])==(root/'LICENSE').read_bytes()
|
|
20
|
+
assert t.extractfile('featm-0.5.7/LICENSE').read()==(root/'LICENSE').read_bytes()
|
|
21
|
+
names={x.relative_to(root/'src').as_posix() for x in (root/'src/featm').rglob('*.py')}
|
|
22
|
+
assert len(names)==77 and names=={n for n in w.namelist() if n.startswith('featm/') and n.endswith('.py')}
|
|
23
|
+
for n in names:
|
|
24
|
+
assert w.read(n)==t.extractfile('featm-0.5.7/src/'+n).read()==(root/'src'/n).read_bytes()
|
|
25
|
+
print('PASS: version, metadata, README, license and 77 product files')
|
|
26
|
+
(root/'release-artifact-hashes.json').write_text(json.dumps({f.name:{'sha256':hashlib.sha256(f.read_bytes()).hexdigest(),'bytes':f.stat().st_size} for f in sorted(dist.iterdir())},indent=2))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Exercise an installed wheel in a fresh environment, never an editable install."""
|
|
2
|
+
import os,subprocess,sys,tempfile,venv
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
root=Path(__file__).resolve().parents[2]
|
|
6
|
+
wheel=next(Path(sys.argv[1]).resolve().glob('*.whl'))
|
|
7
|
+
env=os.environ.copy();env.pop('PYTHONPATH',None);env.update(PYTHONNOUSERSITE='1',PYTHONDONTWRITEBYTECODE='1',PYTHONUTF8='1')
|
|
8
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
9
|
+
base=Path(tmp);v=base/'env';venv.create(v,with_pip=True)
|
|
10
|
+
py=v/('Scripts/python.exe' if os.name=='nt' else 'bin/python')
|
|
11
|
+
def run(*args):subprocess.run([str(py),*map(str,args)],cwd=base,env=env,check=True)
|
|
12
|
+
# These are test dependencies, not changes to the package's runtime metadata.
|
|
13
|
+
run('-m','pip','install',wheel,'pytest','networkx','scipy','pyarrow')
|
|
14
|
+
run('-m','pip','check')
|
|
15
|
+
run('-c',"import featm,importlib.metadata as m,numpy as np,sys; from pathlib import Path; package_path=Path(featm.__file__).resolve(); environment_path=Path(sys.prefix).resolve(); print('INSTALLED_WHEEL',package_path,'ENVIRONMENT',environment_path); assert package_path.is_relative_to(environment_path), (package_path,environment_path); s=featm.REGISTRY.all(); assert featm.__version__==m.version('featm')=='0.5.7'; assert [len(s),len({x.modality for x in s}),len({(x.modality,x.family) for x in s}),sum(x.stateful for x in s),sum(x.gpu_available for x in s)]==[552,18,182,7,22]; np.testing.assert_allclose(featm.extract(np.array([[1.,2.,3.,4.],[10.,20.,30.,40.]]),features=['timeseries.statistical.mean'],errors='raise').to_numpy().ravel(),[2.5,25.])")
|
|
16
|
+
cfg=base/'pytest.ini';cfg.write_text('[pytest]\n')
|
|
17
|
+
runner=base/'runner.py';runner.write_text("import os,sys\nfrom pathlib import Path\nroot=Path(sys.argv.pop(1)); sys.path.insert(0,str(root)); os.chdir(root)\nimport featm,pytest\nassert not Path(featm.__file__).resolve().is_relative_to(root)\nraise SystemExit(pytest.main(sys.argv[1:]))\n")
|
|
18
|
+
run(runner,root,'-c',cfg,'tests/test_core.py','tests/test_state.py','tests/test_matrix.py','tests/test_v057_checkpoint_root.py','-q','-p','no:cacheprovider')
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Distribution CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
jobs:
|
|
9
|
+
wheel:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ubuntu-latest, windows-latest]
|
|
15
|
+
python: ['3.11']
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
18
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python }}
|
|
21
|
+
- name: Build and inspect distributions
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install build twine
|
|
24
|
+
python -m build
|
|
25
|
+
python -m twine check dist/*
|
|
26
|
+
python .github/scripts/check_release.py dist
|
|
27
|
+
- name: Install wheel into a fresh environment and test
|
|
28
|
+
run: python .github/scripts/test_wheel.py dist
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Publish reviewed release to PyPI
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
concurrency:
|
|
8
|
+
group: featm-pypi-v0.5.7
|
|
9
|
+
cancel-in-progress: false
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
if: >-
|
|
13
|
+
github.repository == 'Harish-K22/featm' &&
|
|
14
|
+
github.repository_id == '1409483295' &&
|
|
15
|
+
github.event.repository.private == true &&
|
|
16
|
+
github.actor == 'Harish-K22' &&
|
|
17
|
+
github.event.release.draft == false &&
|
|
18
|
+
github.event.release.prerelease == false &&
|
|
19
|
+
github.event.release.tag_name == 'v0.5.7' &&
|
|
20
|
+
github.event.release.author.login == 'Harish-K22'
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
24
|
+
with:
|
|
25
|
+
ref: refs/tags/v0.5.7
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: '3.11'
|
|
30
|
+
- name: Verify owner-approved release commit
|
|
31
|
+
env:
|
|
32
|
+
APPROVED_RELEASE_COMMIT: ${{ vars.FEATM_APPROVED_RELEASE_COMMIT }}
|
|
33
|
+
run: |
|
|
34
|
+
python -c "import os,re,subprocess; expected=os.environ['APPROVED_RELEASE_COMMIT']; actual=subprocess.check_output(['git','rev-parse','HEAD'],text=True).strip(); assert re.fullmatch('[0-9a-f]{40}',expected), 'Set the repository variable FEATM_APPROVED_RELEASE_COMMIT to the reviewed full SHA'; assert actual==expected, 'Release tag does not point to the approved commit'; print('Approved source commit:',actual)"
|
|
35
|
+
- name: Validate exact source version and build
|
|
36
|
+
env:
|
|
37
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
38
|
+
run: |
|
|
39
|
+
python -m pip install build twine
|
|
40
|
+
python -c "import os,tomllib; p=tomllib.load(open('pyproject.toml','rb'))['project']; assert p['name']=='featm' and p['version']=='0.5.7' and os.environ['RELEASE_TAG']=='v'+p['version']"
|
|
41
|
+
python -m build
|
|
42
|
+
python -m twine check dist/*
|
|
43
|
+
python .github/scripts/check_release.py dist
|
|
44
|
+
python .github/scripts/test_wheel.py dist
|
|
45
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
46
|
+
with:
|
|
47
|
+
name: pypi-distributions
|
|
48
|
+
path: dist/
|
|
49
|
+
if-no-files-found: error
|
|
50
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
51
|
+
with:
|
|
52
|
+
name: reviewed-distribution-hashes
|
|
53
|
+
path: release-artifact-hashes.json
|
|
54
|
+
if-no-files-found: error
|
|
55
|
+
publish:
|
|
56
|
+
needs: build
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
permissions:
|
|
59
|
+
id-token: write
|
|
60
|
+
actions: read
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
63
|
+
with:
|
|
64
|
+
name: pypi-distributions
|
|
65
|
+
path: dist/
|
|
66
|
+
- name: Publish using OIDC
|
|
67
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
68
|
+
with:
|
|
69
|
+
packages-dir: dist/
|
featm-0.5.7/.gitignore
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
venv/
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.coverage
|
|
7
|
+
htmlcov/
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.DS_Store
|
|
12
|
+
Thumbs.db
|
|
13
|
+
.env
|
|
14
|
+
.env.*
|
|
15
|
+
datasets/
|
|
16
|
+
models/
|
|
17
|
+
checkpoints/
|
|
18
|
+
step5_final_results/
|
|
19
|
+
*_AUDIT_HANDOFF.zip
|
featm-0.5.7/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Release notes
|
|
2
|
+
|
|
3
|
+
## 0.5.7 — initial public release
|
|
4
|
+
|
|
5
|
+
FEATM offers a searchable registry for explicit, named feature extraction
|
|
6
|
+
across time series, tabular data and other modalities. Discover names with
|
|
7
|
+
`list_features`, create a callable with `create_feature`, and extract a selected
|
|
8
|
+
set with `extract`. Reuse training-only fitted transformations with `fit`,
|
|
9
|
+
`transform`, `save` and `load_fitted`.
|
|
10
|
+
|
|
11
|
+
The package includes bounded source execution, disk-backed results, compatible
|
|
12
|
+
checkpoint resume, Dask partition execution and a scoped 22-method CuPy GPU
|
|
13
|
+
surface. Backends and external models are optional; the beginner example uses
|
|
14
|
+
only base dependencies. The supporting catalogue retains 552 entries across
|
|
15
|
+
18 modalities, not a claim of universal predictive improvement.
|
|
16
|
+
|
|
17
|
+
v0.5.7 rejects non-object checkpoint JSON roots without overwriting invalid
|
|
18
|
+
manifests, while preserving missing-file creation and valid resume behavior.
|
|
19
|
+
The documentation explains time-series shapes, error/report access,
|
|
20
|
+
training-only state, optional installation and execution limits.
|
|
21
|
+
|
|
22
|
+
Base certification is Windows/Ubuntu-WSL x86-64 CPython 3.10–3.14. Node2vec,
|
|
23
|
+
gensim/text and actual Windows CUDA support have narrower scopes; macOS, ARM
|
|
24
|
+
and Python 3.15 are unvalidated. Short harmonic/tonnetz inputs retain an
|
|
25
|
+
upstream librosa numerical limitation. See [compatibility](docs/COMPATIBILITY.md).
|
|
26
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use explicit named methods, and include a small reproducer when reporting a
|
|
4
|
+
problem. A report should contain the FEATM/Python versions, OS and architecture,
|
|
5
|
+
installed extras and dependency versions, input shape/dtypes, exact feature
|
|
6
|
+
names and parameters, error policy, actual exception/report and expected result.
|
|
7
|
+
For CUDA/Dask, include device/runtime or worker configuration. Remove credentials
|
|
8
|
+
and personal data; prefer synthetic inputs over private datasets.
|
|
9
|
+
|
|
10
|
+
The owner-confirmed repository is [https://github.com/Harish-K22/featm](https://github.com/Harish-K22/featm).
|
|
11
|
+
Use its [issue tracker](https://github.com/Harish-K22/featm/issues) when available; no private contact
|
|
12
|
+
address or repository visibility is assumed by these instructions.
|
|
13
|
+
|
|
14
|
+
## Development setup
|
|
15
|
+
|
|
16
|
+
Once repository access is available, obtain a checkout from `https://github.com/Harish-K22/featm`.
|
|
17
|
+
The package lives in `src/featm/`; method definitions live in `src/featm/features/`
|
|
18
|
+
and stateful encoders in `src/featm/state.py`. From a checkout, in a virtual environment:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
python -m pip install -e ".[dev,io,distributed,scientific]"
|
|
22
|
+
python -m pytest -q -ra
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
These are actual extras. Tests for optional backends/models may skip when their
|
|
26
|
+
dependencies are absent; include skip reasons. CUDA tests need the certified
|
|
27
|
+
GPU setup, not merely the development extra. A minimal CI job can use the above
|
|
28
|
+
CPU setup on the tested Windows/Ubuntu x86-64 Python scope; do not add unvalidated
|
|
29
|
+
platform badges or infer optional-wide support from a green base job.
|
|
30
|
+
|
|
31
|
+
Feature authoring contracts are in [docs/FEATURE_AUTHORING.md](docs/FEATURE_AUTHORING.md).
|
|
32
|
+
Changes should explain inputs, named outputs, dependencies, batch/stateful
|
|
33
|
+
semantics and relevant numerical verification. Avoid committing environments,
|
|
34
|
+
datasets, model weights, checkpoints or private audit material. Product/API
|
|
35
|
+
changes require their own review; this staged release preserves the audited implementation.
|
featm-0.5.7/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harish K
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
featm-0.5.7/MANIFEST.in
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
include README.md LICENSE CONTRIBUTING.md THIRD_PARTY_NOTICES.md CHANGELOG.md
|
|
2
|
+
include .gitignore .gitattributes
|
|
3
|
+
recursive-include docs *.md
|
|
4
|
+
recursive-include examples *.py *.md
|
|
5
|
+
recursive-include tests *.py *.json
|
|
6
|
+
recursive-include benchmarks *.py *.json *.csv
|
|
7
|
+
recursive-include scripts *.py
|
|
8
|
+
recursive-include .github *.md *.yml *.py *.ini
|
|
9
|
+
global-exclude *.pyc *.pyo .DS_Store Thumbs.db
|
|
10
|
+
prune .git
|
|
11
|
+
prune .venv
|
|
12
|
+
prune build
|
|
13
|
+
prune dist
|
featm-0.5.7/PKG-INFO
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: featm
|
|
3
|
+
Version: 0.5.7
|
|
4
|
+
Summary: One searchable API for explicit, named feature extraction across data modalities.
|
|
5
|
+
Author: featm contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Harish-K22/featm
|
|
8
|
+
Project-URL: Repository, https://github.com/Harish-K22/featm
|
|
9
|
+
Project-URL: Issues, https://github.com/Harish-K22/featm/issues
|
|
10
|
+
Keywords: feature-engineering,feature-extraction,machine-learning,time-series,signal-processing,computational-geometry,graphs
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: numpy>=1.24
|
|
15
|
+
Requires-Dist: pandas>=2.0
|
|
16
|
+
Requires-Dist: psutil>=5.9
|
|
17
|
+
Provides-Extra: io
|
|
18
|
+
Requires-Dist: pyarrow>=14; extra == "io"
|
|
19
|
+
Requires-Dist: polars>=1.0; extra == "io"
|
|
20
|
+
Provides-Extra: distributed
|
|
21
|
+
Requires-Dist: dask[distributed]>=2024.1; extra == "distributed"
|
|
22
|
+
Provides-Extra: scientific
|
|
23
|
+
Requires-Dist: scipy>=1.10; extra == "scientific"
|
|
24
|
+
Requires-Dist: scikit-learn>=1.3; extra == "scientific"
|
|
25
|
+
Requires-Dist: statsmodels>=0.14; extra == "scientific"
|
|
26
|
+
Provides-Extra: geometry
|
|
27
|
+
Requires-Dist: scipy>=1.10; extra == "geometry"
|
|
28
|
+
Requires-Dist: scikit-learn>=1.3; extra == "geometry"
|
|
29
|
+
Provides-Extra: graph
|
|
30
|
+
Requires-Dist: networkx>=3.0; extra == "graph"
|
|
31
|
+
Requires-Dist: scipy>=1.10; extra == "graph"
|
|
32
|
+
Requires-Dist: python-igraph>=0.11; extra == "graph"
|
|
33
|
+
Requires-Dist: leidenalg>=0.10; extra == "graph"
|
|
34
|
+
Requires-Dist: gensim>=4.4; python_version < "3.14" and extra == "graph"
|
|
35
|
+
Provides-Extra: graph-node2vec
|
|
36
|
+
Requires-Dist: networkx>=3.0; python_version < "3.13" and extra == "graph-node2vec"
|
|
37
|
+
Requires-Dist: gensim>=4.4; python_version < "3.13" and extra == "graph-node2vec"
|
|
38
|
+
Requires-Dist: node2vec>=0.5; python_version < "3.13" and extra == "graph-node2vec"
|
|
39
|
+
Provides-Extra: audio
|
|
40
|
+
Requires-Dist: librosa<1.0,>=0.11; python_version < "3.12" and extra == "audio"
|
|
41
|
+
Requires-Dist: librosa>=1.0; python_version >= "3.12" and extra == "audio"
|
|
42
|
+
Requires-Dist: scipy>=1.10; extra == "audio"
|
|
43
|
+
Provides-Extra: vision
|
|
44
|
+
Requires-Dist: opencv-python>=4.8; extra == "vision"
|
|
45
|
+
Requires-Dist: scikit-image>=0.22; extra == "vision"
|
|
46
|
+
Requires-Dist: scipy>=1.10; extra == "vision"
|
|
47
|
+
Provides-Extra: signal
|
|
48
|
+
Requires-Dist: scipy>=1.10; extra == "signal"
|
|
49
|
+
Requires-Dist: statsmodels>=0.14; extra == "signal"
|
|
50
|
+
Requires-Dist: EMD-signal>=1.6; extra == "signal"
|
|
51
|
+
Requires-Dist: vmdpy>=0.2; extra == "signal"
|
|
52
|
+
Provides-Extra: topology
|
|
53
|
+
Requires-Dist: gudhi>=3.9; extra == "topology"
|
|
54
|
+
Requires-Dist: scipy>=1.10; extra == "topology"
|
|
55
|
+
Provides-Extra: pointcloud
|
|
56
|
+
Requires-Dist: open3d>=0.18; extra == "pointcloud"
|
|
57
|
+
Requires-Dist: scipy>=1.10; extra == "pointcloud"
|
|
58
|
+
Provides-Extra: text
|
|
59
|
+
Requires-Dist: scikit-learn>=1.3; extra == "text"
|
|
60
|
+
Requires-Dist: gensim>=4.4; extra == "text"
|
|
61
|
+
Requires-Dist: spacy>=3.7; extra == "text"
|
|
62
|
+
Provides-Extra: embeddings
|
|
63
|
+
Requires-Dist: torch>=2.2; extra == "embeddings"
|
|
64
|
+
Requires-Dist: timm>=1.0; extra == "embeddings"
|
|
65
|
+
Requires-Dist: transformers>=4.40; extra == "embeddings"
|
|
66
|
+
Requires-Dist: sentence-transformers>=3.0; extra == "embeddings"
|
|
67
|
+
Requires-Dist: Pillow>=10; extra == "embeddings"
|
|
68
|
+
Provides-Extra: calendar
|
|
69
|
+
Requires-Dist: holidays>=0.50; extra == "calendar"
|
|
70
|
+
Provides-Extra: gpu
|
|
71
|
+
Requires-Dist: cupy-cuda12x[ctk]>=14.0; sys_platform != "darwin" and extra == "gpu"
|
|
72
|
+
Provides-Extra: gpu-cupy
|
|
73
|
+
Requires-Dist: cupy-cuda12x[ctk]>=14.0; sys_platform != "darwin" and extra == "gpu-cupy"
|
|
74
|
+
Provides-Extra: gpu-torch
|
|
75
|
+
Requires-Dist: torch>=2.2; extra == "gpu-torch"
|
|
76
|
+
Provides-Extra: gpu-rapids
|
|
77
|
+
Provides-Extra: full
|
|
78
|
+
Requires-Dist: scipy>=1.10; extra == "full"
|
|
79
|
+
Requires-Dist: scikit-learn>=1.3; extra == "full"
|
|
80
|
+
Requires-Dist: statsmodels>=0.14; extra == "full"
|
|
81
|
+
Requires-Dist: networkx>=3.0; extra == "full"
|
|
82
|
+
Requires-Dist: python-igraph>=0.11; extra == "full"
|
|
83
|
+
Requires-Dist: leidenalg>=0.10; extra == "full"
|
|
84
|
+
Requires-Dist: librosa<1.0,>=0.11; python_version < "3.12" and extra == "full"
|
|
85
|
+
Requires-Dist: librosa>=1.0; python_version >= "3.12" and extra == "full"
|
|
86
|
+
Requires-Dist: opencv-python>=4.8; extra == "full"
|
|
87
|
+
Requires-Dist: scikit-image>=0.22; extra == "full"
|
|
88
|
+
Requires-Dist: EMD-signal>=1.6; extra == "full"
|
|
89
|
+
Requires-Dist: vmdpy>=0.2; extra == "full"
|
|
90
|
+
Requires-Dist: gudhi>=3.9; extra == "full"
|
|
91
|
+
Requires-Dist: open3d>=0.18; extra == "full"
|
|
92
|
+
Requires-Dist: gensim>=4.4; extra == "full"
|
|
93
|
+
Requires-Dist: spacy>=3.7; extra == "full"
|
|
94
|
+
Requires-Dist: holidays>=0.50; extra == "full"
|
|
95
|
+
Requires-Dist: torch>=2.2; extra == "full"
|
|
96
|
+
Requires-Dist: timm>=1.0; extra == "full"
|
|
97
|
+
Requires-Dist: transformers>=4.40; extra == "full"
|
|
98
|
+
Requires-Dist: sentence-transformers>=3.0; extra == "full"
|
|
99
|
+
Requires-Dist: Pillow>=10; extra == "full"
|
|
100
|
+
Provides-Extra: dev
|
|
101
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
102
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
103
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
104
|
+
Dynamic: license-file
|
|
105
|
+
|
|
106
|
+
# FEATM
|
|
107
|
+
|
|
108
|
+
[Repository](https://github.com/Harish-K22/featm) · [Release notes](CHANGELOG.md)
|
|
109
|
+
|
|
110
|
+
**One searchable API for explicit, named feature extraction across data modalities.**
|
|
111
|
+
|
|
112
|
+
Use FEATM to discover an existing feature method by name, compute a small feature
|
|
113
|
+
set, and reuse fitted transformations on new data. You choose the methods;
|
|
114
|
+
FEATM does not select features automatically or promise better model accuracy.
|
|
115
|
+
|
|
116
|
+
## Quickstart
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import numpy as np
|
|
120
|
+
import featm
|
|
121
|
+
|
|
122
|
+
# Two samples, each with four time steps.
|
|
123
|
+
X = np.array([
|
|
124
|
+
[1.0, 2.0, 3.0, 4.0],
|
|
125
|
+
[10.0, 20.0, 30.0, 40.0],
|
|
126
|
+
])
|
|
127
|
+
result = featm.extract(
|
|
128
|
+
X,
|
|
129
|
+
features=["timeseries.statistical.mean", "timeseries.statistical.std"],
|
|
130
|
+
errors="raise",
|
|
131
|
+
)
|
|
132
|
+
print(result)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The mean column contains `2.5` and `25.0`: one output row per input sample.
|
|
136
|
+
For time-series features, `(n_steps,)` means one series, and
|
|
137
|
+
`(n_samples, n_steps)` means a batch. An `(8, 1)` array means eight one-step
|
|
138
|
+
series, **not** one eight-step series. Other modalities use different inputs;
|
|
139
|
+
see [input conventions](docs/GETTING_STARTED.md#input-conventions).
|
|
140
|
+
|
|
141
|
+
## Installation
|
|
142
|
+
|
|
143
|
+
Install FEATM from PyPI:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
pip install featm
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
During initial release testing, GitHub remains private; see the
|
|
150
|
+
[repository-access note](docs/INSTALLATION.md#initial-publication-period).
|
|
151
|
+
|
|
152
|
+
The quickstart needs only base dependencies: NumPy, pandas and psutil.
|
|
153
|
+
For checkpoints, Parquet, Arrow or disk-backed output, install the IO extra:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
python -m pip install "featm[io]"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Quoted requirements work in PowerShell and POSIX shells. See the full
|
|
160
|
+
[installation table](docs/INSTALLATION.md) for minimal optional backends.
|
|
161
|
+
|
|
162
|
+
## Find a feature
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
import numpy as np
|
|
166
|
+
import featm
|
|
167
|
+
|
|
168
|
+
print(featm.list_features("timeseries.fractal.*"))
|
|
169
|
+
print(featm.list_features("*entropy*"))
|
|
170
|
+
print(featm.list_features("*mean*"))
|
|
171
|
+
|
|
172
|
+
spec = featm.feature_info("timeseries.statistical.mean")
|
|
173
|
+
print(spec.input_types, spec.requires, spec.default_params)
|
|
174
|
+
mean = featm.create_feature("timeseries.statistical.mean")
|
|
175
|
+
print(mean(np.array([1.0, 2.0, 3.0, 4.0])))
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Names follow `modality.family.feature_name`. Narrow a broad search such as
|
|
179
|
+
`timeseries.*` by family. `list_modalities()`, `list_families()` and `search()`
|
|
180
|
+
also help with discovery. Parameters and input types vary by feature;
|
|
181
|
+
[API guidance](docs/API.md) explains what metadata is available.
|
|
182
|
+
Some features, including MFCC, HOG and LBP, expand into multiple named columns.
|
|
183
|
+
There is intentionally no `features="all"` mode.
|
|
184
|
+
|
|
185
|
+
## Modalities and inputs
|
|
186
|
+
|
|
187
|
+
The registry covers time series, tabular, graph, image, audio, text, geometry,
|
|
188
|
+
point clouds, signal, video, information, sequence, matrix, topology, manifold,
|
|
189
|
+
spatial, event and multimodal data. Each family has its own input contract.
|
|
190
|
+
For example, text features typically accept an iterable of documents, while
|
|
191
|
+
graph features accept graph objects; do not reshape them using the time-series
|
|
192
|
+
convention.
|
|
193
|
+
|
|
194
|
+
The supporting inventory is 552 registered entries, 18 modalities and 182
|
|
195
|
+
modality/family groups. The [feature catalogue](docs/FEATURE_UNIVERSE.md) lists
|
|
196
|
+
names and dependencies. An entry's availability does not imply that its
|
|
197
|
+
optional backend or external model is installed.
|
|
198
|
+
|
|
199
|
+
## Reuse state learned from training data
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from pathlib import Path
|
|
203
|
+
from tempfile import TemporaryDirectory
|
|
204
|
+
import numpy as np
|
|
205
|
+
import pandas as pd
|
|
206
|
+
import featm
|
|
207
|
+
|
|
208
|
+
name = "tabular.encoding.category_frequency"
|
|
209
|
+
train = pd.DataFrame({"category": ["A", "A", "B", "B", "B", "C"]})
|
|
210
|
+
test = pd.DataFrame({"category": ["A", "B", "C", "D"]})
|
|
211
|
+
fitted = featm.fit(
|
|
212
|
+
train, features=[name], columns={name: "category"}, errors="raise"
|
|
213
|
+
)
|
|
214
|
+
result = fitted.transform(test)
|
|
215
|
+
print(result.to_pandas())
|
|
216
|
+
np.testing.assert_allclose(result.to_numpy().ravel(), [2/6, 3/6, 1/6, 0])
|
|
217
|
+
|
|
218
|
+
with TemporaryDirectory() as directory:
|
|
219
|
+
path = Path(directory) / "categories.pkl"
|
|
220
|
+
fitted.save(path)
|
|
221
|
+
restored = featm.load_fitted(path)
|
|
222
|
+
np.testing.assert_array_equal(
|
|
223
|
+
result.to_numpy(), restored.transform(test).to_numpy()
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Only `train` supplies fitted statistics. Unseen category `D` maps to zero;
|
|
228
|
+
transforming `test` does not refit the encoder. `extract()` fits and transforms
|
|
229
|
+
its own input, so use `fit()` followed by `transform()` for a train/test split.
|
|
230
|
+
There are seven stateful entries, including scaling and corpus-statistic text
|
|
231
|
+
features. See [stateful workflows](docs/GETTING_STARTED.md#stateful-workflows).
|
|
232
|
+
|
|
233
|
+
## Errors and return types
|
|
234
|
+
|
|
235
|
+
Start with `errors="raise"` so a shape, parameter or dependency error is visible.
|
|
236
|
+
The default `errors="skip"` isolates feature failures and can return an empty
|
|
237
|
+
result if none succeeds. `errors="warn"` also emits warnings. An empty result
|
|
238
|
+
is not proof that every requested feature ran.
|
|
239
|
+
|
|
240
|
+
For a simple in-memory `pandas.DataFrame` result, inspect
|
|
241
|
+
`result.attrs.get("execution_report", {})`. The report is present when this
|
|
242
|
+
path records failures. Out-of-core extraction and fitted transformations use
|
|
243
|
+
`FeatureMatrix`: inspect `result.report` and convert with `result.to_pandas()`.
|
|
244
|
+
For large results, iterate batches rather than materializing everything.
|
|
245
|
+
See [tested error examples](docs/GETTING_STARTED.md#error-policy-and-reports).
|
|
246
|
+
|
|
247
|
+
## Larger data, checkpointing and execution backends
|
|
248
|
+
|
|
249
|
+
File-backed extraction can read bounded batches, save disk-backed results and
|
|
250
|
+
resume a compatible checkpoint. IO is required for checkpoints even when the
|
|
251
|
+
input is already in memory. Existing incompatible or structurally invalid
|
|
252
|
+
checkpoints fail closed; choose a fresh directory when you want a new run.
|
|
253
|
+
Memory budgets guide execution; they are not a hard cap on total process RSS.
|
|
254
|
+
|
|
255
|
+
CPU is the default. Optional CuPy kernels cover 22 features; strict GPU mode
|
|
256
|
+
raises when a requested GPU implementation is unavailable, while fallback mode
|
|
257
|
+
reports a CPU fallback. Dask distributes eligible features according to their
|
|
258
|
+
batch semantics. Start with [scaling and checkpoints](docs/SCALING.md),
|
|
259
|
+
[GPU setup](docs/INSTALLATION.md#gpu) or [Dask](docs/DISTRIBUTED.md).
|
|
260
|
+
|
|
261
|
+
## Examples and documentation
|
|
262
|
+
|
|
263
|
+
- [Getting started](docs/GETTING_STARTED.md): shapes, multiple families,
|
|
264
|
+
reports and fitted state.
|
|
265
|
+
- [Installation](docs/INSTALLATION.md) and [compatibility](docs/COMPATIBILITY.md).
|
|
266
|
+
- [Small executable examples](examples/README.md), including audio, images
|
|
267
|
+
and dataset-loading recipes without model-performance claims.
|
|
268
|
+
- [Evidence and benchmark interpretation](docs/BENCHMARKS.md).
|
|
269
|
+
- [Feature authoring](docs/FEATURE_AUTHORING.md) and
|
|
270
|
+
[architecture](docs/ARCHITECTURE.md) for contributors.
|
|
271
|
+
|
|
272
|
+
## Compatibility and known limits
|
|
273
|
+
|
|
274
|
+
Base certification covers Windows x86-64 and Ubuntu/WSL Linux x86-64 with
|
|
275
|
+
CPython 3.10–3.14. Optional extras have narrower scopes: node2vec is certified
|
|
276
|
+
on 3.10–3.12, and gensim-backed text/DeepWalk paths through 3.13.
|
|
277
|
+
`full` is not a universal recommendation across all base Python versions.
|
|
278
|
+
Real GPU evidence is limited to the tested Windows/CUDA-12/CuPy-14 configuration.
|
|
279
|
+
macOS, ARM and Python 3.15 are **not validated**, rather than proven incompatible.
|
|
280
|
+
|
|
281
|
+
Certain short harmonic/tonnetz inputs can yield non-finite values inside
|
|
282
|
+
librosa. This was reproduced upstream without importing FEATM. No minimum
|
|
283
|
+
safe duration, universal sample-rate claim or upstream fix is asserted.
|
|
284
|
+
See [compatibility details](docs/COMPATIBILITY.md).
|
|
285
|
+
|
|
286
|
+
FEATM is explicit extraction, not AutoML, relational DFS or automatic feature
|
|
287
|
+
selection. New windowing infrastructure and sklearn Pipeline integration are
|
|
288
|
+
outside v0.5.7. A legacy `AutoFeatures` planner remains for compatibility; it
|
|
289
|
+
is not the recommended discovery or extraction workflow.
|
|
290
|
+
|
|
291
|
+
## Contributing and license
|
|
292
|
+
|
|
293
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and reproducible bug reports.
|
|
294
|
+
The owner-confirmed project address is [GitHub](https://github.com/Harish-K22/featm); report reproducible
|
|
295
|
+
problems using the [issue tracker](https://github.com/Harish-K22/featm/issues) once the repository is available.
|
|
296
|
+
|
|
297
|
+
FEATM's own code is distributed under the [MIT License](LICENSE),
|
|
298
|
+
Copyright (c) 2026 Harish K. Optional dependencies, datasets and external models
|
|
299
|
+
retain their own terms. See [third-party scope](THIRD_PARTY_NOTICES.md).
|