Машинное обучение на PHP: Rubix ML 3.x – большое обновление экосистемы

В PHP-экосистеме не так часто происходят заметные изменения в области машинного обучения. Пока основное внимание разработчиков сосредоточено на Python, PyTorch и больших языковых моделях, инструменты для ML на PHP продолжают развиваться, хотя и остаются нишевым направлением.
Поэтому выход Rubix ML 3.x – важное событие для PHP-разработчиков, которые хотят использовать машинное обучение в своих проектах. Это не просто очередная версия библиотеки: обновление затронуло производительность, обучение нейросетей, обработку данных и возможности параллельных вычислений.
Кроме того, у проекта появился официальный сайт с обзором возможностей библиотеки, документацией и примерами. Он помогает увидеть Rubix ML не как набор отдельных алгоритмов, а как полноценный инструментарий для всего цикла машинного обучения – от подготовки данных до применения обученной модели в production.
Разберём, что изменилось и почему это интересно разработчикам, которые работают с PHP каждый день.
Зачем вообще машинное обучение в PHP?
Когда в существующем PHP-приложении появляется задача машинного обучения, распространённый подход – создать отдельный сервис на Python.
У такого решения есть очевидные преимущества. В Python огромная ML-экосистема, множество готовых моделей и инструментов, а вычислительную часть можно независимо масштабировать.
Но у отдельного сервиса есть и цена: дополнительное развёртывание, взаимодействие между приложениями, мониторинг, обмен данными и ещё один компонент, который нужно поддерживать.
Представим SaaS-платформу, которая собирает статистику из социальных сетей, публикует контент и анализирует активность пользователей. В какой-то момент возникает потребность находить аномалии в метриках, классифицировать данные или сегментировать аккаунты.
Обязательно ли для этого создавать отдельный Python-сервис?
Не всегда. Для некоторых задач можно использовать ML-библиотеку непосредственно в PHP-приложении. Rubix ML предоставляет алгоритмы классификации, регрессии, кластеризации, обнаружения аномалий и нейросетевые модели, а также инструменты подготовки данных и оценки качества моделей.
Конечно, это не означает, что PHP должен заменить Python во всех задачах машинного обучения. Но возможность начать с уже используемого языка бывает полезна сама по себе.
Что нового в Rubix ML 3.0?
1. Параллельные вычисления: inference и обучение
Одно из наиболее интересных изменений – возможность параллельного выполнения отдельных алгоритмов.
Здесь важно разобраться в терминологии. Training – процесс обучения модели. Inference – применение уже обученной модели к новым данным для получения предсказаний или оценок.
Например, мы обучили модель, которая обнаруживает аномалии в активности пользователей. Теперь каждый день система должна проверять тысячи или миллионы новых наблюдений.
Если обработка выполняется последовательно, время inference может стать узким местом. Параллельные вычисления позволяют распределять работу между несколькими процессами, чтобы эффективнее использовать доступные ядра CPU.
В Rubix ML 3.0 параллельный inference появился у K-Nearest Neighbors и KNN Regressor. У Isolation Forest параллелизованы как обучение, так и inference.
Как это устроено?
Вместо того чтобы самостоятельно создавать процесс для каждого наблюдения, разработчик может использовать механизм параллельного выполнения, поддерживаемый алгоритмом. Библиотека распределяет соответствующие вычислительные задачи через выбранный backend.
Например, для K-Nearest Neighbors обработка нескольких наблюдений может распределяться между рабочими процессами. Для Isolation Forest можно независимо вычислять результаты отдельных деревьев ансамбля и объединять их оценки.
Чтобы действительно включить параллельную обработку, необходимо настроить поддерживаемый backend. В Rubix ML предусмотрены, в частности, backend на основе Amp и Swoole. По умолчанию используется последовательный backend, поэтому сам факт обновления до версии 3.0 не означает, что любой вызов модели автоматически станет параллельным.
Для Isolation Forest настройка backend на основе Swoole выглядит так:
use Rubix\ML\Backends\Swoole;
$estimator->setBackend(new Swoole());Для использования этого backend необходимо установить и настроить соответствующее расширение Swoole. В зависимости от версии библиотеки и окружения можно использовать и другие поддерживаемые backend, например Amp.
Практическое применение:
Пакетный анализ метрик большого количества аккаунтов
Обработка накопившихся событий из очереди
Поиск аномалий в больших наборах данных
Массовые предсказания в фоновых задачах
При этом ускорение зависит от размера пакета, стоимости вычислений и количества доступных ресурсов. На небольших наборах данных последовательная обработка может оказаться быстрее.
2. Новые возможности обучения нейросетей
В Rubix ML 3.0 появились дополнительные инструменты для настройки процесса обучения нейросетей:
Gradient accumulation – накопление градиентов перед обновлением весов модели.
Gradient clipping – ограничение величины градиентов для более стабильного обучения.
Fine-tuning с заморозкой первых слоёв – возможность не обновлять параметры выбранной части сети.
Улучшения обучения на порциях данных и управления процессом обучения.
Эти возможности полезны при работе с нейросетями, когда важно контролировать процесс оптимизации, расход памяти и поведение модели во время обучения.
Это не превращает Rubix ML в прямую замену PyTorch для всех задач глубокого обучения. Но библиотека становится более функциональной для разработчиков, которые хотят экспериментировать с нейросетями в PHP.
3. Улучшения работы с данными и оценки моделей
Машинное обучение – это не только выбор алгоритма. Большая часть работы связана с подготовкой данных, проверкой качества и настройкой модели.
В версии 3.0 появились и другие полезные изменения: улучшения структур данных, новые возможности валидации, дополнительные метрики кластеризации, изменения в обработке категориальных признаков и исправления в структурах поиска ближайших соседей.
Например, целочисленные значения теперь автоматически рассматриваются как категориальный тип, а не как непрерывные данные. Это важно учитывать при переходе со старых версий: автоматическое определение типа признака может повлиять на поведение модели.
Rubix ML 3.1: развитие продолжается
Следом за версией 3.0 вышла Rubix ML 3.1, а затем почти сразу – версия 3.2. В этой статье сосредоточимся на ключевых изменениях версий 3.0 и 3.1, которые затронули параллельные вычисления, обучение нейросетей, подготовку данных и новые алгоритмы.
Среди наиболее интересных дополнений:
K-medoids clustering – алгоритм кластеризации, в котором центрами групп служат реальные наблюдения
Новые экстракторы данных, включая ARFF и Shuffler
Дополнительные планировщики learning rate, в том числе Ramp и Cosine
Новые преобразования изображений, включая Color Jitter и Image Flipper
K-medoids, например, может пригодиться при сегментации клиентов. Если K-means определяет центр кластера как математическое среднее, K-medoids выбирает в качестве представителя реальный объект из данных.
Это удобно, когда хочется посмотреть на конкретного представителя группы, а не на усреднённую комбинацию признаков, которая сама по себе может не соответствовать ни одному реальному клиенту.
В совокупности изменения версий 3.0 и 3.1 показывают, что проект развивается сразу в нескольких направлениях: производительность, нейросети, подготовка данных и расширение набора алгоритмов.
Официальный сайт и документация
Отдельно стоит отметить появление официального сайта Rubix ML – https://rubixml.org/.
Для open-source-проекта это важный шаг с точки зрения удобства использования и представления библиотеки. На сайте собраны основные возможности, информация об алгоритмах, документация, примеры проектов и ссылки на исходный код.
Библиотека позиционируется не просто как набор реализаций ML-алгоритмов, а как инструментарий для полного цикла работы с моделями:
Извлечение и подготовка данных.
Преобразование признаков.
Обучение модели.
Проверка качества и кросс-валидация.
Сохранение модели.
Применение модели в production.
Такой подход важен, потому что в реальном проекте недостаточно один раз вызвать алгоритм. Нужно подготовить данные, оценить качество результата, сохранить модель и обеспечить её применение к новым наблюдениям.
Официальный сайт упрощает знакомство с этими возможностями, особенно для разработчиков, которые только начинают изучать машинное обучение на PHP.
Практический пример: обнаруживаем аномалии в метриках
Рассмотрим задачу, которая вполне может возникнуть в обычном SaaS-продукте.
Допустим, мы собираем статистику активности пользователей и хотим находить подозрительные события. Например, слишком большое количество кликов за короткое время может указывать на автоматизированную активность.
Можно написать обычное правило:
if ($clicks > 10000) {
// Возможно, аномалия
}Но абсолютные значения не всегда информативны. Для крупного аккаунта десять тысяч кликов могут быть нормой, а для небольшого – крайне необычным событием. Чтобы учитывать такие различия, модель должна получать соответствующие признаки или работать с метриками, нормализованными относительно обычной активности конкретного аккаунта.
Здесь можно применить алгоритм обнаружения аномалий Isolation Forest.
Шаг 1. Устанавливаем библиотеку
Rubix ML устанавливается через Composer:
composer require rubix/mlДля актуальной ветки 3.x требуется PHP 8.3 или новее. В зависимости от используемых возможностей могут потребоваться дополнительные расширения и зависимости. Например, для backend на основе Swoole необходимо установить и настроить соответствующее расширение PHP.
Шаг 2. Подготавливаем данные и обучаем модель
Для простоты возьмём два признака: время заполнения формы в миллисекундах и количество кликов за сессию.
<?php
require 'vendor/autoload.php';
use Rubix\ML\AnomalyDetectors\IsolationForest;
use Rubix\ML\Datasets\Unlabeled;
$samples = [
[120.0, 15.0],
[145.0, 18.0],
[90.0, 12.0],
[200.0, 25.0],
[180.0, 22.0],
[110.0, 14.0],
[160.0, 20.0],
[130.0, 16.0],
[150.0, 19.0],
[175.0, 21.0],
];
$training = new Unlabeled($samples);
$estimator = new IsolationForest(100);
$estimator->train($training);Здесь модель обучается на исторических наблюдениях, которые мы считаем характерными для обычного поведения пользователей.
Набор из десяти наблюдений здесь приведён только для демонстрации API библиотеки. Он слишком мал, чтобы делать выводы о качестве обнаружения аномалий в реальном приложении.
В реальном приложении потребуется значительно больше данных, а также проверка их качества. Если обучающая выборка содержит много аномалий, модель может научиться считать подозрительное поведение нормальным.
Шаг 3. Проверяем новые наблюдения
После обучения передадим модели три новых наблюдения:
$unknown = new Unlabeled([
[135.0, 17.0],
[150.0, 20.0],
[5.0, 500.0],
]);
// Оценки аномальности
$scores = $estimator->score($unknown);
echo "Anomaly scores:\n";
print_r($scores);
// Бинарные предсказания: 1 – аномалия, 0 – не аномалия
$predictions = $estimator->predict($unknown);
echo "Predictions:\n";
print_r($predictions);Метод score() возвращает оценки аномальности для наблюдений. Более высокая оценка означает, что наблюдение модель считает более необычным. Конкретные значения зависят от обучающих данных, параметров модели и случайности алгоритма.
Вот как может выглядеть примерный вывод:
// Anomaly scores:
Array
(
[0] => 0.35
[1] => 0.41
[2] => 1.68
)Фактические оценки зависят от обучающих данных, параметров модели и случайности алгоритма.
В таком примере третье наблюдение выглядит наиболее необычным: время заполнения формы составляет всего 5 мс, а количество кликов достигает 500.
Но как понять, является ли наблюдение аномалией?
Здесь важно различать два метода:
score()возвращает оценку необычности наблюдения. Более высокая оценка означает, что модель считает наблюдение более необычным.predict()возвращает бинарное решение детектора:1означает аномалию,0– отсутствие обнаруженной аномалии.
Примерный вывод для Predictions:
// Predictions:
Array
(
[0] => 0
[1] => 0
[2] => 1
)Где:
[0] => 0— первое наблюдение не распознано как аномалия.[1] => 0— второе наблюдение не распознано как аномалия.[2] => 1— третье наблюдение распознано как аномалия.
Таким образом, score() полезен, когда нужно сравнивать наблюдения или анализировать степень их необычности, а predict() – когда приложению требуется непосредственно решение классификатора.
В продакшене порог срабатывания следует подбирать на реальных данных, а подозрительные события проверять дополнительными правилами.
Шаг 4. Включаем параллельные вычисления
Если нужно проверять не три наблюдения, а тысячи или миллионы, можно рассмотреть параллельный inference.
Продолжим предыдущий пример и подключим backend на основе Swoole для параллельного выполнения вычислений. Ниже показано, как настроить backend и выполнить inference для новых наблюдений. Массив $samples используется из шага 2.
use Rubix\ML\AnomalyDetectors\IsolationForest;
use Rubix\ML\Backends\Swoole;
use Rubix\ML\Datasets\Unlabeled;
$training = new Unlabeled($samples);
$estimator = new IsolationForest(100);
$estimator->setBackend(new Swoole());
$estimator->train($training);
$unknown = new Unlabeled([
[135.0, 17.0],
[150.0, 20.0],
[5.0, 500.0],
]);
$scores = $estimator->score($unknown);
$predictions = $estimator->predict($unknown);Для этого необходимо установить и настроить расширение Swoole, а также убедиться, что выбранный backend поддерживается используемой версией библиотеки.
После обучения можно передавать модели большие пакеты новых наблюдений. Isolation Forest способен распределять соответствующие вычисления между рабочими процессами, что может сократить время обработки на подходящей нагрузке.
При этом важно не запускать обучение заново при каждом запросе. В производственном приложении модель обычно обучают отдельно, сохраняют и затем загружают для inference. Сам inference удобно выполнять в фоновых задачах или очередях, если объём данных велик.
Таким образом, ML-модель может стать ещё одним компонентом PHP-приложения, а параллельная обработка помогает справляться с растущим объёмом данных без немедленного перехода к отдельному сервису.
Где проходит граница применимости?
Не стоит воспринимать развитие Rubix ML как доказательство того, что PHP должен заменить Python в машинном обучении.
Если задача требует обучения больших нейросетей на GPU, работы с современными LLM или использования специфических моделей из экосистемы PyTorch, отдельный Python-сервис может быть наиболее рациональным решением.
Но если задача заключается в классификации, кластеризации, поиске аномалий или прогнозировании внутри существующего бизнес-приложения, можно сначала проверить, подходит ли для неё PHP-библиотека.
Такой подход позволяет не усложнять архитектуру раньше времени. Сначала можно проверить гипотезу, измерить качество и производительность, а затем решить, нужно ли выносить вычисления в отдельный сервис.
И даже если впоследствии отдельный сервис всё-таки понадобится, первоначальный прототип поможет лучше понять требования к нему.
Итог
Выход Rubix ML 3.0 – это действительно значимое событие для PHP-экосистемы, в которой изменения в области машинного обучения происходят не так часто. Новые возможности параллельных вычислений, развитие нейросетевых инструментов и последующие дополнения версии 3.1 показывают, что библиотека продолжает двигаться вперёд.
Появление официального сайта и более удобной документации тоже важно: знакомиться с библиотекой и применять её в реальных проектах становится проще.
Лично для меня самое интересное в развитии Rubix ML – не сам факт появления новых алгоритмов, а то, что теперь у PHP-разработчиков становится больше возможностей экспериментировать с ML без необходимости сразу строить отдельную инфраструктуру.
А ведь иногда всё начинается с небольшого эксперимента: попробовать найти аномалии в метриках, сгруппировать клиентов или предсказать поведение пользователей. И кто знает – возможно, для первой версии решения уже достаточно PHP и нескольких строк кода.
Удачи вам в машинном обучении!
Полезные ссылки:
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.