miércoles, 25 de junio de 2025

Implementando Árboles de Decisión en PHP para Tareas de Clasificación

Implementando Árboles de Decisión en PHP para Tareas de Clasificación

Los árboles de decisión son algoritmos de aprendizaje supervisado que se utilizan para la clasificación y la regresión. En esencia, crean una estructura de árbol donde cada nodo interno representa una "prueba" sobre un atributo, cada rama representa el resultado de esa prueba y cada nodo hoja representa una decisión o una clasificación. Si bien PHP no es el lenguaje más común para el machine learning, es posible implementar estos algoritmos para tareas más pequeñas o específicas. Este artículo mostrará cómo construir un árbol de decisión básico para la clasificación en PHP.


<?php

class DecisionTreeNode {
    public $attribute;
    public $children = [];
    public $result;

    public function __construct($attribute = null, $result = null) {
        $this->attribute = $attribute;
        $this->result = $result;
    }

    public function addChild($value, DecisionTreeNode $node) {
        $this->children[$value] = $node;
    }
}

function buildDecisionTree(array $data, array $attributes, $targetAttribute) {
    // Si no hay más datos, devolver la clase más común
    if (empty($data)) {
        return new DecisionTreeNode(null, getMostCommonClass([])); // Función auxiliar
    }

    // Si no hay más atributos, devolver la clase más común
    if (empty($attributes)) {
        return new DecisionTreeNode(null, getMostCommonClass(array_column($data, $targetAttribute))); // Función auxiliar
    }

    // 1. Seleccionar el mejor atributo para dividir (ej: usando ganancia de información)
    $bestAttribute = selectBestAttribute($data, $attributes, $targetAttribute); // Función auxiliar

    // 2. Crear el nodo raíz del árbol
    $rootNode = new DecisionTreeNode($bestAttribute);

    // 3. Para cada valor posible del mejor atributo...
    $values = array_unique(array_column($data, $bestAttribute));
    foreach ($values as $value) {
        // 4. Filtrar los datos donde el atributo es igual al valor actual
        $subset = array_filter($data, function($row) use ($bestAttribute, $value) {
            return $row[$bestAttribute] == $value;
        });

        $subset = array_values($subset); // Reindexar el array

        // 5. Remover el atributo del conjunto de atributos restantes
        $remainingAttributes = array_diff($attributes, [$bestAttribute]);

        // 6. Construir recursivamente el subárbol
        $childNode = buildDecisionTree($subset, $remainingAttributes, $targetAttribute);

        // 7. Agregar el subárbol como hijo del nodo raíz
        $rootNode->addChild($value, $childNode);
    }

    return $rootNode;
}

// Funciones auxiliares: selectBestAttribute, getMostCommonClass, etc., deben implementarse según la lógica de tu problema.
// Ejemplo:
function getMostCommonClass(array $classes) {
    if (empty($classes)) return null;
    $counts = array_count_values($classes);
    return array_search(max($counts), $counts);
}

// Ejemplo de uso (requiere implementación de selectBestAttribute, etc.)
/*
$data = [
    ['weather' => 'sunny', 'temperature' => 'hot', 'humidity' => 'high', 'wind' => 'weak', 'play' => 'no'],
    ['weather' => 'sunny', 'temperature' => 'hot', 'humidity' => 'high', 'wind' => 'strong', 'play' => 'no'],
    ['weather' => 'overcast', 'temperature' => 'hot', 'humidity' => 'high', 'wind' => 'weak', 'play' => 'yes'],
    ['weather' => 'rain', 'temperature' => 'mild', 'humidity' => 'high', 'wind' => 'weak', 'play' => 'yes'],
    ['weather' => 'rain', 'temperature' => 'cool', 'humidity' => 'normal', 'wind' => 'weak', 'play' => 'yes'],
];

$attributes = ['weather', 'temperature', 'humidity', 'wind'];
$targetAttribute = 'play';

$tree = buildDecisionTree($data, $attributes, $targetAttribute);

// Para clasificar una nueva instancia, se recorre el árbol según los valores de sus atributos.
*/

?>
    

El código anterior proporciona una estructura básica para construir un árbol de decisión. La clase `DecisionTreeNode` representa un nodo en el árbol. La función `buildDecisionTree` construye recursivamente el árbol, seleccionando el mejor atributo en cada paso y creando subárboles para cada valor posible de ese atributo. Es crucial implementar correctamente las funciones auxiliares como `selectBestAttribute` (que determinaría el atributo más relevante para la división, normalmente usando ganancia de información o índice Gini) y `getMostCommonClass` que devuelve la clase más frecuente en un conjunto de datos.

Este es un ejemplo rudimentario, la eficiencia puede mejorar significativamente con técnicas de poda y optimización del algoritmo de selección de atributos. La clasificación de nuevas instancias implicaría recorrer el árbol desde la raíz, siguiendo las ramas correspondientes a los valores de los atributos de la instancia hasta llegar a un nodo hoja, cuyo valor representa la clasificación predicha.

No hay comentarios:

Publicar un comentario