Metadata-Version: 2.5
Name: autobooster-ml
Version: 0.1.0
Summary: Massive automatic feature engineering + model selection + ensembling for tabular, text, time and sequence data
Requires-Python: >=3.10
Requires-Dist: catboost>=1.2.5
Requires-Dist: gensim>=4.3
Requires-Dist: holidays>=0.50
Requires-Dist: joblib>=1.3
Requires-Dist: lightgbm>=4.3
Requires-Dist: numpy>=1.26
Requires-Dist: optuna>=3.6
Requires-Dist: pandas>=2.1
Requires-Dist: prophet>=1.1.5
Requires-Dist: pyarrow>=14
Requires-Dist: pyod>=2.0
Requires-Dist: pyyaml>=6
Requires-Dist: scikit-image>=0.24
Requires-Dist: scikit-learn>=1.5
Requires-Dist: scipy>=1.11
Requires-Dist: sentence-transformers>=3.0
Requires-Dist: shap>=0.45
Requires-Dist: torch>=2.3
Requires-Dist: umap-learn>=0.5
Requires-Dist: xgboost>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# autobooster

AutoML для табличных данных с акцентом на массовый feature engineering. Вы размечаете колонки по типам,
библиотека генерирует тысячи признаков (всё со всем), отсеивает шум через LightGBM с shadow-признаками,
обучает зоопарк моделей, собирает ансамбль и сохраняет результат одним файлом.

```bash
pip install autobooster-ml
```

```python
import autobooster as ab

m = ab.AutoBooster(
    task="auto",                      # regression|binary|multiclass|multilabel|ranking|forecast|anomaly|clustering
    target="churn",
    columns={                         # всё неразмеченное определяется автоматически
        "numeric": ["age", "balance"],
        "categorical": ["city", "tariff"],
        "text": ["last_ticket"],      # многоязычные эмбеддинги
        "datetime": ["signup_at"],
        "sequential": ["events"],     # ячейка-список: ["view", "cart", "buy"] или [1.2, 3.4, ...]
        "image": ["photo"],           # путь, bytes, PIL.Image, numpy или {"bytes": ...} из HF datasets
    },
    time_budget="30m", top_k=0.2,
)
m.fit(df)
m.leaderboard()                       # CV- и holdout-метрики каждой модели и ансамбля
m.feature_report()                    # отобранные признаки, важность, какой генератор их сделал
m.explain(df)                         # mean |SHAP|
m.report("report.html", df)
m.predict(new_df); m.predict_proba(new_df)
m.transform(new_df)                   # отобранные признаки, чтобы кормить ими свои модели
m.save("churn.ab"); m = ab.load("churn.ab")
```

## Что происходит внутри `fit`

1. **Схема и задача.** Роли колонок берутся из `columns` или определяются автоматически, задача определяется по таргету.
   Пресет подстраивается под число строк (фолды, сколько признаков смешивать, режим SVM, kNN, число потоков).
2. **Holdout.** Сначала откладывается 12% данных. Для временных данных это последние по времени строки,
   для `group_col` и ранжирования используются целые группы. На этой части считается честная итоговая оценка.
3. **Генерация, стадия 1** (по сырым колонкам):
   - числа: сырые, signed-log, ранг, дробная часть, круглость, NaN-флаги, построчные z-статистики;
   - категории: count, частотный код, one-hot (до 12 уровней), **out-of-fold target encoding**
     (по классам для multiclass), кроссы пар категорий;
   - даты: час, день недели, месяц, день года, неделя, выходные, начало и конец месяца, sin/cos,
     праздники (`holidays_country="RU"`), разности между датами;
   - текст: эмбеддинги `paraphrase-multilingual-MiniLM-L12-v2` → PCA, mean-pool по нескольким текстовым
     колонкам и косинусная близость между ними, char TF-IDF (2–4 символа) → SVD, word TF-IDF (слова и биграммы)
     → SVD, темы NMF (10 тем, доля каждой в документе), **OOF-линейная модель** на эмбеддингах, char- и
     word-TF-IDF, статистики текста. Эмбеддинги кешируются в `~/.cache/autobooster`;
   - sequential-ячейки: для числовых последовательностей форма ряда (квантили, наклон, хвост, автокорреляция,
     пересечения среднего, FFT: пиковая частота, энергия по полосам, спектральная энтропия); для токенов TF-IDF
     по n-граммам → SVD, item2vec (Word2Vec), OOF-линейная модель, а у коротких последовательностей фиксированной
     длины ещё и токен на каждой позиции (ДНК, коды событий);
   - картинки: эмбеддинги DINOv2-small (CLS + mean-pool патчей, CPU) → PCA, OOF-линейная модель (linear probe),
     размеры, яркость, контраст, средние цвета. Плюс классические дескрипторы scikit-image: текстура GLCM
     (контраст, однородность, энергия, корреляция), гистограммы LBP, плотность границ Canny, резкость (дисперсия
     Лапласиана), энтропия, насыщенность и colorfulness как отдельные признаки, а HOG + LBP + HSV-гистограмма
     (1920 чисел) → PCA и своя OOF-линейная модель. Всё кешируется по содержимому картинки;
   - рекомендательные пары (user × item): находятся автоматически среди высококардинальных категорий
     или задаются через `mf_pairs=[("user_id", "item_id")]`. Даёт OOF-матричную факторизацию ALS с bias-ами
     (прогноз, bias пользователя, bias объекта, скалярное произведение) и SVD-эмбеддинги матрицы взаимодействий;
   - `time_col` (+`group_col`): лаги, rolling mean/std/min/max, ewm, dt от предыдущего события внутри ряда.
     Для `forecast` добавляются лаги таргета со сдвигом на горизонт. Хвост истории хранится в модели,
     поэтому `predict` на будущих строках продолжает окна;
   - **Prophet**: yhat, trend, weekly, yearly, daily и seasonal по каждому ряду (крупнейшие ряды получают
     свою модель, остальные общую). На train значения строго out-of-fold по времени. В регрессии и прогнозе
     Prophet дополнительно участвует в ансамбле как отдельная модель;
   - `geo=[("lat","lon")]`: повёрнутые координаты, кластеры, расстояние до центров, плотность сетки;
   - `fit(df, related={"orders": (orders_df, "user_id")})`: агрегаты дочерних таблиц.
4. **Генерация, стадия 2.** Быстрый LightGBM ранжирует признаки стадии 1. Топ-N смешиваются попарно
   (+ − × ÷), а для групп по категориям считаются mean, std, отклонение от среднего группы и z-score.
   Число признаков ограничено бюджетом памяти: `rows × features × 4B ≤ memory_budget_gb`.
5. **Отбор.** Сначала фильтры: пустые, константные, дубликаты, |corr| > 0.98. Затем LightGBM примерно
   на 500 деревьев с early stopping по фолдам и gain importance против перемешанных shadow-копий:
   выживают признаки, которые сильнее 95-го перцентиля шума. Из них берётся `top_k`.
   Если строк больше 200k, генерация и отбор идут на подвыборке, после чего пайплайн **обрезается**
   до нужного и пересчитывается на всех строках.
6. **Модели.** LightGBM, CatBoost (категории нативно), XGBoost, Ridge/Logistic, ElasticNet (регрессия), MLP (torch), ExtraTrees,
   RandomForest, SVM (точный RBF на малых фолдах, Nyström на больших) и kNN. У каждой модели свой тюнинг
   Optuna на одном фолде в пределах доли бюджета, затем CV с OOF-предсказаниями.
   Для ранжирования используются lambdarank, YetiRank и rank:ndcg.
7. **Ансамбль.** Из лучшей одиночной модели, жадного Caruana и стекинга (Ridge/Logistic поверх OOF)
   выбирается вариант с лучшим OOF-скором. Сложные варианты должны выиграть с запасом.
8. **Holdout-скор, затем refit** пайплайна и моделей ансамбля на всех данных с числом итераций из CV.

Сильно скошенный неотрицательный таргет регрессии автоматически обучается в log1p, а метрики считаются в исходной шкале.
С `metric="rmsle"` модели всегда учатся на log1p(y).

## Пропущенные значения

До построения схемы спецсимволы пропуска заменяются на NaN. По умолчанию (`na_values="auto"`) это
`""`, `"?"`, `"NA"`, `"N/A"`, `"null"`, `"NaN"`, `"#N/A"` и подобные. Можно задать свои: список строк
и/или чисел (`na_values=["?", -999]`), словарь по колонкам (`{"age": [0], "city": ["unknown"]}`) или `None`.
Если колонка была числовой, но из-за `"?"` прочиталась строками, она снова становится числовой.

Затем, при `imputation="model"` (по умолчанию), **каждая числовая или категориальная колонка с пропусками
получает свою LightGBM**. Модель предсказывает значение колонки по остальным колонкам, а пропуски в самих
предикторах LightGBM обрабатывает нативно. Модель проверяется на 20% известных значений и остаётся только
если обходит медиану или моду (MAE на 2% ниже, accuracy на 0.5 п.п. выше). Иначе используется медиана или мода.
Рядом добавляется флаг `<col>__was_missing`, чтобы не терять, что значение отсутствовало («нет гаража»
и «неизвестно» — разные вещи). Колонки, где пропущено больше 60%, и категории с более чем 100 уровнями
не заполняются, NaN в них остаётся моделям. Таргет и `cv_group` никогда не используются как предикторы,
поэтому те же модели работают на `predict`.

```python
m = ab.AutoBooster("binary", "y", na_values=["?", ""]).fit(df)
m.imputation_report()          # колонка, сколько пропусков, метод, MAE/accuracy модели против медианы/моды
clean = m.impute(df)           # исходный датафрейм с заполненными пропусками
clean = ab.Imputer(na_values=["?"], exclude=["y"]).fit_transform(df)   # то же самое без обучения моделей задачи
```

`imputation="simple"` заполняет медианой или модой, `imputation=None` только превращает маркеры в NaN.

## Валидация

Фолды выбираются автоматически: stratified для классов, `GroupKFold` по `group_col` (для ранжирования это query),
expanding-window по `time_col`. Если тест состоит из **новых групп** (другие дни, клиенты, магазины),
передайте `cv_group="day"`. Тогда группа целиком попадает либо в train, либо в валидацию и holdout,
а сама колонка не используется как признак. Иначе отбор признаков и ансамбль подстроятся под интерполяцию,
которой на тесте не будет.

Если известны строки, на которых будет предсказание (например, тест Kaggle), передайте их без таргета:
`m.fit(train, test_df=test)`. Это **adversarial validation**: классификатор учится отличать train от test,
и признаки, по которым они различаются (например, «день месяца», когда тест — другие дни), выкидываются
до отбора. Таргет теста не используется.

Бюджет времени соблюдается и внутри обучения: у бустингов и MLP есть дедлайн-callback, а модели,
до которых очередь не дошла, пропускаются.

## Типы задач

| task | что нужно | метрика по умолчанию |
|---|---|---|
| regression | `target` | rmse |
| binary / multiclass | `target` (любые метки) | auc / mlogloss |
| multilabel | `target=[...]` 0/1-колонки | средний AUC |
| ranking | `target` релевантность, `group_col` = query id | ndcg@10 |
| forecast | `target`, `time_col`, опционально `group_col`, `horizon` | rmse |
| anomaly | без таргета (если передан, по нему считается AUC) | — |
| clustering | без таргета, `n_clusters` опционально; работает на признаках любых типов (текст, картинки, последовательности) | silhouette |

`horizon` в `forecast` задаёт, на сколько шагов ряда вперёд строится прогноз. Лаги таргета сдвинуты
на `horizon`, поэтому строки дальше горизонта от конца истории остаются без лагов. Ставьте `horizon`
равным максимальной дальности прогноза.

## Пресеты и бюджет

`preset="auto"` выбирается по числу строк: до 30k, 30–200k и свыше 200k. `"fast"` подходит для черновых
прогонов, `"best"` смешивает больше признаков и делает два раунда shadow. Отдельные поля можно
переопределить, например
`preset_overrides={"models": ("lightgbm", "catboost"), "memory_budget_gb": 4, "tune": False}`.
`time_budget` (`"30m"`, `"2h"`, секунды) ограничивает этап моделей: модели, на которые не хватает времени,
пропускаются.

## Сохранение

`save` пишет один joblib-файл, внутри которого лежит манифест с версиями python, numpy, pandas, sklearn,
lightgbm, catboost, xgboost, torch и других библиотек. `load` предупреждает о расхождении версий,
`ab.load(path, strict=True)` в этом случае падает. Сеть sentence-transformers по умолчанию не сохраняется,
только её имя: при загрузке она берётся из кеша HuggingFace. `bundle_text_model=True` кладёт веса внутрь
файла, это нужно для офлайн-инференса.

## CLI

```bash
autobooster fit train.parquet --target y --schema schema.yaml --budget 1h -o model.ab
autobooster predict model.ab test.parquet --proba -o pred.csv
autobooster info model.ab
```

`schema.yaml` содержит списки колонок по ролям, а в секции `options:` можно передать любые аргументы `AutoBooster`.

Есть также sklearn-обёртки: `autobooster.sklearn.AutoBoosterRegressor` и `AutoBoosterClassifier`.

## Бенчмарки

`benchmarks/run.py` запускает Kaggle-датасеты из публичных зеркал (OpenML, UCI, GroupLens, HuggingFace) и сравнивает
результат с эталонным топ-скором. Результаты лежат в [BENCHMARKS.md](BENCHMARKS.md).

```bash
.venv/bin/python benchmarks/run.py --all --budget 12m --cluster
```

## Разработка

```bash
python -m venv .venv && .venv/bin/pip install -e .[dev]
.venv/bin/pytest -m "not slow"     # быстрые тесты, ~3 мин
.venv/bin/pytest -m slow           # полный зоопарк + текст (качает модель эмбеддингов)
```
