Apprentissage Automatique avec Symfony : Intégration Facile de Rubix ML en PHP

symfony et rubix ML pour le machine learning

Introduction

Sur ce blog, on a déjà exploré pas mal de territoires techniques — de Docker au traitement asynchrone avec RabbitMQ, en passant par la configuration avancée d’environnements de développement. Mais aujourd’hui, on passe un cap : on entre dans l’univers fascinant du Machine Learning, directement depuis notre stack PHP.

Pas de RAG, pas d’API externe ni de microservice compliqué à maintenir. Non. Ici, on intègre une logique de recommandation directement dans notre application Symfony, grâce à la puissante librairie Rubix ML.

🧪 Le but ? Comprendre et expérimenter un algorithme de clustering KMeans++ (aussi appelé K3 ici) à travers un exemple très simple : l’analyse de votre consommation de café.

Le tout sans quitter votre framework préféré — Symfony — et avec une base de données ultra-légère : SQLite. Comme toujours, du concret, du PHP, et une pincée d’intelligence artificielle.

Rubix ML, késako ?

Oui, vous avez bien lu : du Machine Learning en PHP. Et non, on ne parle pas ici de cloner ChatGPT ou de jouer aux apprentis sorciers avec une IA générative. On reste sur du machine learning classique, concret, utile — et surtout intégré dans Symfony.

Alors, c’est quoi Rubix ML ?

Rubix ML est une librairie PHP open-source dédiée à l’apprentissage automatique. Elle permet, de façon simple, rapide et fiable, de mettre en place des algorithmes comme :

  • Des classificateurs (Multilayer Perceptron, Naive Bayes…)
  • Des systèmes de recommandation
  • Des algorithmes de clustering comme KMeans++

L’idée ? Ne pas dépendre de Python et de son écosystème massif, mais rester dans notre zone de confort PHP, tout en accédant à des outils puissants d’analyse de données.

Oui, PHP est historiquement plus lent, et non, la communauté ML PHP n’est pas aussi vaste que celle de Python. Mais avec Rubix ML, les développeurs Symfony disposent enfin d’un véritable moteur de machine learning natif qui permet de construire, entraîner et exploiter un modèle sans quitter leur projet PHP.

Le vrai défi : les données

Avant même de penser à lancer un modèle de Machine Learning, il faut affronter le nerf de la guerre : les données.

Oui, c’est bien beau de vouloir jouer avec Rubix ML et Symfony, mais avec quelles données allons-nous entraîner notre algorithme ? Car ici, on ne parle pas d’un simple appel à une API d’OpenAI ou d’un système pré-entraîné. Non. On parle de vrai apprentissage supervisé ou non supervisé, avec des données réelles, à injecter, structurer et analyser.

Données factices, mais pédagogiques

Pour notre projet, on part sur une base simple : des fixtures dans SQLite, basées sur une mini-étude auprès de 200 personnes. Oui, c’est très peu. Et oui, ce n’est pas scientifiquement représentatif. Mais ce n’est pas le but ici.

👉 Ce qu’on apprend, surtout, c’est que la qualité de vos données d’entrée détermine la qualité de vos prédictions. Du mauvais dataset ? Attendez-vous à des résultats absurdes. Garbage in, garbage out.

Une fois la base en place…

Une fois nos données injectées dans la base, il ne reste plus qu’à les transformer en Dataset Rubix ML, puis à les passer à l’algorithme de clustering. Et là, la magie peut enfin opérer : Rubix ML identifie des groupes, des tendances, et commence à clusteriser nos amateurs de café.

Mise en place du projet Symfony

Pour bien commencer, on part sur une base propre et neuve. On installe un projet Symfony from scratch, et on utilise SQLite comme base de données pour rester léger et rapide.

Étape 1 : Création du projet Symfony

Lancez la commande suivante dans votre terminal :

symfony new rubixML-learn --webapp

Cela vous génère une structure complète avec tout le nécessaire pour démarrer une application web Symfony.

Étape 2 : Configuration de la base SQLite

Par défaut, Symfony utilise MySQL. Pour switcher vers SQLite (idéal pour un projet de test ou de POC), modifiez la variable DATABASE_URL dans votre fichier .env :

DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"

Ensuite, créez la base de données avec :

php bin/console doctrine:database:create

Simple, rapide, efficace.

Étape 3 : Création des entités

C’est maintenant le moment de modéliser les données que vous allez utiliser pour entraîner votre algorithme. Commencez à créer vos entités avec :

php bin/console make:entity
class PredictionFeedback
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column]
    private int $inputAge;

    #[ORM\Column]
    private int $inputHour;

    #[ORM\Column(length: 10)]
    private string $predictedPreference;

    #[ORM\Column(length: 10)]
    private string $actualPreference;

    #[ORM\Column(type: 'string', precision: 3, scale: 2)]
    private string $predictionConfidence;

    #[ORM\Column]
    private bool $wasCorrect;

    #[ORM\Column]
    private \DateTimeImmutable $createdAt;
<?php

namespace App\Entity;

use App\Repository\PersonPreferenceRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: PersonPreferenceRepository::class)]
class PersonPreference
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column]
    private ?int $age = null;

    #[ORM\Column]
    private ?int $hourOfDay = null;

    #[ORM\Column(length: 10)]
    private ?string $preference = null;

    #[ORM\Column]
    private ?\DateTimeImmutable $createdAt = null;

    #[ORM\Column(nullable: true)]
    private ?string $experimentTag = null;

Entraîner le modèle : transformer vos entités en intelligence

Maintenant que nos entités sont prêtes et que la base contient des données, on peut passer à l’étape clé du projet : entraîner notre modèle avec Rubix ML.

L’approche ici est simple mais efficace : on crée un dataset cohérent, basé sur l’âge et l’heure de consommation, puis on entraîne un algorithme de classification pour qu’il devienne capable de prédire une préférence café/thé en fonction de ces données.

Génération de données factices

Avant d’entraîner le modèle, on doit générer un jeu de données d’apprentissage. Ce jeu est basé sur une logique comportementale simple : les jeunes préfèrent le café, surtout le matin, tandis que les plus âgés auront tendance à se tourner vers le thé l’après-midi.

    /**
     * Génère des données d'exemple pour l'apprentissage
     * En production, ces données viendraient de vrais utilisateurs
     */
    public function generateSampleData(int $count = 100): void
    {
        // Logique simple : les jeunes boivent plus de café le matin
        // et plus de thé l'après-midi, les plus âgés l'inverse

        for ($i = 0; $i < $count; $i++) {
            $age = rand(18, 70);
            $hour = rand(6, 22);

            // Logique probabiliste pour créer des patterns cohérents
            $preference = $this->determinePreference($age, $hour);

            $entity = new PersonPreference();
            $entity->setAge($age)
                ->setHourOfDay($hour)
                ->setPreference($preference)
                ->setExperimentTag('initial_training');

            $this->getEntityManager()->persist($entity);
        }

        $this->getEntityManager()->flush();
    }

    private function determinePreference(int $age, int $hour): string
    {
        // Simulons des patterns réalistes avec un peu d'aléatoire
        $coffeeScore = 0;

        // Les jeunes préfèrent le café
        if ($age < 35) $coffeeScore += 3;
        elseif ($age < 50) $coffeeScore += 1;
        else $coffeeScore -= 2;

        // Le matin, plus de café
        if ($hour < 12) $coffeeScore += 4;
        elseif ($hour < 15) $coffeeScore += 1;
        else $coffeeScore -= 2;

        // Un peu d'aléatoire pour que ce ne soit pas trop prévisible
        $coffeeScore += rand(-2, 2);

        return $coffeeScore > 0 ? 'coffee' : 'tea';
    }

Cette méthode permet de générer un dataset d’entraînement réaliste et exploitable, même en l’absence de données utilisateurs réelles.

le dataset pour rubix ML avec Symfony

Entraînement du modèle avec Rubix ML

Une fois les données en place, on peut les convertir en dataset Labeled de Rubix ML, puis entraîner notre classificateur :

    /**
     * Entraîne notre modèle avec les données existantes
     * Cette méthode transforme vos données Doctrine en dataset Rubix ML
     */
    public function trainModel(): array
    {
        // Récupérons nos données depuis la base
        $trainingData = $this->personPreferenceRepository->getTrainingDataset();

        if (empty($trainingData['samples'])) {
            throw new RuntimeException('Aucune donnée d\'entraînement disponible. Générez d\'abord des données d\'exemple.');
        }

        // Créons un dataset Rubix ML à partir de nos données Doctrine
        $dataset = new Labeled($trainingData['samples'], $trainingData['labels']);

        // Divisons nos données : 80% pour l'entraînement, 20% pour le test
        [$training, $testing] = $dataset->randomize()->split(0.8);

        // Entraînons notre modèle
        $this->classifier->train($training);

        // Testons les performances
        $predictions = $this->classifier->predict($testing);
        $accuracy = $this->accuracyMetric->score($predictions, $testing->labels());

        return [
            'training_samples' => count($training),
            'testing_samples' => count($testing),
            'accuracy' => $accuracy,
            'accuracy_percentage' => round($accuracy * 100, 2)
        ];
    }

Ce processus permet de créer un modèle prédictif robuste basé uniquement sur les données collectées dans notre base Symfony.

Un modèle qui s’améliore avec le feedback

Et le plus beau dans tout ça ? Grâce à l’entité PredictionFeedback, il est tout à fait possible d’intégrer un retour utilisateur sur les prédictions effectuées.

Ainsi, on crée une boucle vertueuse : chaque retour corrige ou affine le modèle, qui gagne en précision au fil du temps.

Apprendre du feedback ? Bien sûr !

À ce stade, notre modèle est fonctionnel. Il est simple, oui, mais cohérent : vous saisissez un âge, une heure de la journée… et le modèle vous répond avec une prédiction personnalisée.


Voici l’interface de notre Rubix ML Lab, une petite application Symfony qui permet de tester un modèle de classification en temps réel.

En quelques secondes, l’utilisateur entre son âge et l’heure de consommation, et le système prédit s’il préfère le café ou le thé.
Mieux encore, il peut valider ou infirmer la prédiction, permettant ainsi à l’algorithme de s’améliorer continuellement grâce au feedback utilisateur.

➡️ Avec seulement 208 échantillons d’entraînement et 8 feedbacks collectés, on atteint déjà une précision de 87,5%. Imaginez avec plus de données…

le feedback user avec rubix ML et Symfony 7

Et là, une idée surgit : « Est-ce qu’on peut intégrer le feedback utilisateur pour améliorer le modèle ? »
La réponse : absolument. Et on aurait tort de s’en priver.

Vers un apprentissage continu

En production, il serait même recommandé d’aller plus loin : filtrer les retours trop rapides, analyser les écarts âge/réponse, exclure les feedbacks incohérents… car oui, de mauvaises données restent toxiques, même en boucle de rétroaction.

Mais ici, en version simplifiée, le principe est déjà là : l’utilisateur entre une donnée, le système prédit, et il peut ensuite valider ou corriger cette prédiction.

Chaque envoi de formulaire devient alors un nouvel échantillon de vérité, enrichissant la base et permettant au modèle d’être réentraîné régulièrement avec des données plus fines, plus réalistes.

Un système complet, basé uniquement sur Symfony & Rubix ML

On a désormais un mini système intelligent :

  • Un modèle entraîné localement
  • Une base alimentée par les utilisateurs
  • Un retour utilisateur intégré
  • Et surtout : aucun service externe, tout en PHP

C’est simple. C’est léger. C’est pédagogique.
Et c’est la preuve qu’on peut faire du machine learning proprement dans Symfony.


Conclusion : Symfony + Rubix ML, une combinaison prometteuse

En tant que développeur passionné de Symfony, vous le savez si vous suivez ce blog, j’aime tester des approches nouvelles. Et là, clairement, Rubix ML m’a bluffé.

🎯 En quelques heures, j’ai pu :

  • Comprendre les bases du machine learning en PHP
  • Intégrer Rubix ML dans un projet Symfony 7.2
  • Construire un petit système de recommandation interactif
  • Et surtout : obtenir des prédictions fiables, directement dans un environnement PHP pur

Quelques limites, mais rien de bloquant

Actuellement, Rubix ML n’est pas encore totalement compatible avec PHP 8.4 — j’ai eu quelques warnings en console — mais rien de critique. Le cœur du système fonctionne, et c’est bien là l’essentiel.

🚀 Un futur prometteur avec Rubix ML

Ce qui est passionnant, c’est que Rubix ML évolue constamment. La doc est bien fournie, les mises à jour régulières, et il semblerait même qu’il y ait un pont vers Tensor… Oui, oui, en PHP. Autant dire que le champ des possibles s’élargit sérieusement.

Avec Symfony en base, vous avez :

  • Un framework robuste
  • Un ORM ultra puissant
  • Un écosystème mature

Et désormais, une librairie ML capable d’évoluer dans cet environnement.

👉 C’est sûr, je referai du contenu autour de Rubix ML prochainement.
Restez connectés, on n’a clairement pas fini d’en parler !

comment le model fonctionne ?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *