salearn 1.0.0__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.
Files changed (51) hide show
  1. salearn-1.0.0/LICENSE +21 -0
  2. salearn-1.0.0/PKG-INFO +221 -0
  3. salearn-1.0.0/README.md +170 -0
  4. salearn-1.0.0/pyproject.toml +48 -0
  5. salearn-1.0.0/salearn/__init__.py +49 -0
  6. salearn-1.0.0/salearn/_numba.py +34 -0
  7. salearn-1.0.0/salearn/automl.py +104 -0
  8. salearn-1.0.0/salearn/base.py +120 -0
  9. salearn-1.0.0/salearn/calibration.py +76 -0
  10. salearn-1.0.0/salearn/clean.py +131 -0
  11. salearn-1.0.0/salearn/cluster.py +305 -0
  12. salearn-1.0.0/salearn/compose.py +3 -0
  13. salearn-1.0.0/salearn/datasets.py +86 -0
  14. salearn-1.0.0/salearn/db.py +322 -0
  15. salearn-1.0.0/salearn/decomposition.py +285 -0
  16. salearn-1.0.0/salearn/dummy.py +3 -0
  17. salearn-1.0.0/salearn/eda.py +167 -0
  18. salearn-1.0.0/salearn/ensemble.py +610 -0
  19. salearn-1.0.0/salearn/exceptions.py +10 -0
  20. salearn-1.0.0/salearn/explain.py +89 -0
  21. salearn-1.0.0/salearn/extras.py +407 -0
  22. salearn-1.0.0/salearn/feature_selection.py +164 -0
  23. salearn-1.0.0/salearn/features.py +154 -0
  24. salearn-1.0.0/salearn/impute.py +107 -0
  25. salearn-1.0.0/salearn/io.py +189 -0
  26. salearn-1.0.0/salearn/linear_model.py +489 -0
  27. salearn-1.0.0/salearn/metrics.py +534 -0
  28. salearn-1.0.0/salearn/mixture.py +131 -0
  29. salearn-1.0.0/salearn/model_selection.py +296 -0
  30. salearn-1.0.0/salearn/multiclass.py +3 -0
  31. salearn-1.0.0/salearn/multioutput.py +3 -0
  32. salearn-1.0.0/salearn/naive_bayes.py +129 -0
  33. salearn-1.0.0/salearn/neighbors.py +157 -0
  34. salearn-1.0.0/salearn/neural_network.py +244 -0
  35. salearn-1.0.0/salearn/persist.py +78 -0
  36. salearn-1.0.0/salearn/pipeline.py +139 -0
  37. salearn-1.0.0/salearn/preprocessing.py +323 -0
  38. salearn-1.0.0/salearn/svm.py +330 -0
  39. salearn-1.0.0/salearn/text.py +155 -0
  40. salearn-1.0.0/salearn/timeseries.py +171 -0
  41. salearn-1.0.0/salearn/tree.py +351 -0
  42. salearn-1.0.0/salearn/utils.py +73 -0
  43. salearn-1.0.0/salearn/viz.py +72 -0
  44. salearn-1.0.0/salearn.egg-info/PKG-INFO +221 -0
  45. salearn-1.0.0/salearn.egg-info/SOURCES.txt +49 -0
  46. salearn-1.0.0/salearn.egg-info/dependency_links.txt +1 -0
  47. salearn-1.0.0/salearn.egg-info/requires.txt +33 -0
  48. salearn-1.0.0/salearn.egg-info/top_level.txt +1 -0
  49. salearn-1.0.0/setup.cfg +4 -0
  50. salearn-1.0.0/tests/test_smoke.py +93 -0
  51. salearn-1.0.0/tests/test_stack.py +112 -0
salearn-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 salim-studio
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.
salearn-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: salearn
3
+ Version: 1.0.0
4
+ Summary: salearn — sklearn-compatible ML plus databases, EDA, AutoML, time-series and NLP in one import
5
+ Author: salim-studio
6
+ Maintainer: salim-studio
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/salim-studio/salearn
9
+ Project-URL: Documentation, https://github.com/salim-studio/salearn#readme
10
+ Project-URL: Repository, https://github.com/salim-studio/salearn
11
+ Project-URL: Issues, https://github.com/salim-studio/salearn/issues
12
+ Keywords: machine-learning,sklearn,data-science,database,eda,automl,time-series,nlp
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Classifier: Topic :: Database
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: numpy>=1.24
24
+ Requires-Dist: scipy>=1.10
25
+ Provides-Extra: speed
26
+ Requires-Dist: numba>=0.57; extra == "speed"
27
+ Provides-Extra: db
28
+ Requires-Dist: sqlalchemy>=2.0; extra == "db"
29
+ Requires-Dist: duckdb>=0.9; extra == "db"
30
+ Requires-Dist: pandas>=1.5; extra == "db"
31
+ Requires-Dist: pyarrow>=10; extra == "db"
32
+ Provides-Extra: eda
33
+ Requires-Dist: pandas>=1.5; extra == "eda"
34
+ Requires-Dist: matplotlib>=3.6; extra == "eda"
35
+ Provides-Extra: nlp
36
+ Requires-Dist: pandas>=1.5; extra == "nlp"
37
+ Provides-Extra: all
38
+ Requires-Dist: numba>=0.57; extra == "all"
39
+ Requires-Dist: scipy>=1.10; extra == "all"
40
+ Requires-Dist: pytest; extra == "all"
41
+ Requires-Dist: sqlalchemy>=2.0; extra == "all"
42
+ Requires-Dist: duckdb>=0.9; extra == "all"
43
+ Requires-Dist: pandas>=1.5; extra == "all"
44
+ Requires-Dist: pyarrow>=10; extra == "all"
45
+ Requires-Dist: matplotlib>=3.6; extra == "all"
46
+ Provides-Extra: test
47
+ Requires-Dist: pytest; extra == "test"
48
+ Requires-Dist: scikit-learn; extra == "test"
49
+ Requires-Dist: pandas; extra == "test"
50
+ Dynamic: license-file
51
+
52
+ <div align="center">
53
+
54
+ <img src="assets/banner.svg" alt="salearn banner" width="100%"/>
55
+
56
+ [![PyPI version](https://img.shields.io/pypi/v/salearn?color=10B981&label=PyPI)](https://pypi.org/project/salearn/)
57
+ [![Python](https://img.shields.io/badge/Python-3.9%2B-4F46E5?logo=python&logoColor=white)](https://www.python.org/)
58
+ [![License: MIT](https://img.shields.io/badge/License-MIT-0F172A)](LICENSE)
59
+ [![CI](https://img.shields.io/github/actions/workflow/status/salim-studio/salearn/ci.yml?label=CI)](https://github.com/salim-studio/salearn/actions)
60
+ [![Stars](https://img.shields.io/github/stars/salim-studio/salearn?style=social)](https://github.com/salim-studio/salearn)
61
+
62
+ **From SQL to serving — in one import.**
63
+
64
+ sklearn-compatible and fast (NumPy + optional Numba), with a built-in data stack:
65
+ databases · loading · EDA · cleaning · features · time-series · NLP · AutoML · explainability · model registry.
66
+
67
+ [Quickstart](#quickstart) · [Modules](#module-map) · [Benchmarks](#benchmarks) · [Roadmap](#roadmap) · [Contributing](CONTRIBUTING.md)
68
+
69
+ </div>
70
+
71
+ ---
72
+
73
+ ## Why salearn?
74
+
75
+ | You know (sklearn) | You get (salearn) | Speed / extra |
76
+ |---|---|---|
77
+ | `linear_model` | `salearn.linear_model` | Ridge Cholesky, Lasso-CD (Numba), L-BFGS Logistic |
78
+ | `tree` / `ensemble` | `salearn.tree` / `salearn.ensemble` | Vectorized CART, ThreadPool RF/ExtraTrees, GBM, Voting, Stacking |
79
+ | `neighbors` / `cluster` | `salearn.neighbors` / `salearn.cluster` | BLAS distances, Numba k-means++ |
80
+ | `svm` / `decomposition` / `metrics` / `model_selection` / `pipeline` | same names | Pegasos linear SVM, Nyström approx, full metrics + CV/grid/random search |
81
+ | — | `salearn.db` | SQLite / DuckDB / Postgres / MySQL + train straight from SQL |
82
+ | — | `salearn.io` `salearn.eda` `salearn.clean` `salearn.features` `salearn.viz` | CSV/Parquet/JSON/URL loading, 1-line profiling + HTML report, dedup/outlier cleaning, target/date encoders |
83
+ | — | `salearn.timeseries` `salearn.text` `salearn.automl` `salearn.explain` `salearn.persist` | AR/ETS forecasters, EN+AR TF-IDF, budgeted AutoML, permutation importance, versioned model registry |
84
+
85
+ > Formerly developed as `sslearn`. The package was renamed to **salearn** for its 1.0 launch — same API, bigger scope.
86
+
87
+ ## Install
88
+
89
+ ```bash
90
+ pip install salearn
91
+ pip install "salearn[speed]" # numba — JIT for hot loops
92
+ pip install "salearn[db]" # sqlalchemy + duckdb + pandas + pyarrow
93
+ pip install "salearn[eda]" # pandas + matplotlib
94
+ pip install "salearn[all]" # everything
95
+ ```
96
+
97
+ Requires Python 3.9+, `numpy`, `scipy`. Everything else is optional.
98
+
99
+ ## Quickstart
100
+
101
+ **1. Drop-in sklearn replacement**
102
+
103
+ ```python
104
+ # from sklearn.ensemble import RandomForestClassifier
105
+ from salearn.ensemble import RandomForestClassifier
106
+ from salearn.preprocessing import StandardScaler
107
+ from salearn.pipeline import make_pipeline
108
+
109
+ pipe = make_pipeline(StandardScaler(), RandomForestClassifier(n_estimators=200, n_jobs=-1))
110
+ pipe.fit(X_train, y_train)
111
+ print(pipe.score(X_test, y_test))
112
+ ```
113
+
114
+ **2. Databases — train straight from SQL**
115
+
116
+ ```python
117
+ from salearn.db import Database
118
+
119
+ db = Database.sqlite_file("shop.db")
120
+ db.to_sql("sales", df=df, if_exists="replace")
121
+ X, y, feats = db.load_X_y("SELECT * FROM sales WHERE amount > 0", target="churn")
122
+ model = db.train_sql("SELECT * FROM sales", target="churn")
123
+ ```
124
+
125
+ **3. Load → profile → clean in three lines**
126
+
127
+ ```python
128
+ from salearn import io, eda
129
+ from salearn.clean import DataCleaner
130
+
131
+ df = io.load_csv("data.csv") # or load_parquet / load_url(...)
132
+ eda.profile(df, html_path="report.html") # shape, missing, outliers, duplicates
133
+ df = DataCleaner(outlier_clip="iqr").fit_transform(df)
134
+ ```
135
+
136
+ **4. Features → AutoML → explain → ship**
137
+
138
+ ```python
139
+ from salearn.features import auto_featurize
140
+ from salearn.automl import find_best
141
+ from salearn.explain import model_report
142
+ from salearn.persist import save_model
143
+
144
+ X, y, names = auto_featurize(df, target="churn", date_cols=["signup_date"])
145
+ best, board = find_best(X, y, time_budget=15)
146
+ print(board[0], model_report(best, X, y, names))
147
+ save_model(best, "churn.ssl")
148
+ ```
149
+
150
+ **5. Time-series (NumPy only) and multilingual NLP**
151
+
152
+ ```python
153
+ from salearn.timeseries import ARForecaster, temporal_split
154
+ train, test = temporal_split(sales, test_size=30)
155
+ forecast = ARForecaster(lags=14).fit(train).predict(30)
156
+
157
+ from salearn.text import TextClassifier # English + Arabic out of the box
158
+ clf = TextClassifier().fit(["great movie", "فيلم رائع", "boring", "ممل"], [1, 1, 0, 0])
159
+ clf.predict(["absolutely great", "رائع جدا"])
160
+ ```
161
+
162
+ ## Module map
163
+
164
+ ```
165
+ salearn/
166
+ ├── linear_model tree ensemble neighbors naive_bayes svm cluster # classic ML (sklearn API)
167
+ ├── decomposition metrics model_selection pipeline preprocessing # ...faster (BLAS / Numba / threads)
168
+ ├── impute feature_selection mixture neural_network extras datasets calibration
169
+ ├── db.py # Database (sqlite/duckdb/postgres/mysql), QueryBuilder, train_sql
170
+ ├── io.py # csv/parquet/json/excel/url, chunked reading, to_X_y
171
+ ├── eda.py # profile / missing / outliers / correlation / HTML report
172
+ ├── clean.py # DataCleaner transformer
173
+ ├── features.py # DateFeaturizer, TargetEncoder, FrequencyEncoder, auto_featurize
174
+ ├── timeseries.py # Naive / Seasonal / MA / ETS / AR + walk-forward CV
175
+ ├── text.py # clean_text, Count/TfidfVectorizer, TextClassifier
176
+ ├── automl.py # find_best + leaderboard
177
+ ├── explain.py # permutation importance, partial dependence, model_report
178
+ ├── persist.py # save_model / load_model / ModelRegistry
179
+ └── viz.py # confusion / residuals / importance (matplotlib optional)
180
+ ```
181
+
182
+ ```mermaid
183
+ flowchart LR
184
+ DB[("SQL databases")] --> IO["salearn.io"]
185
+ IO --> EDA["salearn.eda"]
186
+ EDA --> CLEAN["clean + features"]
187
+ CLEAN --> ML["classic ML"]
188
+ CLEAN --> AUTO["salearn.automl"]
189
+ ML --> EXP["salearn.explain"]
190
+ AUTO --> EXP
191
+ EXP --> REG[("model registry")]
192
+ ```
193
+
194
+ ## Benchmarks
195
+
196
+ ```bash
197
+ python bench/bench.py
198
+ python -m pytest -q # 12 tests, ~20s
199
+ python examples_fullstack.py
200
+ ```
201
+
202
+ Vectorized NumPy paths (BLAS pairwise distances, Cholesky Ridge, `lstsq`), optional Numba JIT
203
+ for KMeans/KNN/SGD/Lasso-CD/Pegasos, and ThreadPool-parallel forests.
204
+
205
+ ## Roadmap
206
+
207
+ - [ ] PyPI release + docs site
208
+ - [ ] Deep-learning bridge (`torch`/`onnx` export)
209
+ - [ ] Streaming / incremental estimators
210
+ - [ ] More connectors (BigQuery, Snowflake via SQLAlchemy)
211
+ - [ ] Multilingual docs (Arabic, French)
212
+
213
+ Vote with a ⭐ or open an issue — it shapes priorities.
214
+
215
+ ## Contributing
216
+
217
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and PRs welcome.
218
+
219
+ ## License
220
+
221
+ MIT — see [LICENSE](LICENSE). Changelog in [CHANGELOG.md](CHANGELOG.md).
@@ -0,0 +1,170 @@
1
+ <div align="center">
2
+
3
+ <img src="assets/banner.svg" alt="salearn banner" width="100%"/>
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/salearn?color=10B981&label=PyPI)](https://pypi.org/project/salearn/)
6
+ [![Python](https://img.shields.io/badge/Python-3.9%2B-4F46E5?logo=python&logoColor=white)](https://www.python.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-0F172A)](LICENSE)
8
+ [![CI](https://img.shields.io/github/actions/workflow/status/salim-studio/salearn/ci.yml?label=CI)](https://github.com/salim-studio/salearn/actions)
9
+ [![Stars](https://img.shields.io/github/stars/salim-studio/salearn?style=social)](https://github.com/salim-studio/salearn)
10
+
11
+ **From SQL to serving — in one import.**
12
+
13
+ sklearn-compatible and fast (NumPy + optional Numba), with a built-in data stack:
14
+ databases · loading · EDA · cleaning · features · time-series · NLP · AutoML · explainability · model registry.
15
+
16
+ [Quickstart](#quickstart) · [Modules](#module-map) · [Benchmarks](#benchmarks) · [Roadmap](#roadmap) · [Contributing](CONTRIBUTING.md)
17
+
18
+ </div>
19
+
20
+ ---
21
+
22
+ ## Why salearn?
23
+
24
+ | You know (sklearn) | You get (salearn) | Speed / extra |
25
+ |---|---|---|
26
+ | `linear_model` | `salearn.linear_model` | Ridge Cholesky, Lasso-CD (Numba), L-BFGS Logistic |
27
+ | `tree` / `ensemble` | `salearn.tree` / `salearn.ensemble` | Vectorized CART, ThreadPool RF/ExtraTrees, GBM, Voting, Stacking |
28
+ | `neighbors` / `cluster` | `salearn.neighbors` / `salearn.cluster` | BLAS distances, Numba k-means++ |
29
+ | `svm` / `decomposition` / `metrics` / `model_selection` / `pipeline` | same names | Pegasos linear SVM, Nyström approx, full metrics + CV/grid/random search |
30
+ | — | `salearn.db` | SQLite / DuckDB / Postgres / MySQL + train straight from SQL |
31
+ | — | `salearn.io` `salearn.eda` `salearn.clean` `salearn.features` `salearn.viz` | CSV/Parquet/JSON/URL loading, 1-line profiling + HTML report, dedup/outlier cleaning, target/date encoders |
32
+ | — | `salearn.timeseries` `salearn.text` `salearn.automl` `salearn.explain` `salearn.persist` | AR/ETS forecasters, EN+AR TF-IDF, budgeted AutoML, permutation importance, versioned model registry |
33
+
34
+ > Formerly developed as `sslearn`. The package was renamed to **salearn** for its 1.0 launch — same API, bigger scope.
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ pip install salearn
40
+ pip install "salearn[speed]" # numba — JIT for hot loops
41
+ pip install "salearn[db]" # sqlalchemy + duckdb + pandas + pyarrow
42
+ pip install "salearn[eda]" # pandas + matplotlib
43
+ pip install "salearn[all]" # everything
44
+ ```
45
+
46
+ Requires Python 3.9+, `numpy`, `scipy`. Everything else is optional.
47
+
48
+ ## Quickstart
49
+
50
+ **1. Drop-in sklearn replacement**
51
+
52
+ ```python
53
+ # from sklearn.ensemble import RandomForestClassifier
54
+ from salearn.ensemble import RandomForestClassifier
55
+ from salearn.preprocessing import StandardScaler
56
+ from salearn.pipeline import make_pipeline
57
+
58
+ pipe = make_pipeline(StandardScaler(), RandomForestClassifier(n_estimators=200, n_jobs=-1))
59
+ pipe.fit(X_train, y_train)
60
+ print(pipe.score(X_test, y_test))
61
+ ```
62
+
63
+ **2. Databases — train straight from SQL**
64
+
65
+ ```python
66
+ from salearn.db import Database
67
+
68
+ db = Database.sqlite_file("shop.db")
69
+ db.to_sql("sales", df=df, if_exists="replace")
70
+ X, y, feats = db.load_X_y("SELECT * FROM sales WHERE amount > 0", target="churn")
71
+ model = db.train_sql("SELECT * FROM sales", target="churn")
72
+ ```
73
+
74
+ **3. Load → profile → clean in three lines**
75
+
76
+ ```python
77
+ from salearn import io, eda
78
+ from salearn.clean import DataCleaner
79
+
80
+ df = io.load_csv("data.csv") # or load_parquet / load_url(...)
81
+ eda.profile(df, html_path="report.html") # shape, missing, outliers, duplicates
82
+ df = DataCleaner(outlier_clip="iqr").fit_transform(df)
83
+ ```
84
+
85
+ **4. Features → AutoML → explain → ship**
86
+
87
+ ```python
88
+ from salearn.features import auto_featurize
89
+ from salearn.automl import find_best
90
+ from salearn.explain import model_report
91
+ from salearn.persist import save_model
92
+
93
+ X, y, names = auto_featurize(df, target="churn", date_cols=["signup_date"])
94
+ best, board = find_best(X, y, time_budget=15)
95
+ print(board[0], model_report(best, X, y, names))
96
+ save_model(best, "churn.ssl")
97
+ ```
98
+
99
+ **5. Time-series (NumPy only) and multilingual NLP**
100
+
101
+ ```python
102
+ from salearn.timeseries import ARForecaster, temporal_split
103
+ train, test = temporal_split(sales, test_size=30)
104
+ forecast = ARForecaster(lags=14).fit(train).predict(30)
105
+
106
+ from salearn.text import TextClassifier # English + Arabic out of the box
107
+ clf = TextClassifier().fit(["great movie", "فيلم رائع", "boring", "ممل"], [1, 1, 0, 0])
108
+ clf.predict(["absolutely great", "رائع جدا"])
109
+ ```
110
+
111
+ ## Module map
112
+
113
+ ```
114
+ salearn/
115
+ ├── linear_model tree ensemble neighbors naive_bayes svm cluster # classic ML (sklearn API)
116
+ ├── decomposition metrics model_selection pipeline preprocessing # ...faster (BLAS / Numba / threads)
117
+ ├── impute feature_selection mixture neural_network extras datasets calibration
118
+ ├── db.py # Database (sqlite/duckdb/postgres/mysql), QueryBuilder, train_sql
119
+ ├── io.py # csv/parquet/json/excel/url, chunked reading, to_X_y
120
+ ├── eda.py # profile / missing / outliers / correlation / HTML report
121
+ ├── clean.py # DataCleaner transformer
122
+ ├── features.py # DateFeaturizer, TargetEncoder, FrequencyEncoder, auto_featurize
123
+ ├── timeseries.py # Naive / Seasonal / MA / ETS / AR + walk-forward CV
124
+ ├── text.py # clean_text, Count/TfidfVectorizer, TextClassifier
125
+ ├── automl.py # find_best + leaderboard
126
+ ├── explain.py # permutation importance, partial dependence, model_report
127
+ ├── persist.py # save_model / load_model / ModelRegistry
128
+ └── viz.py # confusion / residuals / importance (matplotlib optional)
129
+ ```
130
+
131
+ ```mermaid
132
+ flowchart LR
133
+ DB[("SQL databases")] --> IO["salearn.io"]
134
+ IO --> EDA["salearn.eda"]
135
+ EDA --> CLEAN["clean + features"]
136
+ CLEAN --> ML["classic ML"]
137
+ CLEAN --> AUTO["salearn.automl"]
138
+ ML --> EXP["salearn.explain"]
139
+ AUTO --> EXP
140
+ EXP --> REG[("model registry")]
141
+ ```
142
+
143
+ ## Benchmarks
144
+
145
+ ```bash
146
+ python bench/bench.py
147
+ python -m pytest -q # 12 tests, ~20s
148
+ python examples_fullstack.py
149
+ ```
150
+
151
+ Vectorized NumPy paths (BLAS pairwise distances, Cholesky Ridge, `lstsq`), optional Numba JIT
152
+ for KMeans/KNN/SGD/Lasso-CD/Pegasos, and ThreadPool-parallel forests.
153
+
154
+ ## Roadmap
155
+
156
+ - [ ] PyPI release + docs site
157
+ - [ ] Deep-learning bridge (`torch`/`onnx` export)
158
+ - [ ] Streaming / incremental estimators
159
+ - [ ] More connectors (BigQuery, Snowflake via SQLAlchemy)
160
+ - [ ] Multilingual docs (Arabic, French)
161
+
162
+ Vote with a ⭐ or open an issue — it shapes priorities.
163
+
164
+ ## Contributing
165
+
166
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and PRs welcome.
167
+
168
+ ## License
169
+
170
+ MIT — see [LICENSE](LICENSE). Changelog in [CHANGELOG.md](CHANGELOG.md).
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "salearn"
7
+ version = "1.0.0"
8
+ description = "salearn — sklearn-compatible ML plus databases, EDA, AutoML, time-series and NLP in one import"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "salim-studio" }]
13
+ maintainers = [{ name = "salim-studio" }]
14
+ dependencies = [
15
+ "numpy>=1.24",
16
+ "scipy>=1.10",
17
+ ]
18
+ keywords = ["machine-learning", "sklearn", "data-science", "database", "eda", "automl", "time-series", "nlp"]
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Intended Audience :: Developers",
22
+ "Intended Audience :: Science/Research",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Programming Language :: Python :: 3",
25
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
26
+ "Topic :: Database",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/salim-studio/salearn"
31
+ Documentation = "https://github.com/salim-studio/salearn#readme"
32
+ Repository = "https://github.com/salim-studio/salearn"
33
+ Issues = "https://github.com/salim-studio/salearn/issues"
34
+
35
+ [project.optional-dependencies]
36
+ speed = ["numba>=0.57"]
37
+ db = ["sqlalchemy>=2.0", "duckdb>=0.9", "pandas>=1.5", "pyarrow>=10"]
38
+ eda = ["pandas>=1.5", "matplotlib>=3.6"]
39
+ nlp = ["pandas>=1.5"]
40
+ all = ["numba>=0.57", "scipy>=1.10", "pytest", "sqlalchemy>=2.0", "duckdb>=0.9", "pandas>=1.5", "pyarrow>=10", "matplotlib>=3.6"]
41
+ test = ["pytest", "scikit-learn", "pandas"]
42
+
43
+ [tool.setuptools.packages.find]
44
+ where = ["."]
45
+ include = ["salearn*"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
@@ -0,0 +1,49 @@
1
+ """salearn — from SQL to serving in one import.
2
+
3
+ A sklearn-compatible, faster ML library (NumPy + optional Numba) with a
4
+ built-in data stack: databases, loading, EDA, cleaning, feature engineering,
5
+ time-series forecasting, NLP, AutoML, explainability and model registry.
6
+
7
+ # sklearn-style, drop-in
8
+ from salearn.ensemble import RandomForestClassifier
9
+ # full stack
10
+ from salearn.db import Database
11
+ from salearn import eda, io, clean, features, timeseries, text, automl, explain, persist, viz
12
+ """
13
+ from __future__ import annotations
14
+
15
+ __version__ = "1.0.0"
16
+
17
+ from . import (
18
+ base, utils, exceptions, preprocessing, impute, linear_model, tree,
19
+ ensemble, neighbors, naive_bayes, svm, cluster, decomposition, metrics,
20
+ model_selection, pipeline, feature_selection, mixture, neural_network,
21
+ extras, datasets, calibration,
22
+ db, io, eda, clean, features, timeseries, text, automl, explain,
23
+ persist, viz,
24
+ )
25
+ from .base import BaseEstimator, ClassifierMixin, RegressorMixin, TransformerMixin, ClusterMixin, clone, is_classifier, is_regressor
26
+ from .pipeline import Pipeline, FeatureUnion, make_pipeline, make_union
27
+ from .model_selection import (
28
+ train_test_split, KFold, StratifiedKFold, ShuffleSplit, LeaveOneOut,
29
+ cross_val_score, cross_validate, cross_val_predict, GridSearchCV,
30
+ RandomizedSearchCV, learning_curve, validation_curve,
31
+ )
32
+ from . import metrics as metrics_module
33
+
34
+ __all__ = [
35
+ "__version__",
36
+ "base", "utils", "exceptions", "preprocessing", "impute", "linear_model",
37
+ "tree", "ensemble", "neighbors", "naive_bayes", "svm", "cluster",
38
+ "decomposition", "metrics", "model_selection", "pipeline",
39
+ "feature_selection", "mixture", "neural_network", "extras", "datasets",
40
+ "calibration",
41
+ "db", "io", "eda", "clean", "features", "timeseries", "text",
42
+ "automl", "explain", "persist", "viz",
43
+ "BaseEstimator", "ClassifierMixin", "RegressorMixin", "TransformerMixin",
44
+ "ClusterMixin", "clone", "is_classifier", "is_regressor",
45
+ "Pipeline", "FeatureUnion", "make_pipeline", "make_union",
46
+ "train_test_split", "KFold", "StratifiedKFold", "ShuffleSplit",
47
+ "LeaveOneOut", "cross_val_score", "cross_validate", "cross_val_predict",
48
+ "GridSearchCV", "RandomizedSearchCV", "learning_curve", "validation_curve",
49
+ ]
@@ -0,0 +1,34 @@
1
+ """salearn._numba — optional Numba acceleration dispatcher.
2
+
3
+ If numba is installed we use njit(parallel/fastmath) for hot loops.
4
+ Otherwise pure-NumPy fallbacks are used so salearn works everywhere.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ try:
9
+ from numba import njit, prange # type: ignore
10
+ HAS_NUMBA = True
11
+ except Exception: # pragma: no cover
12
+ HAS_NUMBA = False
13
+
14
+ def njit(*a, **k):
15
+ def deco(f):
16
+ return f
17
+ if a and callable(a[0]) and len(a) == 1 and not k:
18
+ return a[0]
19
+ return deco
20
+
21
+ def prange(*a):
22
+ return range(*a)
23
+
24
+
25
+ def jit(nopython=True, cache=True, fastmath=True, parallel=False, **kw):
26
+ """Decorator: njit when numba exists, identity otherwise."""
27
+ if HAS_NUMBA:
28
+ from numba import njit as _njit
29
+ def deco(f):
30
+ return _njit(nopython=nopython, cache=cache, fastmath=fastmath, parallel=parallel, **kw)(f)
31
+ return deco
32
+ def deco(f):
33
+ return f
34
+ return deco
@@ -0,0 +1,104 @@
1
+ """salearn.automl — 5-line AutoML for developers & analysts.
2
+
3
+ from salearn.automl import find_best, leaderboard
4
+ best, report = find_best(X, y, task="auto", time_budget=10) # seconds-ish
5
+ print(report)
6
+
7
+ - tries a smart portfolio (logistic/ridge/RF/ET/GBM/KNN/NB/MLP...) with CV
8
+ - task auto-detect (classification vs regression)
9
+ - deterministic, no new deps, respects time_budget loosely
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import time
14
+ import numpy as np
15
+ from .base import clone
16
+
17
+
18
+ def _detect_task(y) -> str:
19
+ y = np.asarray(y)
20
+ if y.dtype.kind in "OUS" or len(np.unique(y)) <= 20 and y.dtype.kind in "iu":
21
+ # heuristic: few unique ints/strings -> classification
22
+ if y.dtype.kind in "OUS" or len(np.unique(y)) <= max(10, len(y) * 0.05):
23
+ return "classification"
24
+ return "regression"
25
+
26
+
27
+ def _portfolio(task: str, n: int, p: int):
28
+ if task == "classification":
29
+ from .linear_model import LogisticRegression
30
+ from .tree import DecisionTreeClassifier
31
+ from .ensemble import RandomForestClassifier, ExtraTreesClassifier, GradientBoostingClassifier, HistGradientBoostingClassifier
32
+ from .neighbors import KNeighborsClassifier
33
+ from .naive_bayes import GaussianNB
34
+ from .neural_network import MLPClassifier
35
+ ests = [
36
+ ("logreg", LogisticRegression(max_iter=200)),
37
+ ("tree", DecisionTreeClassifier()),
38
+ ("rf", RandomForestClassifier(n_estimators=100, n_jobs=-1)),
39
+ ("et", ExtraTreesClassifier(n_estimators=100, n_jobs=-1)),
40
+ ("knn", KNeighborsClassifier(n_neighbors=min(7, max(1, n - 1)))),
41
+ ("gnb", GaussianNB()),
42
+ ("mlp", MLPClassifier(hidden_layer_sizes=(64,), max_iter=200)),
43
+ ]
44
+ if n < 5000:
45
+ ests.append(("gbm", GradientBoostingClassifier(n_estimators=100)))
46
+ ests.append(("hgb", HistGradientBoostingClassifier(max_iter=100)))
47
+ return ests
48
+ from .linear_model import Ridge, Lasso, ElasticNet, LinearRegression
49
+ from .tree import DecisionTreeRegressor
50
+ from .ensemble import RandomForestRegressor, ExtraTreesRegressor, GradientBoostingRegressor, HistGradientBoostingRegressor
51
+ from .neighbors import KNeighborsRegressor
52
+ from .neural_network import MLPRegressor
53
+ ests = [
54
+ ("ridge", Ridge()),
55
+ ("lasso", Lasso(alpha=0.01)),
56
+ ("tree", DecisionTreeRegressor()),
57
+ ("rf", RandomForestRegressor(n_estimators=100, n_jobs=-1)),
58
+ ("et", ExtraTreesRegressor(n_estimators=100, n_jobs=-1)),
59
+ ("knn", KNeighborsRegressor(n_neighbors=min(7, max(1, n - 1)))),
60
+ ("mlp", MLPRegressor(hidden_layer_sizes=(64,), max_iter=200)),
61
+ ]
62
+ if n < 5000:
63
+ ests.append(("gbm", GradientBoostingRegressor(n_estimators=100)))
64
+ return ests
65
+
66
+
67
+ def leaderboard(X, y, task="auto", cv=3, scoring=None, time_budget=30, verbose=False):
68
+ """Evaluate portfolio with CV. Returns ranked list of dicts."""
69
+ from .model_selection import cross_val_score
70
+ X = np.asarray(X)
71
+ y = np.asarray(y)
72
+ task = _detect_task(y) if task == "auto" else task
73
+ rows = []
74
+ t0 = time.time()
75
+ for name, est in _portfolio(task, len(X), X.shape[1] if X.ndim > 1 else 1):
76
+ if time.time() - t0 > time_budget:
77
+ break
78
+ try:
79
+ t1 = time.time()
80
+ s = cross_val_score(clone(est), X, y, cv=cv, scoring=scoring)
81
+ rows.append({"model": name, "estimator": clone(est),
82
+ "mean": float(np.mean(s)), "std": float(np.std(s)),
83
+ "fit_time": round(time.time() - t1, 3)})
84
+ if verbose:
85
+ print(f"{name}: {np.mean(s):.4f}±{np.std(s):.4f}")
86
+ except Exception as e:
87
+ if verbose:
88
+ print(f"{name} failed: {e}")
89
+ rows.sort(key=lambda r: -r["mean"])
90
+ return rows
91
+
92
+
93
+ def find_best(X, y, task="auto", cv=3, scoring=None, time_budget=30, refit=True, verbose=False):
94
+ """Return (best_estimator_fitted, leaderboard_rows)."""
95
+ rows = leaderboard(X, y, task=task, cv=cv, scoring=scoring, time_budget=time_budget, verbose=verbose)
96
+ if not rows:
97
+ raise RuntimeError("All AutoML candidates failed")
98
+ best = rows[0]["estimator"]
99
+ if refit:
100
+ best.fit(np.asarray(X), np.asarray(y))
101
+ return best, rows
102
+
103
+
104
+ __all__ = ["find_best", "leaderboard"]