baxter-ts 0.1.1__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 (39) hide show
  1. baxter_ts-0.1.1/LICENSE +21 -0
  2. baxter_ts-0.1.1/PKG-INFO +479 -0
  3. baxter_ts-0.1.1/README.md +440 -0
  4. baxter_ts-0.1.1/baxter_ts/__init__.py +19 -0
  5. baxter_ts-0.1.1/baxter_ts/anomaly/__init__.py +3 -0
  6. baxter_ts-0.1.1/baxter_ts/anomaly/detector.py +118 -0
  7. baxter_ts-0.1.1/baxter_ts/bax/__init__.py +4 -0
  8. baxter_ts-0.1.1/baxter_ts/bax/explainer.py +58 -0
  9. baxter_ts-0.1.1/baxter_ts/bax/narrator.py +128 -0
  10. baxter_ts-0.1.1/baxter_ts/core.py +483 -0
  11. baxter_ts-0.1.1/baxter_ts/models/__init__.py +6 -0
  12. baxter_ts-0.1.1/baxter_ts/models/base_model.py +87 -0
  13. baxter_ts-0.1.1/baxter_ts/models/catboost_model.py +23 -0
  14. baxter_ts-0.1.1/baxter_ts/models/rf_model.py +21 -0
  15. baxter_ts-0.1.1/baxter_ts/models/selector.py +78 -0
  16. baxter_ts-0.1.1/baxter_ts/models/xgb_model.py +26 -0
  17. baxter_ts-0.1.1/baxter_ts/preprocessing/__init__.py +19 -0
  18. baxter_ts-0.1.1/baxter_ts/preprocessing/column_handler.py +135 -0
  19. baxter_ts-0.1.1/baxter_ts/preprocessing/feature_eng.py +142 -0
  20. baxter_ts-0.1.1/baxter_ts/preprocessing/imputer.py +78 -0
  21. baxter_ts-0.1.1/baxter_ts/preprocessing/outlier.py +87 -0
  22. baxter_ts-0.1.1/baxter_ts/preprocessing/scaler.py +62 -0
  23. baxter_ts-0.1.1/baxter_ts/preprocessing/splitter.py +48 -0
  24. baxter_ts-0.1.1/baxter_ts/preprocessing/transformer.py +92 -0
  25. baxter_ts-0.1.1/baxter_ts/preprocessing/validator.py +120 -0
  26. baxter_ts-0.1.1/baxter_ts/report/__init__.py +3 -0
  27. baxter_ts-0.1.1/baxter_ts/report/generator.py +342 -0
  28. baxter_ts-0.1.1/baxter_ts/visualization/__init__.py +3 -0
  29. baxter_ts-0.1.1/baxter_ts/visualization/plotter.py +290 -0
  30. baxter_ts-0.1.1/baxter_ts.egg-info/PKG-INFO +479 -0
  31. baxter_ts-0.1.1/baxter_ts.egg-info/SOURCES.txt +37 -0
  32. baxter_ts-0.1.1/baxter_ts.egg-info/dependency_links.txt +1 -0
  33. baxter_ts-0.1.1/baxter_ts.egg-info/requires.txt +19 -0
  34. baxter_ts-0.1.1/baxter_ts.egg-info/top_level.txt +1 -0
  35. baxter_ts-0.1.1/pyproject.toml +61 -0
  36. baxter_ts-0.1.1/setup.cfg +4 -0
  37. baxter_ts-0.1.1/tests/test_all_datasets.py +827 -0
  38. baxter_ts-0.1.1/tests/test_baxter.py +387 -0
  39. baxter_ts-0.1.1/tests/test_comprehensive.py +737 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 baxter-ts contributors
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.
@@ -0,0 +1,479 @@
1
+ Metadata-Version: 2.4
2
+ Name: baxter-ts
3
+ Version: 0.1.1
4
+ Summary: AutoML time series library with BAX behavioural explanation, anomaly detection and visualisation
5
+ Author-email: Pooja Patil <pooja.patil2509@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/PoojaPatil2509/baxter-ts
8
+ Project-URL: Repository, https://github.com/PoojaPatil2509/baxter-ts
9
+ Project-URL: Issues, https://github.com/PoojaPatil2509/baxter-ts/issues
10
+ Keywords: time-series,automl,forecasting,anomaly-detection,explainability,shap
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Operating System :: OS Independent
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: pandas>=2.0
21
+ Requires-Dist: numpy>=1.25
22
+ Requires-Dist: scikit-learn>=1.3
23
+ Requires-Dist: xgboost>=2.0
24
+ Requires-Dist: catboost>=1.2
25
+ Requires-Dist: shap>=0.43
26
+ Requires-Dist: plotly>=5.18
27
+ Requires-Dist: statsmodels>=0.14
28
+ Requires-Dist: scipy>=1.11
29
+ Requires-Dist: jinja2>=3.1
30
+ Requires-Dist: kaleido>=0.2
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest; extra == "dev"
33
+ Requires-Dist: pytest-cov; extra == "dev"
34
+ Requires-Dist: black; extra == "dev"
35
+ Requires-Dist: ruff; extra == "dev"
36
+ Requires-Dist: twine; extra == "dev"
37
+ Requires-Dist: build; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # baxter-ts
41
+
42
+ > AutoML time series library with BAX (Behavioural Analysis & eXplanation)
43
+
44
+ [![PyPI version](https://img.shields.io/pypi/v/baxter-ts)](https://pypi.org/project/baxter-ts/)
45
+ [![Python](https://img.shields.io/pypi/pyversions/baxter-ts)](https://pypi.org/project/baxter-ts/)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
47
+ [![TestPyPI](https://img.shields.io/badge/TestPyPI-passing-brightgreen)](https://test.pypi.org/project/baxter-ts/)
48
+
49
+ **baxter-ts** is a one-call AutoML pipeline for any time series data. It automatically preprocesses your data, trains and compares three models, selects the best one, explains every prediction in plain English using SHAP (the BAX layer), detects anomalies, and produces a fully interactive offline HTML report — all from a single `fit()` call.
50
+
51
+ No manual preprocessing. No model tuning. No explainability code. Just results.
52
+
53
+ ---
54
+
55
+ ## Contents
56
+
57
+ - [Why baxter-ts](#why-baxter-ts)
58
+ - [Installation](#installation)
59
+ - [Quickstart](#quickstart)
60
+ - [How it works](#how-it-works)
61
+ - [API reference](#api-reference)
62
+ - [Supported data types](#supported-data-types)
63
+ - [Examples](#examples)
64
+ - [Report output](#report-output)
65
+ - [Project structure](#project-structure)
66
+ - [Contributing](#contributing)
67
+ - [License](#license)
68
+
69
+ ---
70
+
71
+ ## Why baxter-ts
72
+
73
+ | Problem today | What baxter-ts solves |
74
+ |---|---|
75
+ | 60–70% of project time spent on preprocessing | 10 preprocessing steps run automatically |
76
+ | Manually training and comparing multiple models | AutoML competition — winner selected automatically |
77
+ | Client asks "why did the model predict this?" | BAX generates a plain-English SHAP narrative |
78
+ | Anomalies discovered only after damage is done | Every prediction carries an anomaly score |
79
+ | Rebuilding the same pipeline for every new dataset | One API works on stock prices, IoT, sales, energy — any time series |
80
+ | No audit trail for model decisions | Full preprocessing and model log exported to HTML |
81
+
82
+ ---
83
+
84
+ ## Installation
85
+
86
+ ```bash
87
+ pip install baxter-ts
88
+ ```
89
+
90
+ Requires Python 3.9 or higher.
91
+
92
+ ---
93
+
94
+ ## Quickstart
95
+
96
+ ```python
97
+ from baxter_ts import BAXModel
98
+ import pandas as pd
99
+
100
+ df = pd.read_csv("your_data.csv")
101
+
102
+ model = BAXModel()
103
+ model.fit(df, target_col="sales", date_col="date")
104
+
105
+ model.predict(steps=30) # 30-step future forecast
106
+ model.explain() # BAX plain-English narrative
107
+ model.anomalies() # anomaly DataFrame
108
+ model.visualize() # 7 interactive Plotly charts
109
+ model.report("my_report") # saves my_report.html — open in any browser
110
+ ```
111
+
112
+ ---
113
+
114
+ ## How it works
115
+
116
+ Every `fit()` call runs a 10-step pipeline automatically:
117
+
118
+ ```
119
+ Raw data
120
+
121
+ ├── Step 1 Datetime parsing auto-detects date column, parses any format
122
+ ├── Step 2 Frequency inference detects minutely / hourly / daily / weekly / monthly
123
+ ├── Step 3 Missing value fill auto selects ffill / interpolation / seasonal mean / KNN
124
+ ├── Step 4 Outlier handling auto selects Z-score / IQR / Isolation Forest → cap or flag
125
+ ├── Step 5 Stationarity ADF + KPSS test, applies differencing or log transform
126
+ ├── Step 6 STL decomposition extracts trend, seasonal, residual as model features
127
+ ├── Step 7 Scaling auto selects MinMax / Standard / Robust
128
+ ├── Step 8 Feature engineering lags, rolling stats, EWM, Fourier terms, calendar, holidays
129
+ ├── Step 9 Temporal split walk-forward CV, zero data leakage
130
+
131
+ ├── AutoML competition
132
+ │ ├── Random Forest
133
+ │ ├── XGBoost
134
+ │ └── CatBoost
135
+ │ → winner selected by composite MAE + RMSE + MAPE score
136
+
137
+ ├── BAX explanation SHAP values translated to plain English narrative
138
+ ├── Anomaly detection ensemble of Isolation Forest + Z-score + IQR on residuals
139
+ └── HTML report 7 interactive Plotly charts, metrics, audit trail — fully offline
140
+ ```
141
+
142
+ ---
143
+
144
+ ## API reference
145
+
146
+ ### `BAXModel`
147
+
148
+ ```python
149
+ BAXModel(
150
+ test_size = 0.2, # fraction of data held out for evaluation
151
+ n_cv_splits = 5, # number of walk-forward cross-validation folds
152
+ outlier_treatment = "cap", # "cap" (winsorise) or "flag" (add boolean column)
153
+ anomaly_method = "ensemble", # "ensemble" | "isolation_forest" | "zscore" | "iqr"
154
+ contamination = 0.05, # expected anomaly fraction for Isolation Forest
155
+ verbose = True, # print pipeline progress to console
156
+ )
157
+ ```
158
+
159
+ ---
160
+
161
+ ### `.fit(df, target_col, date_col=None)`
162
+
163
+ Runs the full preprocessing and AutoML pipeline.
164
+
165
+ | Parameter | Type | Description |
166
+ |---|---|---|
167
+ | `df` | `pd.DataFrame` | Raw time series data |
168
+ | `target_col` | `str` | Name of the column to forecast |
169
+ | `date_col` | `str` or `None` | Datetime column name. Auto-detected if not provided |
170
+
171
+ Returns `self` — supports method chaining.
172
+
173
+ ---
174
+
175
+ ### `.predict(steps=30) → pd.DataFrame`
176
+
177
+ Generates a future forecast for `steps` time periods ahead.
178
+
179
+ Returns a DataFrame indexed by future dates with a single `forecast` column.
180
+
181
+ ---
182
+
183
+ ### `.explain() → str`
184
+
185
+ Prints and returns the BAX behavioural narrative.
186
+
187
+ Plain-English description of which features drove the model's predictions and by how much, backed by SHAP (SHapley Additive eXplanations) values. Non-technical stakeholders can read this directly without any ML background.
188
+
189
+ ---
190
+
191
+ ### `.anomalies() → pd.DataFrame`
192
+
193
+ Runs anomaly detection on model residuals (actual minus predicted). Detecting anomalies on residuals — not raw values — catches unexpected deviations the model itself did not predict, which is far more useful than flagging obvious spikes.
194
+
195
+ Returns a DataFrame with columns:
196
+
197
+ | Column | Description |
198
+ |---|---|
199
+ | `actual` | True observed value |
200
+ | `predicted` | Model prediction |
201
+ | `residual` | Difference between actual and predicted |
202
+ | `anomaly_flag` | 1 = anomaly, 0 = normal |
203
+ | `severity` | 0 = normal, 1 = suspicious, 2 = anomaly |
204
+ | `severity_label` | `"normal"`, `"suspicious"`, or `"anomaly"` |
205
+
206
+ ---
207
+
208
+ ### `.scoreboard() → pd.DataFrame`
209
+
210
+ Returns the full AutoML competition results with MAE, RMSE, MAPE, R², CV scores, and composite score for all three candidate models.
211
+
212
+ ---
213
+
214
+ ### `.visualize(show=True) → dict`
215
+
216
+ Generates and optionally displays all 7 interactive Plotly charts. Returns a dictionary of figure objects for further customisation.
217
+
218
+ Charts included:
219
+
220
+ | Chart | What it shows |
221
+ |---|---|
222
+ | Forecast | Actual vs predicted on test set + future forecast line |
223
+ | Anomaly overlay | Flagged anomaly and suspicious points on the series |
224
+ | SHAP importance | Top features ranked by mean absolute SHAP value |
225
+ | Model scoreboard | MAE, RMSE, MAPE bars for all 3 models side by side |
226
+ | Residuals over time | Scatter plot coloured by anomaly severity |
227
+ | Residual distribution | Histogram showing error distribution shape |
228
+ | STL decomposition | Trend, seasonal, and residual component panels |
229
+
230
+ ---
231
+
232
+ ### `.report(output_path) → str`
233
+
234
+ Saves a fully self-contained HTML report to `output_path.html`.
235
+
236
+ The Plotly JS bundle (4.7 MB) is embedded inline inside the file — no internet connection is needed to open it. Works in Chrome, Firefox, Edge, and Safari. Includes all 7 charts, model metrics, BAX narrative, top anomaly timestamps, and a full preprocessing audit trail showing every transformation applied with its parameters.
237
+
238
+ ---
239
+
240
+ ### `.summary() → dict`
241
+
242
+ Returns a flat dictionary of all key results for programmatic access or logging.
243
+
244
+ ```python
245
+ model.summary()
246
+ # {
247
+ # "target_col": "sales",
248
+ # "frequency": "D",
249
+ # "best_model": "CatBoost",
250
+ # "test_mae": 0.1367,
251
+ # "test_rmse": 0.203,
252
+ # "test_mape": 70.9,
253
+ # "test_r2": 0.9523,
254
+ # "anomalies_found": 2,
255
+ # "shap_top_features": ["seasonal_component", "residual_component", "dayofweek"],
256
+ # "train_rows": 400,
257
+ # "test_rows": 100,
258
+ # }
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Supported data types
264
+
265
+ baxter-ts automatically detects the frequency of your data and adapts all preprocessing, lag generation, rolling windows, Fourier terms, and calendar features accordingly.
266
+
267
+ | Frequency | Typical use cases |
268
+ |---|---|
269
+ | Sub-minute (1 min) | IoT sensor streams, industrial equipment monitoring |
270
+ | Hourly | Energy consumption, weather stations, web traffic |
271
+ | Daily | Retail sales, stock prices, hospital admissions |
272
+ | Weekly | Demand forecasting, marketing performance |
273
+ | Monthly | Revenue, macroeconomic indicators, subscriptions |
274
+ | Quarterly | Financial reporting, EPS, budget cycles |
275
+ | Yearly | Annual statistics, long-range planning |
276
+
277
+ Data quality issues handled automatically:
278
+
279
+ - Missing values up to 30% of the series
280
+ - Extreme outlier spikes
281
+ - Unsorted or duplicate timestamps
282
+ - Sudden level shifts
283
+ - Non-stationary series (random walks, strong trends)
284
+ - Negative values and integer-only count data
285
+ - Mixed-frequency gaps (e.g. trading data with weekend gaps)
286
+
287
+ ---
288
+
289
+ ## Examples
290
+
291
+ ### Daily retail sales
292
+
293
+ ```python
294
+ from baxter_ts import BAXModel
295
+ import pandas as pd
296
+
297
+ df = pd.read_csv("sales.csv")
298
+
299
+ model = BAXModel()
300
+ model.fit(df, target_col="sales", date_col="date")
301
+
302
+ forecast = model.predict(steps=30)
303
+ print(forecast)
304
+
305
+ model.explain()
306
+ model.report("sales_report")
307
+ ```
308
+
309
+ ### Stock price forecasting
310
+
311
+ ```python
312
+ import yfinance as yf
313
+ from baxter_ts import BAXModel
314
+
315
+ df = yf.download("AAPL", start="2020-01-01", end="2024-01-01").reset_index()
316
+ df = df[["Date", "Close"]].rename(columns={"Date": "date", "Close": "price"})
317
+
318
+ model = BAXModel()
319
+ model.fit(df, target_col="price", date_col="date")
320
+ model.predict(steps=30)
321
+ model.report("aapl_forecast")
322
+ ```
323
+
324
+ ### IoT sensor anomaly detection
325
+
326
+ ```python
327
+ import pandas as pd
328
+ from baxter_ts import BAXModel
329
+
330
+ df = pd.read_csv("sensor_data.csv")
331
+
332
+ model = BAXModel(anomaly_method="ensemble", contamination=0.03)
333
+ model.fit(df, target_col="temperature", date_col="timestamp")
334
+
335
+ anom = model.anomalies()
336
+ print(anom[anom["severity_label"] == "anomaly"])
337
+ model.report("sensor_report")
338
+ ```
339
+
340
+ ### Hourly energy consumption
341
+
342
+ ```python
343
+ from baxter_ts import BAXModel
344
+ import pandas as pd
345
+
346
+ df = pd.read_csv("energy.csv")
347
+
348
+ model = BAXModel(test_size=0.15, n_cv_splits=3)
349
+ model.fit(df, target_col="kwh", date_col="datetime")
350
+
351
+ forecast = model.predict(steps=168) # 7 days ahead
352
+ model.explain()
353
+ model.visualize()
354
+ ```
355
+
356
+ ### Monthly revenue with full output
357
+
358
+ ```python
359
+ from baxter_ts import BAXModel
360
+ import pandas as pd
361
+
362
+ df = pd.read_csv("revenue.csv")
363
+
364
+ model = BAXModel(n_cv_splits=3, anomaly_method="zscore")
365
+ model.fit(df, target_col="revenue", date_col="month")
366
+
367
+ forecast = model.predict(steps=12)
368
+ anomalies = model.anomalies()
369
+ narrative = model.explain()
370
+ scoreboard = model.scoreboard()
371
+ summary = model.summary()
372
+
373
+ model.report("revenue_report")
374
+
375
+ print(f"Winner : {summary['best_model']}")
376
+ print(f"R² : {summary['test_r2']}")
377
+ print(f"Anomalies found: {summary['anomalies_found']}")
378
+ ```
379
+
380
+ ---
381
+
382
+ ## Report output
383
+
384
+ Every `.report()` call produces a single self-contained HTML file.
385
+
386
+ | Section | Contents |
387
+ |---|---|
388
+ | Model performance | MAE, RMSE, MAPE, R² metric cards |
389
+ | AutoML scoreboard | All 3 models with CV scores and composite rank |
390
+ | BAX explanation | Plain-English SHAP narrative with preprocessing summary |
391
+ | Anomaly summary | Total points, anomaly count, suspicious count, top timestamps |
392
+ | Preprocessing audit | Every step applied with method, parameters, and row counts |
393
+ | Forecast chart | Actual, predicted, and future forecast on one interactive plot |
394
+ | Anomaly overlay | Series with anomaly and suspicious points highlighted |
395
+ | SHAP importance | Horizontal bar chart of top features by influence percentage |
396
+ | Model scoreboard | Side-by-side MAE, RMSE, MAPE bars for all models |
397
+ | Residual analysis | Scatter over time + histogram — coloured by severity |
398
+ | STL decomposition | Trend, seasonal, and residual panels with hover tooltips |
399
+
400
+ The report has no external dependencies and works fully offline.
401
+
402
+ ---
403
+
404
+ ## Project structure
405
+
406
+ ```
407
+ baxter-ts/
408
+ ├── baxter_ts/
409
+ │ ├── core.py ← BAXModel — public API entry point
410
+ │ ├── preprocessing/
411
+ │ │ ├── validator.py ← datetime parsing and frequency inference
412
+ │ │ ├── imputer.py ← missing value imputation
413
+ │ │ ├── outlier.py ← outlier detection and treatment
414
+ │ │ ├── transformer.py ← stationarity testing and STL decomposition
415
+ │ │ ├── scaler.py ← feature scaling
416
+ │ │ ├── feature_eng.py ← lag, rolling, Fourier, and calendar features
417
+ │ │ ├── splitter.py ← temporal train/test split
418
+ │ │ └── column_handler.py ← categorical encoding and column cleanup
419
+ │ ├── models/
420
+ │ │ ├── base_model.py ← shared fit, score, and CV logic
421
+ │ │ ├── rf_model.py ← Random Forest
422
+ │ │ ├── xgb_model.py ← XGBoost
423
+ │ │ ├── catboost_model.py ← CatBoost
424
+ │ │ └── selector.py ← AutoML competition and winner selection
425
+ │ ├── bax/
426
+ │ │ ├── explainer.py ← SHAP TreeExplainer wrapper
427
+ │ │ └── narrator.py ← SHAP values to plain-English narrative
428
+ │ ├── anomaly/
429
+ │ │ └── detector.py ← ensemble anomaly detection on residuals
430
+ │ ├── visualization/
431
+ │ │ └── plotter.py ← 7 interactive Plotly charts
432
+ │ └── report/
433
+ │ └── generator.py ← self-contained HTML report generator
434
+ ├── tests/
435
+ │ ├── test_baxter.py ← 37 unit tests
436
+ │ ├── test_comprehensive.py ← 30 scenario tests across domains and frequencies
437
+ │ ├── test_all_datasets.py ← 10 real-world CSV dataset tests
438
+ │ └── datasets/ ← 10 test CSV files
439
+ ├── examples/
440
+ │ ├── quickstart.py ← runnable end-to-end example
441
+ │ └── demo_report.html ← sample output report
442
+ ├── pre_launch_check.py ← pre-publish verification script
443
+ ├── CONTRIBUTING.md ← development setup and release process
444
+ ├── pyproject.toml
445
+ ├── README.md
446
+ └── LICENSE
447
+ ```
448
+
449
+ ---
450
+
451
+ ## Contributing
452
+
453
+ Contributions, bug reports, and feature requests are welcome.
454
+
455
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, running the test suite, and the release process.
456
+
457
+ To report a bug or request a feature, open an issue at:
458
+ https://github.com/PoojaPatil2509/baxter-ts/issues
459
+
460
+ ---
461
+
462
+ ## License
463
+
464
+ MIT License. See [LICENSE](LICENSE) for details.
465
+
466
+
467
+ ---
468
+
469
+ ## Value for engineers
470
+
471
+ > "baxter-ts turns a 2-week ML pipeline build into a 4-line script,
472
+ > while giving you more explainability and auditability than most
473
+ > hand-crafted solutions ever achieve."
474
+
475
+ - **Data engineers**: ingest raw CSV → production-ready forecast in minutes
476
+ - **ML engineers**: skip boilerplate preprocessing, focus on domain logic
477
+ - **Data scientists**: SHAP explanations built in, no extra code
478
+ - **DevOps / MLOps**: full audit trail exportable for compliance and review
479
+ - **Non-ML engineers**: human-readable BAX narrative means no ML knowledge needed to understand why the model predicted what it predicted