Metadata-Version: 2.4
Name: claros
Version: 0.7.2
Summary: Учебная ML-библиотека с нуля на NumPy: sklearn-подобный интерфейс и свои робастные компоненты
Author-email: Сафин Георгий <sikirchannel@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/kuketa-tech/claros
Project-URL: Repository, https://github.com/kuketa-tech/claros
Keywords: machine-learning,numpy,from-scratch,education,scikit-learn
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.20
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: scikit-learn; extra == "dev"
Dynamic: license-file

# Claros

**Учебная ML-библиотека, написанная с нуля на чистом NumPy.** Sklearn-подобный интерфейс, никаких готовых ML-зависимостей — все алгоритмы реализованы руками.

`Python ≥ 3.9` · `только NumPy` · `лицензия MIT` · `32 теста зелёных`

---

## Содержание

- [Установка](#установка)
- [Документация](#документация)
- [Как устроено](#как-устроено)
- [Удобство: предобработка без Pipeline](#удобство-предобработка-без-pipeline)
- [Функции с примерами](#функции-с-примерами)
- [Валидация](#валидация)
- [Структура и тесты](#структура-и-тесты)
- [Дорожная карта](#дорожная-карта)

---

## Установка

```bash
pip install -e .            # библиотека
pip install -e ".[dev]"     # + pytest и scikit-learn для тестов
```

## Документация

Полная документация — в папке [`docs/`](docs/index.md): по каждому классу параметры (тип, дефолт, смысл), методы, что возвращают, атрибуты, примеры, плюс гайд «как писать свои компоненты».

- [**Полный справочник всех функций**](docs/reference.md) — всё одним списком
- [Модели](docs/models.md) · [Кластеризация и PCA](docs/clustering.md) · [Потери и сжимающие функции](docs/losses-and-links.md)
- [Предобработка и конвейеры](docs/preprocessing-and-pipelines.md) · [Оценка и подбор](docs/evaluation.md) · [Как писать свои компоненты](docs/extending.md)

Можно собрать в сайт: `pip install mkdocs && mkdocs serve`.

## Как устроено

Все модели наследуют `Estimator` и говорят на одном языке: `fit(X, y)` обучает (возвращает `self`), `predict(X)` предсказывает, `score(X, y)` — R² (регрессоры) или доля верных (классификаторы), `get_params` / `set_params` дают клонирование. Обученные величины оканчиваются на `_` (`coef_`, `labels_`).

Стержень дизайна — **потеря определяет модель**: весь шаг спуска это `g = loss.gradient(y, p) * link.derivative(z)`, поэтому линейная регрессия, логистическая регрессия и SVM — один движок с разной потерей и сжимающей функцией.

---

## Удобство: предобработка без Pipeline

Чтобы не собирать `Pipeline` руками, предобработку можно подключить прямо к модели.

**`prep(model, scale=1, clean_noise_features=1, pca=2)`** оборачивает **любую** модель и возвращает объект с обычным `fit`/`predict`/`score`/`fit_predict`. Опции: `scale=1` — масштабирование, `clean_noise_features=1` — убрать шумовые признаки, `pca=k` — сжать до k главных компонент (порядок: чистка → масштабирование → PCA → модель):

```python
from claros import prep, LogisticRegression, KNeighborsClassifier

prep(LogisticRegression(), scale=1).fit(X, y)                     # + масштабирование
prep(KNeighborsClassifier(5), scale=1, clean_noise_features=1).fit(X, y)  # + чистка шумовых признаков
prep(LogisticRegression(), pca=2).fit(X, y)                       # + сжатие до 2 главных компонент
```

Это все предобработчики библиотеки (`StandardScaler`, `NoiseFeatureRemover`, `PCA`) — больше ничего через Pipeline не идёт. Полноценный `Pipeline` остаётся для произвольных цепочек.

У `DBSCAN` и `KMeans` есть встроенный флаг-сокращение `clean_noise_features` (1 — включить нашу чистку шумовых признаков, 0 — обычный режим):

```python
from claros import DBSCAN
DBSCAN(eps=0.6, min_samples=6, clean_noise_features=1).fit_predict(X)
```

Полноценный `Pipeline` (см. ниже) тоже остаётся — для произвольных цепочек.

---

## Функции с примерами

> В примерах `X` — матрица признаков `(n, d)`, `y` — цель, `X_new` — новые объекты.

### Линейные модели

**`LinearRegression(loss=MSE(), link=Identity(), lr=0.1, n_iters=300, l2=0.0)`** — линейная регрессия градиентным спуском. Атрибуты: `coef_`, `intercept_`.
```python
from claros import LinearRegression
m = LinearRegression().fit(X, y)
m.predict(X_new); m.score(X, y)
```

**`LogisticRegression(loss=LogLoss(), link=Sigmoid(), lr=0.1, n_iters=300, l2=0.0)`** — бинарная классификация.
```python
from claros import LogisticRegression
clf = LogisticRegression().fit(X, y)
clf.predict(X_new); clf.predict_proba(X_new)
```

### SVM

**`LinearSVC(C=1.0, lr=0.01, n_iters=1000)`** — линейный SVM (тот же движок + `HingeLoss`). `C` — обратная сила регуляризации.
```python
from claros import LinearSVC
clf = LinearSVC(C=1.0).fit(X, y)
clf.predict(X_new); clf.decision_function(X_new)
```

### Наивный Байес

**`GaussianNB(var_smoothing=1e-9)`** — гауссов наивный Байес, мультикласс. Есть `predict_proba`.
```python
from claros import GaussianNB
clf = GaussianNB().fit(X, y)
```

### Деревья решений

**`DecisionTreeClassifier(max_depth=5, min_samples_split=2, max_features=None, random_state=None)`** — примесь Gini.
**`DecisionTreeRegressor(...)`** — примесь = дисперсия.
```python
from claros import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=5).fit(X, y)
```

### Ансамбли

**`RandomForestClassifier(n_estimators=50, max_depth=10, max_features="sqrt", random_state=None)`** / **`RandomForestRegressor(...)`** — бэггинг деревьев.
```python
from claros import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=100).fit(X, y)
```

**`GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3)`** / **`GradientBoostingRegressor(...)`** — бустинг по остаткам.
```python
from claros import GradientBoostingRegressor
m = GradientBoostingRegressor(n_estimators=200).fit(X, y)
```

### Ближайшие соседи

**`KNeighborsClassifier(n_neighbors=5)`** / **`KNeighborsRegressor(n_neighbors=5)`** — k ближайших (векторный поиск, ×3 к прежнему).
```python
from claros import KNeighborsClassifier
clf = KNeighborsClassifier(5).fit(X, y)
```

### Мультикласс

**`OneVsRestClassifier(estimator)`** — мультикласс из любой бинарной модели.
```python
from claros import OneVsRestClassifier, LogisticRegression
clf = OneVsRestClassifier(LogisticRegression()).fit(X, y)
```

### Кластеризация

**`DBSCAN(eps=0.5, min_samples=5, clean_noise_features=0, feature_threshold=0.9)`** — плотностная кластеризация; метка `-1` — шум. `clean_noise_features=1` убирает шумовые признаки перед кластеризацией (наша доработка). Атрибуты: `labels_`, `remover_` (при включённом флаге).
```python
from claros import DBSCAN
DBSCAN(eps=0.5, min_samples=5).fit_predict(X)                          # обычный DBSCAN
DBSCAN(eps=0.6, min_samples=6, clean_noise_features=1).fit_predict(X)  # + чистка шумовых признаков
```

**`KMeans(n_clusters=3, max_iter=100, n_init=10, random_state=None, clean_noise_features=0, feature_threshold=0.9)`** — по центрам, `n_init` перезапусков. Атрибуты: `cluster_centers_`, `labels_`, `inertia_`.
```python
from claros import KMeans
KMeans(n_clusters=3).fit_predict(X)
```

### Снижение размерности

**`PCA(n_components=2)`** — главные компоненты через SVD. Методы: `transform`, `inverse_transform`; атрибут `explained_variance_ratio_`.
```python
from claros import PCA
X2 = PCA(n_components=2).fit_transform(X)
```

### Функции потерь

**`MSE()`**, **`LogLoss()`**, **`HingeLoss()`**, **`DeadZoneLoss(delta=1.0)`** — `DeadZoneLoss` робастная (плоское дно + насыщение градиента, устойчива к выбросам).
```python
from claros import LinearRegression, DeadZoneLoss
LinearRegression(loss=DeadZoneLoss(0.5), lr=0.02, n_iters=40000).fit(X, y)
```

### Сжимающие функции

**`Identity()`**, **`Sigmoid()`**, **`ArctanLink()`** — `ArctanLink` осторожнее сигмоиды (тяжёлые хвосты).
```python
from claros import LogisticRegression, ArctanLink
LogisticRegression(link=ArctanLink()).fit(X, y)
```

### Предобработка и отбор признаков

**`StandardScaler()`** — среднее 0, дисперсия 1.
```python
from claros import StandardScaler
Xs = StandardScaler().fit_transform(X)
```

**`NoiseFeatureRemover(bins=20, threshold=0.9)`** — убирает признаки-шум (почти равномерная гистограмма). Атрибут `keep_mask_`.
```python
from claros import NoiseFeatureRemover
Xc = NoiseFeatureRemover().fit_transform(X)
```

### Конвейер

**`prep(model, scale=0, clean_noise_features=0, pca=0)`** — предобработка к любой модели без ручного Pipeline: масштабирование, чистка шумовых признаков, PCA (см. раздел выше).
```python
from claros import prep, KNeighborsClassifier
prep(KNeighborsClassifier(5), scale=1, clean_noise_features=1, pca=2).fit(X, y)
```

**`Pipeline(steps)`** — произвольная цепочка `[(имя, объект), …]`: трансформеры по очереди, затем модель.
```python
from claros import Pipeline, StandardScaler, LogisticRegression
Pipeline([("scale", StandardScaler()), ("model", LogisticRegression())]).fit(X, y)
```

### Подбор и оценка

**`train_test_split(X, y, test_size=0.25, random_state=None, shuffle=True)`** → `X_train, X_test, y_train, y_test`.
```python
from claros import train_test_split
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0)
```

**`cross_val_score(model, X, y, cv=5, shuffle=True, random_state=None)`** → массив оценок.
```python
from claros import cross_val_score, RandomForestClassifier
cross_val_score(RandomForestClassifier(), X, y, cv=5).mean()
```

**`GridSearchCV(estimator, param_grid, cv=5)`** — перебор по сетке. Атрибуты: `best_params_`, `best_score_`, `best_estimator_`.
```python
from claros import GridSearchCV, DecisionTreeClassifier
gs = GridSearchCV(DecisionTreeClassifier(), {"max_depth": [3, 5, 7]}, cv=5).fit(X, y)
gs.best_params_; gs.best_score_
```

### Метрики

Модуль **`claros.metrics`**, все вида `f(y_true, y_pred)`: регрессия — `mse`, `rmse`, `mae`, `r2_score`; классификация — `accuracy`, `precision`, `recall`, `f1_score`.
```python
from claros.metrics import accuracy, r2_score
accuracy(y_true, y_pred); r2_score(y_true, y_pred)
```

---

## Валидация

Сверено со scikit-learn на одинаковых данных:

| Модель                              | claros  | sklearn |
|-------------------------------------|-------|---------|
| RandomForest — accuracy (круг)      | 0.972 | 0.972   |
| KNN — accuracy (круг)               | 0.983 | 0.983   |
| GradientBoosting — R^2 (sin)        | 0.991 | 0.991   |
| LinearSVC — accuracy (две группы)   | 1.000 | 1.000   |
| GaussianNB — accuracy (3 класса)    | 0.972 | 0.972   |

Метки `GaussianNB` и `DBSCAN` совпадают со scikit-learn один-в-один, доли дисперсии `PCA` — до 4-го знака.

## Структура и тесты

```
claros-project/
├── pyproject.toml   README.md   LICENSE   PUBLISHING.md
├── claros/            # base, losses, links, linear_model, svm, naive_bayes,
│                    # tree, ensemble, neighbors, multiclass, decomposition,
│                    # cluster, preprocessing, feature_selection, pipeline,
│                    # model_selection, metrics
└── tests/           # 32 теста
```

```bash
pytest tests/ -q     # 32 passed
```


## Лицензия

MIT.
