CLR

Clasificación y predicción mediante boosting adaptativo

James McCaffrey

Descargar el ejemplo de código

La clasificación es una técnica de aprendizaje automático que usa datos de entrenamiento para generar un modelo (generalmente una ecuación matemática o regla compleja única) que asigne elementos de datos a una de varias categorías distintivas. El modelo se puede usar luego para hacer predicciones sobre nuevos elementos de datos cuya categoría se desconoce. Los ejemplos incluyen predecir si un paciente tiene cáncer (sí, no) según datos de diversos exámenes médicos y predecir la categoría de riesgo (bajo, medio, alto) de una aplicación de préstamo según el historial financiero de un solicitante.

Existen muchos algoritmos y técnicas de clasificación diferentes, como Naive Bayes, red neuronal y regresión logística. En este artículo, explico una técnica fascinante denominada clasificación por boosting adaptativo en la cual, en lugar de intentar determinar una regla de predicción compleja única, se usan datos de entrenamiento para generar una colección grande de reglas generales muy sencillas y rudimentarias. Luego se calcula una ponderación para cada regla general. Se hace una predicción sobre la nueva entrada al combinar las reglas generales, tomando en cuenta cada ponderación de cada regla sencilla y llegando a un resultado consensual. El término "boosting" viene del hecho de que la calidad predictiva de las reglas sencillas se impulsa (mejora) al combinarlas.

El boosting adaptativo es metaheurístico. Con ello, quiero decir que el boosting adaptativo es un conjunto de pautas que se pueden usar para crear un algoritmo de clasificación específico. Existen muchas variaciones de algoritmos de boosting adaptativo así como existen muchas herramientas independientes que implementan alguna forma de boosting adaptativo, de manera que ¿para qué molestarse en codificar la clasificación de boosting adaptativo desde cero? Puede ser difícil o incluso imposible personalizar las herramientas de clasificación de boosting adaptativo actuales; pueden ser difíciles de integrar en un sistema de software y es posible que tengan problemas relacionados con la propiedad intelectual. 

Un ejemplo concreto es la mejor manera de comprender qué es el boosting adaptativo. Observe la figura 1. El mayor problema del programa de demostración es predecir si algún equipo deportivo de Seattle ganará o perderá un próximo enfrentamiento contra un equipo de Detroit cuando Seattle juegue como local y el consenso de las apuestas (la extensión) es que Seattle tiene una leve ventaja (pequeña) La parte superior de la figura 1 muestra 10 elementos de datos de entrenamiento hipotéticos con resultados conocidos. La primera tupla de entrenamiento (Detroit, Home, Large, Win) significa que en un juego anterior contra Detroit, cuando Seattle jugó de local y la extensión del punto era grande, Seattle ganó el juego.

Adaptive Boosting Classification and PredictionFigura 1 Clasificación y predicción de boosting adaptativo

La siguiente parte del programa de demostración muestra que los 10 elementos de datos de entrenamiento se convirtieron de datos de cadena a enteros basados en cero para un procesamiento más eficaz y luego se almacenaron en una memoria de máquina como una matriz. Por ejemplo, (Detroit, Home, Large, Win) se almacenó como (3, 0, 2, 1). Observe que en este ejemplo, el resultado que se va a predecir solo tiene dos valores, ganar o perder. Esto se denomina un problema de clasificación binaria. El boosting adaptativo también puede usarse en situaciones en que la variable dependiente tiene tres o más valores (clasificación multinomial). La mayoría de las técnicas de clasificación binaria codifican la variable dependiente que se va a predecir mediante un esquema (0,1), pero el boosting adaptativo casi siempre usa un esquema (-1, +1) porque esa codificación simplifica levemente algo de la implementación de algoritmos. Observe que todos los valores independientes de predictor variable son categóricos (“Home,” “Medium”, etc.) y no numéricos. El boosting adaptativo también se puede usar al entrenar datos con valores numéricos, como explicaré más adelante.

La tercera parte de la figura 1 muestra que se generaron ocho reglas generales de los datos de entrenamiento. Las reglas generales a menudo se denominan factores débiles o clasificadores débiles en terminología de boosting adaptativo. El primer factor débil, expresado en forma sencilla, es “IF Opponent IS Buffalo THEN Result IS Win” con una tasa de error bruto de 0,0. El segundo factor débil, que es más ilustrativo, es “IF Opponent IS Chicago THEN Result IS Lose” con una tasa de error bruto de 0,33. ¿De dónde proviene este factor débil? Si examina los datos de entrenamiento, verá que hay tres instancias en que el oponente es Chicago. En dos de estas instancias de entrenamiento, el resultado fue Lose, de manera que el factor débil es correcto dos de tres veces (0,67) y equivocado una vez de tres (0,33).

Observe que no todos los valores predictores de elementos de entrenamiento generaron un factor débil: no existe regla para cuando el oponente es Atlanta. Como hay dos tuplas de entrenamiento en el oponente en Atlanta y un resultado es Win y el otro resultado es Lose, la tasa de error para el factor sería 0,50, lo cual no proporciona ninguna información útil. La versión de clasificación de boosting adaptativo presentada en este artículo supone que todos los factores débiles tienen una tasa de error bruto inferior a 0,50.

La sección siguiente de la figura 1 indica que tras bambalinas el algoritmo del boosting adaptativo procesa los factores débiles para encontrar un ponderado para cada factor. Estos ponderados son medidas de la importancia década clasificador débil y se denominan valores alfa en terminología de boosting adaptativo. Determinar los valores alfa es la parte clave del boosting adaptativo. El conjunto de factores débiles y sus ponderados alfa conforman el modelo de clasificación.

La última parte del programa de demostración muestra el modelo de clasificación que se usa para hacer una predicción para el equipo Seattle cuando el equipo oponente es Detroit, el campo es Home y la extensión del punto es Small. Si consulta el conjunto de factores débiles, verá que se pueden aplicar tres factores: [2] IF Opponent IS Detroit THEN Result IS Win (+1), [3] IF Field IS Home THEN Result IS Win (+1) y [5] IF Spread IS Small THEN Result IS Lose (-1). Los valores alfa calculados para los factores débiles 2, 3 y 5 son 0,63, 3,15 y 4,49, respectivamente. Por lo tanto, la predicción consensual = (0,63)(+1) + (3,15)(+1) + (4,49)(-1) = -0,72 (redondeada), la cual, como el valor es negativo, significa Lose. Observe que aun cuando dos de tres factores débiles (2 y 3) predicen Win, el alfa grande del factor débil 5 pesa más que esas predicciones de Win para arrojar una predicción general de Lose.

En las secciones que siguen, explicaré con cuidado cómo funciona el programa de demostración para que pueda agregar características de predicción a un sistema o aplicación .NET. Este artículo supone que ha avanzado habilidades de programación con un lenguaje de la familia C, pero no supone que sepa algo acerca de la clasificación con boosting adaptativo. Codifiqué la demostración con C#, pero la explicación debe brindarle información suficiente para refactorizar el código para otros lenguajes como Visual Basic .NET o Python. El código para el programa de demostración es demasiado largo para incluirlo en su totalidad en este artículo, pero el código fuente completo está disponible en archive.msdn.microsoft.com/mag201304AdaptiveBoost.

El algoritmo del boosting adaptativo

El centro de la clasificación de boosting adaptativo es una rutina que examina cada factor débil y asigna una ponderación alfa a cada uno. El algoritmo es bastante complejo y queda mejor explicado con un ejemplo concreto. Supongamos que hay 10 tuplas de entrenamiento y ocho factores débiles, tal como se muestra en la figura 1. A cada tupla de entrenamiento se le asigna una ponderación, generalmente denominada D en literatura de boosting adaptativo. La suma de las ponderaciones D es 1,0, lo cual deja los valores D como una distribución. Inicialmente, a todos los elementos de datos de entrenamiento se les asignan iguales ponderaciones D, en este caso 0,10 porque hay 10 elementos:

[0] (D = 0.10) Detroit   Home   Large    Win
[1] (D = 0.10) Detroit   Away   Medium   Win
[2] (D = 0.10) Buffalo   Home   Small    Win
[3] (D = 0.10) Buffalo   Home   Medium   Win
[4] (D = 0.10) Atlanta   Away   Large    Win
[5] (D = 0.10) Chicago   Home   Medium   Win
[6] (D = 0.10) Chicago   Away   Small    Lose
[7] (D = 0.10) Chicago   Home   Small    Lose
[8] (D = 0.10) Atlanta   Away   Medium   Lose
[9] (D = 0.10) Detroit   Away   Large    Lose

Cada factor tiene un valor épsilon y un valor alfa. Los valores épsilon son tasas de error ponderadas usadas para calcular valores alfa. Inicialmente todos los factores tienen valores alfa desconocidos (digamos a = 0,00) y valores épsilon desconocidos (digamos e = -1,0):

[0] (a = 0.00) (e = -1.0) IF Opponent IS Buffalo THEN Result IS Win
[1] (a = 0.00) (e = -1.0) IF Opponent IS Chicago THEN Result IS Lose
[2] (a = 0.00) (e = -1.0) IF Opponent IS Detroit THEN Result IS Win
[3] (a = 0.00) (e = -1.0) IF Field IS Home THEN Result IS Win
[4] (a = 0.00) (e = -1.0) IF Field IS Away THEN Result IS Lose
[5] (a = 0.00) (e = -1.0) IF Spread IS Small THEN Result IS Lose
[6] (a = 0.00) (e = -1.0) IF Spread IS Medium THEN Result IS Win
[7] (a = 0.00) (e = -1.0) IF Spread IS Large THEN Result IS Win

En seudocódigo, el algoritmo para encontrar las ponderaciones alfa para cada factor es:

set t=0
while not done loop
  update all learners' epsilons (weighted errors)
  find best (smallest epsilon) unused learner
  compute and save the alpha of best learner using its epsilon
  update the D weights for each training item using the best learner
  normalize the D weights so they sum to 1.0
  ++t
end loop

El bucle de procesamiento principal termina cuando todos los factores débiles se han procesado y se les ha asignado una ponderación alfa; o cuando la variable del contador de bucle t sobrepasa algún valor máximo; o cuando la tasa de error ponderada, épsilon, para el mejor factor débil sin usar es algún valor (como 0,45 o 0,49), que indica que relativamente no queda ningún factor bueno sin uso para procesar.

El primer paso dentro del bucle es actualizar todos los epsilones. Un valor épsilon es la suma de las ponderaciones D de tuplas de entrenamiento clasificadas incorrectamente. Para el factor [0] (IF Opponent IS Buffalo THEN Result IS Win) hay dos tuplas de entrenamiento aplicables, [2] y [3] y la regla es correcta en ambas instancias, de manera que épsilon es 0,00. Para el factor [1] (IF Opponent IS Chicago THEN Result IS Lose) hay tres tuplas de entrenamiento aplicables, [5], [6] y [7]. De estas, la tupla [5] es incorrecta, de manera que épsilon es solo la ponderación D para la tupla [5] = 0,10.

Aunque no es inmediatamente obvio, si revisa cuidadosamente cómo se calculan los epsilones, observará que los valores épsilon siempre estarán entre 0,0 y 0,5. Después de todas las actualizaciones, los epsilones factor son:

[0] (a = 0.00) (e = 0.00) IF Opponent IS Buffalo THEN Result IS Win
[1] (a = 0.00) (e = 0.10) IF Opponent IS Chicago THEN Result IS Lose
[2] (a = 0.00) (e = 0.10) IF Opponent IS Detroit THEN Result IS Win
[3] (a = 0.00) (e = 0.10) IF Field IS Home THEN Result IS Win
[4] (a = 0.00) (e = 0.20) IF Field IS Away THEN Result IS Lose
[5] (a = 0.00) (e = 0.10) IF Spread IS Small THEN Result IS Lose
[6] (a = 0.00) (e = 0.10) IF Spread IS Medium THEN Result IS Win
[7] (a = 0.00) (e = 0.10) IF Spread IS Large THEN Result IS Win

En este momento, se selecciona el mejor factor. Es el factor [0], porque su épsilon es inferior a 0,00. El alfa asociado se calcula como:

alpha = 0.5 * log((1.0 - epsilon) / epsilon)

Esto es esencialmente una ecuación mágica a partir de la teoría del boosting adaptativo. Aquí, log es el logaritmo natural (base e). Recuerde que el valor alfa es una ponderación que asigna una importancia a un factor. La ecuación previa está diseñada de manera que los valores más pequeños de épsilon (error de factor) arrojan valores más grandes de alfa (importancia de factor).

En esta situación determinada, hay un problema porque épsilon es 0, de manera que habría un error de división por 0. Para evitar esto, el programa de demostración arbitrariamente convierte cualquier épsilon con un valor 0 en 0,000001. De manera que el alfa para el factor [0] se calcula como 0,5 * log(0,999999/0,000001) = 6,91 y ese valor se asigna al factor [0] y el factor [0] se marca como completado.

El paso siguiente dentro del bucle del algoritmo es actualizar las ponderaciones de la tupla de entrenamiento D según el mejor factor que se acaba de calcular. La idea es aumentar las ponderaciones D para esas tuplas de entrenamiento clasificadas incorrectamente por el mejor factor y disminuir las ponderaciones D para las tuplas de entrenamiento clasificadas correctamente por el mejor factor. La ecuación de actualización D es un poco compleja a primera vista:

D(new) = D(old) * exp(-alpha * actualY * predictedY)

El mejor factor fue el factor [0] (IF Opponent IS Buffalo THEN Result IS Win) con un alfa de 6,91. De las 10 tuplas de entrenamiento, el factor [0] se aplica a las tuplas [2] y [3], de manera que los valores D se actualizan. Para la tupla de entrenamiento [2]:

D(new) = 0.10 * exp(-6.91 * (+1) * (+1))
       = 0.10 * exp(-6.91)
       = 0.0000997758

El nuevo valor D para la tupla de entrenamiento [3] tiene el mismo cálculo y el mismo valor que la tupla [2].

En este caso, obtenemos una nueva ponderación D que es muy pequeña, porque el mejor factor clasificó correctamente la tupla de entrenamiento. Observe que cuando el valor Y verdadero y el valor Y predicho son iguales (ambos son -1 o +1), cuando se multiplican juntos, el resultado es +1 y el argumento será un número negativo (porque -alfa siempre será negativo), lo cual arrojará un resultado menor que 1,0. Sin embargo, si Y verdadero e Y predicho son diferentes, su producto será -1 y el argumento será positivo, lo cual arrojará un número (posiblemente grande) mayor que 1,0. Esta técnica de actualización para D es el porqué la clasificación de boosting adaptativo generalmente usa -1 y +1 para los valores de variable dependiente en lugar de 0 y +1.

En este punto, los valores D aproximados preliminares (redondeados) son:

[0] (D = 0.1000) Detroit   Home   Large    Win
[1] (D = 0.1000) Detroit   Away   Medium   Win
[2] (D = 0.0001) Buffalo   Home   Small    Win
[3] (D = 0.0001) Buffalo   Home   Medium   Win
[4] (D = 0.1000) Atlanta   Away   Large    Win
[5] (D = 0.1000) Chicago   Home   Medium   Win
[6] (D = 0.1000) Chicago   Away   Small    Lose
[7] (D = 0.1000) Chicago   Home   Small    Lose
[8] (D = 0.1000) Atlanta   Away   Medium   Lose
[9] (D = 0.1000) Detroit   Away   Large    Lose

El paso siguiente en el bucle del algoritmo principal es normalizar los valores D para que sumen 1,0 al dividir cada valor D preliminar por la suma de los valores D. La suma de los 10 valores D es alrededor de 0,8002, de manera que el valor D normalizado para la tupla de entrenamiento [0] es aproximadamente 0,1000/0,8002 = 0,1249. Las ponderaciones D actualizadas son:

[0] (D = 0.1249) Detroit   Home   Large    Win
[1] (D = 0.1249) Detroit   Away   Medium   Win
[2] (D = 0.0001) Buffalo   Home   Small    Win
[3] (D = 0.0001) Buffalo   Home   Medium   Win
[4] (D = 0.1249) Atlanta   Away   Large    Win
[5] (D = 0.1249) Chicago   Home   Medium   Win
[6] (D = 0.1249) Chicago   Away   Small    Lose
[7] (D = 0.1249) Chicago   Home   Small    Lose
[8] (D = 0.1249) Atlanta   Away   Medium   Lose
[9] (D = 0.1249) Detroit   Away   Large    Lose

La idea aquí es que ahora deseamos que el algoritmo se centre en tuplas de entrenamiento distintas de [2] y [3], porque el factor [0] ya tomó en cuenta estas. En este punto, el algoritmo retrocede a la parte superior del bucle y actualiza los valores épsilon de todos los factores según las ponderaciones D recién calculadas, determina el mejor factor sin usar (factor [5]), calcula el valor alfa para el mejor factor (4,49), actualiza los valores D para las tuplas de entrenamiento aplicable ([2], [6] y [7]) y actualiza los valores D normalizados para todas las tuplas de entrenamiento.

En este ejemplo, el proceso continúa hasta que se hayan calculado los valores alfa para los ocho factores débiles, pero, en general, no todos los factores débiles resultarán necesariamente buenos ni se les asignará un valor alfa.

Estructura general del programa

El programa de demostración que aparece en la figura 1 es una aplicación de consola C# única. Usé Visual Studio 2010, pero cualquier versión compatible con Microsoft .NET Framework 2.0 o superior funcionará. Creé un nuevo proyecto denominado AdaptiveBoosting y luego, en la ventana Explorador de soluciones, cambié el nombre de Program.cs al más descriptivo AdaptiveBoostingProgram.cs, que también cambió de nombre automáticamente a la clase Program. Borré todas las instrucciones de uso generadas por plantilla en la parte superior del código fuente, excepto por las referencias a los espacios de nombres System y Collections.Generic. El método Main (con algunas instrucciones WriteLine eliminadas, unas cuantas otras ediciones menores y una clase clave definida por programa para definir objetos de factor débil) aparece en la figura 2.

Figura 2 Estructura general de programa

using System;
using System.Collections.Generic;
namespace AdaptiveBoosting
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        Console.WriteLine("\nBegin adaptive boosting classification demo\n");
        string[] features = new string[] { "Opponent", "Field", "Spread",
          "Result" };
        string[][] values = new string[4][];
        values[0] = new string[] { "Atlanta", "Buffalo", "Chicago",
          "Detroit" }; // opponent
        values[1] = new string[] { "Home", "Away" };  // Field
        values[2] = new string[] { "Small ", "Medium", "Large " }; 
        // Note: Spaces added
        values[3] = new string[] { "Lose", "Win" }; 
        // The dependent/predicted variable
        string[][] rawTrain = new string[10][];
        rawTrain[0] = new string[] { "Detroit", "Home", "Large ", "Win" };
        rawTrain[1] = new string[] { "Detroit", "Away", "Medium", "Win" };
        rawTrain[2] = new string[] { "Buffalo", "Home", "Small ", "Win" };
        rawTrain[3] = new string[] { "Buffalo", "Home", "Medium", "Win" };
        rawTrain[4] = new string[] { "Atlanta", "Away", "Large ", "Win" };
        rawTrain[5] = new string[] { "Chicago", "Home", "Medium", "Win" };
        rawTrain[6] = new string[] { "Chicago", "Away", "Small ", "Lose" };
        rawTrain[7] = new string[] { "Chicago", "Home", "Small ", "Lose" };
        rawTrain[8] = new string[] { "Atlanta", "Away", "Medium", "Lose" };
        rawTrain[9] = new string[] { "Detroit", "Away", "Large ", "Lose" };
        Console.WriteLine("Raw (string) training data for team seattle:\n");
        Console.WriteLine("Opponent Field  Spread   Result");
        Console.WriteLine("===============================");
        ShowMatrix(rawTrain);
        Console.WriteLine("\nConverting and storing training data");
        int[][] train = RawTrainToInt(rawTrain, values);
        Console.WriteLine("Training data in int form:\n");
        ShowMatrix(train, true);
        Console.WriteLine(
          "\nCreating weak categorical stump learners from training data");
        List<Learner> learners = MakeLearners(values, train);
        Console.WriteLine("Completed. Weak learners are:\n");
        for (int i = 0; i < learners.Count; ++i)
          Console.WriteLine("[" + i + "] " + Description(learners[i],
            features, values));
        Console.WriteLine("\nInitializing list of best learner indexes");
        List<int> bestLearners = new List<int>();  // Indexes of good weak learners
        Console.WriteLine(
          "\nUsing adaptive boosting to find best  learners and alphas");
        MakeModel(train, values, learners, bestLearners);
        Console.WriteLine("\nModel completed");
        int numGood = bestLearners.Count;
        Console.Write("Algorithm found " + numGood + " good learners ");
        Console.WriteLine("and associated alpha values");
        Console.WriteLine("\nThe good learners and their alpha value are:");
        for (int i = 0; i < bestLearners.Count; ++i)
        {
          int lrn = bestLearners[i];
          Console.Write("[" + lrn + "] " +
            learners[lrn].alpha.ToString("F2") + "  ");
        }
        Console.Write("\nPredicting outcome when Opponent = Detroit, ");
        Console.WriteLine("Field = Home, Spread = Small\n");
        int[] unknownTuple = new int[] { 3, 0, 0 }; // Detroit, Home, Small
        int Y = Classify(unknownTuple, learners, bestLearners);
        Console.Write("Predicted Y = " + Y + " => ");
        Console.WriteLine("seattle will " + YValueToString(Y, values));
        Console.WriteLine("\nEnd\n");
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    } // Main
    // (Many) static methods here
  } // Class Program
  public class Learner  // Weak learner
  {
    // Definition code here
  }
} // ns

El método Main comienza al configurar cadenas codificadas de forma rígida para “Opponent,” “Field,” “Spread” y “Result” para las características. Luego el código en Main configura valores codificados de forma rígida para característica: “Atlanta,” “Buffalo,” “Chicago,” “Detroit,” “Home,” “Away,” “Small,” “Medium,” “Large,” “Lose” y “Win.” Para que mi resultado se mantuviera ordenado, usé una modificación e inserté un espacio vacío al final de “Small” y “Large.”

Para simplificar las cosas, los datos de entrenamiento también se codifican de forma rígida en el programa de demostración. En muchas situaciones, sus datos de entrenamiento se almacenarán en un archivo de texto o en una tabla SQL. En tales situaciones, quizás le conviene considerar explorar de manera programática los datos de entrenamiento para determinar los nombres de característica (supuestamente a partir de la línea de un encabezado de archivo de texto o de nombres de la columna de una tabla SQL) y los valores de característica.

El método RawTrainToInt convierte los datos de entrenamiento en forma de cadena en enteros basados en cero y los almacena en una matriz int[][] denominada tren. RawTrainToInt llama a un auxiliar denominado ValueToInt. La matriz tren tiene los valores de variable dependiente (Result) almacenados en la última columna. Le conviene almacenar los valores dependientes en una matriz de columna separada. En situaciones con conjuntos de datos de entrenamiento muy grandes, es posible que no pueda almacenar todo el conjunto de datos de entrenamiento en memoria de máquina. En esas situaciones, tendrá que transmitir en secuencias a través de los datos externos almacenados en lugar de una matriz interna.

El programa de demostración determina los factores débiles que usan el método MakeLearners y una clase Learner definida por el programa. Describiré ese método y esa clase en detalle en la sección siguiente de este artículo. Después de que se han creado los factores débiles, el programa de demostración llama al método MakeModel. MakeModel es el corazón del algoritmo de boosting adaptativo según se describe en la sección anterior. El resultado neto es una lista ordenada, denominada bestLearners, de los índices de los factores a los cuales se asignaron valores alfa.

El método Main finaliza al predecir el resultado para Seattle para un conjunto de entradas con Opponent de “Detroit,” Field de “Home” y Spread de “Small,” usando el método Classify. En este caso, el valor de devolución de Classify es -0,72, el cual se interpreta como "Lose".

Cómo se hacen los factores débiles

La implementación de un algoritmo de boosting adaptativo depende hasta cierto punto de la definición específica de un factor débil. La clase Learner definida por el programa tiene seis campos:

public int feature;
public int value;
public int predicted;
public double error;
public double epsilon;
public double alpha;

Declaré los cinco campos con alcance público por motivos de simplicidad. El campo de característica contiene un entero que indica cuál variable independiente es la clave para el factor. Por ejemplo, si la característica es 0, el factor débil se basa en el valor de un oponente. El campo de valor contiene un entero que indica el valor de la característica. Por ejemplo, si el valor es 3, el factor débil se basa en la condición de que el oponente es Detroit. El campo predicho es -1 o +1, dependiendo de si la verdadera categoría para el valor de la característica es Lose o Win.

El campo de error es de tipo doble y es la tasa de error bruto asociada con el factor débil en los datos de entrenamiento. Por ejemplo, si un factor débil tiene característica = 0, valor = 3 y predicho = +1 (lo que significa que si Opponent es Detroit, entonces el resultado es Win), entonces la tasa de error bruto para los datos de entrenamiento en la figura 1 es 0,33 porque uno de tres elementos de datos de entrenamiento se predeciría incorrectamente. Observe que el error bruto trata cada elemento de entrenamiento de manera igual. Resulta que el algoritmo de boosting adaptativo presentado en este artículo realmente no necesita el campo de error bruto, de manera que ese campo podría haberse omitido, pero creo que la información es útil.

El campo de épsilon es un término de error ponderado. El épsilon para un factor débil es un término de error que toma en cuenta las ponderaciones D internas asignadas a cada elemento de entrenamiento. El algoritmo de boosting adaptativo usa los valores épsilon para calcular las ponderaciones alfa. En resumen, en la clasificación de boosting adaptativo se usan dos conjuntos de ponderaciones. Las ponderaciones alfa asignan una importancia a cada factor débil y se usan para determinar una predicción general. Un error de épsilon es un error interno asociado con un factor débil que se usa para calcular las ponderaciones alfa. Cada tupla de entrenamiento tiene una ponderación interna (con el nombre D en literatura de boosting adaptativo) que se usa para calcular los errores de épsilon.

En seudocódigo, el método MakeLearners funciona así:

initialize an empty result list of learners
for each feature loop
  for each value of curr feature loop
    scan training data to determine most likely -1, +1 result
    if no most likely result, skip curr value
    create a new learner object with feature, value, predicted
    add learner object to result list
  end each value
end each feature
for each learner in result list
  for each training data item
    if learner isn't applicable to data, skip curr data item
    compute raw error rate
    store raw error into learner
  end each training data item
end each learner

La idea es que cada valor de característica como “Atlanta” (oponente) o “Medium” (extensión de punto) generará una regla de factor débil basada en los datos de entrenamiento, a menos que el valor no aparezca en los datos de entrenamiento (por ejemplo, un oponente de "New York") o no arroje un resultado más probable porque son el mismo número de victorias y derrotas asociadas con el valor (por ejemplo, cuando el oponente es "Atlanta" en los datos de demostración, con una victoria y una derrota).

En resumen

Una variación importante del algoritmo presentado en este artículo tiene que ver con los datos que tienen valores numéricos. Por ejemplo, supongamos que los valores para la característica de punto de extensión, en lugar de ser categórica“Small,” “Medium” y “Large,” fuera numérica, como 1,5, 3,0 y 9,5. Una de las ventajas principales de la clasificación de boosting adaptativo comparado con algunas otras técnicas de clasificación es que el boosting adaptativo puede controlar fácilmente datos categóricos y numéricos directamente. Podría crear una clase de factor dedicado que tuviera una descripción sencilla similar a "si Spread es menor que o igual a 5,5, entonces Result es Lose", o un factor más complejo parecido a "si Spread está entre 4,0 y 6,0, entonces Result es Win".

En mi opinión, la clasificación de boosting adaptativo se usa al máximo cuando la variable dependiente que se va a predecir tiene solo dos valores posibles. Sin embargo, las formas avanzadas de boosting adaptativo pueden administrar una clasificación multinomial. Si desea investigar esto o la teoría detrás del boosting adaptativo en general, recomiendo buscar artículos de los investigadores R. Schapire e Y. Freund.

La investigación de aprendizaje automático sugiere que no existe ninguna otra técnica/clasificación mejor de datos. Pero el boosting adaptativo es un enfoque muy eficaz que puede formar la base de agregar características predictivas a un sistema de software .NET.

El Dr. James McCaffrey  trabaja en Volt Information Sciences Inc., donde está a cargo del entrenamiento técnico de los ingenieros informáticos que trabajan en el campus de Microsoft en Redmond, Washington. Ha colaborado en el desarrollo de varios productos de Microsoft como, por ejemplo, Internet Explorer y MSN Search. Es el autor de “.NET Test Automation Recipes” (Apress, 2006) y se puede ubicar en la dirección de correo electrónico jammc@microsoft.com.

Gracias a los siguientes expertos técnicos por su ayuda en la revisión de este artículo: Darren Gehring (Microsoft)