Il presente articolo è stato tradotto automaticamente.

Esecuzione di test

Classificazione con regressione logistica tramite ottimizzazione con sciami multipli

James McCaffrey

Scaricare il codice di esempio

James McCaffreyUno dei moduli principali di apprendimento automatico è la classificazione di regressione logistica (LR). L'obiettivo della classificazione LR consiste nel creare un modello che prevede una variabile che può assumere uno dei due valori possibili. Ad esempio, è possibile prevedere quale dei due candidati elettore selezionerà ("Smith" = 0, "Jones" = 1) in base alla durata dell'elettore (x1), sesso (2) e reddito annua (3).

Se Y è il valore previsto, un modello LR per questo problema dovrebbe assumere la forma:

z = b0 + b1(x1) + b2(x2) + b3(x3)
Y = 1.0 / (1.0 + e^-z)

In questo caso, b0, b1, b2 e b3 sono pesi, sono valori numerici solo che devono essere determinati. In parole, è possibile calcolare un valore z è la somma dei valori di input volte b pesi, oltre a una costante b0 quindi feed il valore z all'equazione che utilizza espressioni matematiche costante e. Ho scoperto che Y sarà sempre compreso tra 0 e 1. Se Y è minore di 0,5, è possibile concludere l'output è 0 e se Y è maggiore di 0,5 si concludono che l'output è 1.

Ad esempio, si supponga che l'età dell'elettore è 32, sesso è maschio (-1) e annuale reddito in decine di migliaia di dollari è 48.0. E si supponga che b0 =-9.0, b1 = 8.0, b2 = 5.0 e b3 = -5.0. Quindi z =-9.0 + (8.0)(32) + (5.0)(-1) + (-5.0)(48.0) = 2.0 e in tal caso Y = 1.0 / (1.0 + e ^ 2.0) = 0.88.

Poiché Y è maggiore a 0,5, si potrebbe concludere che l'elettore sceglierà candidate 1 ("Jones"). Ma i valori di peso b da dove provengono? Formazione di un classificatore LR è il processo di ricerca di valori per i pesi di b. L'idea consiste nell'utilizzare dati di training che ha definito i valori di output e quindi trovare il set di valori di b in modo che la differenza tra i valori di output calcolate e i valori di output che viene ridotto a icona. Si tratta di un problema matematico che viene spesso chiamato ottimizzazione numerica.

Sono disponibili su una dozzina gli algoritmi di ottimizzazione principali utilizzati in apprendimento automatico. Per la formazione di classificazione di regressione logistica, due degli algoritmi più comuni sono chiamati iterativo Newton-Raphson e BFGS L. In questo articolo, presenterò una tecnica denominata ottimizzazione multi-sciame (MSO). MSO è una variazione di ottimizzazione sciame di particelle (PSO). In MSO, una particella virtuale dispone di una posizione che corrisponde a un insieme di valori di peso b. Uno sciame è un insieme di particelle che si spostano in modo ispirato dal comportamento di gruppo, ad esempio il floccaggio di uccelli. MSO mantiene sciami diverse che interagiscono tra di loro, invece di PSO, che utilizza un unico sciame.

Un buon metodo per vedere dove questo articolo è diretto e per avere un'idea di ciò che è LR con MSO, consiste nell'esaminare il programma demo in Figura 1. L'obiettivo del programma demo consiste nell'utilizzare MSO per creare un modello LR predice Y per un set di dati (a livello di codice generati) sintetici.

la regressione logistica con ottimizzazione multi-sciame in azione
Figura 1 la regressione logistica con ottimizzazione multi-sciame in azione

Il programma demo inizia con la creazione di 10.000 elementi di dati casuali cui sono presenti cinque variabili predittive (spesso denominati funzionalità nella terminologia ML). Ogni valore di funzione è compreso tra -10.0 e +10.0 e il valore di Y, 0 o 1, è nell'ultima colonna del set di dati. I valori di funzione non corrispondono a un vero problema.

Il set di dati di 10.000 elementi in modo casuale è suddiviso in un set di addestramento 8.000 elemento utilizzato per creare il modello LR e un set di test-out di esenzione elemento 2.000 utilizzata per valutare l'accuratezza del modello dopo la formazione. Il programma demo crea un classificatore LR e quindi utilizza quattro sciami, ognuno con tre particelle, per formare il classificatore. MSO è un processo iterativo e il numero massimo di iterazioni, maxEpochs, è impostato su 100.

La demo viene visualizzato l'errore di (dal più piccolo) migliore trovato particelle, ogni 10 periodi. Al termine della formazione, i pesi ottimali trovati sono (4.09, 10,00, 8.43, 1,86,-9.27, 1.84). Utilizzando tali pesi, l'accuratezza del modello LR è calcolato per i dati di training (pari al 99.98% risolvere, ovvero 7,998 di 8.000) e per i dati di test (99.85% risolvere, ovvero 1,997 di 2.000). L'accuratezza del modello con i dati di test fornisce un'approssimazione generica del modello come farebbe quando verrà visualizzata con i nuovi dati che include un valori di output.

In questo articolo si presuppone che si hanno almeno intermedi delle capacità di programmazione, ma non di che esperti sulla classificazione di regressione logistica o ottimizzazione multi sciame. Il programma demo viene codificato tramite C#, ma non dovrebbe essere eccessiva difficoltà refactoring del codice a un altro linguaggio quale Visual Basic .NET o Python.

Il codice demo è troppo lungo per presentare qui nella sua interezza, ma il codice sorgente completo è disponibile nel download del codice che accompagna questo articolo. Il codice demo presenta tutti errore normale controllo rimosso per mantenere ridotte le idee principali in evidenza le possibili e le dimensioni del codice.

Struttura generale del programma

La struttura generale del programma, con poche modifiche per risparmiare spazio, è presentata in Figura 2. Per creare la demo, ho avviato Visual Studio e create una nuova applicazione console C# denominata LogisticWithMulti. La demo non ha alcuna dipendenza di Microsoft.NET Framework significativi, in modo che tutte le versioni recenti di Visual Studio funzionerà.

Figura 2 struttura generale del programma

using System;
namespace LogisticWithMulti
{
  class LogisticMultiProgram
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Begin demo");
      int numFeatures = 5;
      int numRows = 10000;
      int seed = 0;
      Console.WriteLine("Generating " + numRows +
        " artificial data items with " + numFeatures + " features");
      double[][] allData = MakeAllData(numFeatures, numRows, seed);
      Console.WriteLine("Done");
      Console.WriteLine("Creating train and test matrices");
      double[][] trainData;
      double[][] testData;
      MakeTrainTest(allData, 0.80, seed, out trainData, out testData);
      Console.WriteLine("Done");
      Console.WriteLine("Training data: ");
      ShowData(trainData, 4, 2, true);
      Console.WriteLine("Test data: ");
      ShowData(testData, 3, 2, true);
      Console.WriteLine("Creating Logistic Regression classifier");
      LogisticClassifier lc = new LogisticClassifier(numFeatures);
      int numSwarms = 4;
      int numParticles = 3;
      int maxEpochs = 100;
      Console.WriteLine("Setting numSwarms = " + numSwarms);
      Console.WriteLine("Setting numParticles = " + numParticles);
      Console.WriteLine("Setting maxEpochs = " + maxEpochs);
      Console.WriteLine("\nStarting training");
      double[] bestWeights = lc.Train(trainData, maxEpochs,
        numSwarms, numParticles);
      Console.WriteLine("Training complete");
      Console.WriteLine("Best weights found:");
      ShowVector(bestWeights, 4, true);
      double trainAcc = lc.Accuracy(trainData, bestWeights);
      Console.WriteLine("Accuracy on training data = " +
        trainAcc.ToString("F4"));
      double testAcc = lc.Accuracy(testData, bestWeights);
      Console.WriteLine("Accuracy on test data = " +
        testAcc.ToString("F4"));
      Console.WriteLine("End demo");
      Console.ReadLine();
    } // Main
    static double[][] MakeAllData(int numFeatures,
      int numRows, int seed) { . . }
    static void MakeTrainTest(double[][] allData, 
      double trainPct, int seed,
      out double[][] trainData, out double[][] testData) { . . }
    static void ShowData(double[][] data, int numRows,
      int decimals, bool indices) { . . }
    static void ShowVector(double[] vector, int decimals,
      bool newLine) { . . }
  } // Program
  public class LogisticClassifier { . . }
} // ns

Dopo il codice del modello caricato nell'editor di Visual Studio , in Esplora soluzioni finestra dopo aver rinominato il file Program.cs al LogisticMultiProgram.cs e Visual Studio più descrittivo automaticamente rinominato class Program per me. Nella parte superiore del codice sorgente, eliminato tutto utilizzando istruzioni a cui fa riferimento agli spazi dei nomi non necessari, lasciando solo il riferimento per lo spazio dei nomi System di primo livello.

La classe del programma dispone di metodi di supporto MakeAllData, rendere­TrainTest, ShowData e ShowVector. Tutta la logica di regressione logistica è contenuto in una singola classe di LogisticClassifier. La classe LogisticClassifier contiene le classi di supporto annidate delle particelle, sciame e MultiSwarm per incapsulare i dati MSO e la logica utilizzata durante il training. Queste classi di supporto potrebbero aver definite dall'esterno della classe LogisticClassifier.

Il metodo Main è un forte rumore WriteLine. Istruzioni di chiamata chiave sono abbastanza semplici. I dati sintetici vengono generati, come segue:

int numFeatures = 5;
int numRows = 10000;
int seed = 0; // Gives representative demo
double[][] allData = MakeAllData(numFeatures, numRows, seed);

Metodo MakeAllData consente di creare valori casuali b-peso compreso tra -10.0 e +10.0, quindi per ogni elemento di dati, i valori x casuali compreso tra -10.0 e +10.0 vengono generati e combinati con i valori di peso b, quindi vengono utilizzati per generare i valori Y. I dati sintetici corrispondono a un insieme di dati cui sono stati normalizzati i valori x e in cui sono presenti più o meno uguali conteggi di Y = 0 e Y = 1 valori.

I dati vengono suddivisi in una formazione e set di test con le seguenti istruzioni:

double[][] trainData;
double[][] testData;
MakeTrainTest(allData, 0.80, seed, out trainData, out testData);

Il modello LR viene creato e addestrato con queste istruzioni:

LogisticClassifier lc = new LogisticClassifier(numFeatures);
int numSwarms = 4;
int numParticles = 3;
int maxEpochs = 100;
double[] bestWeights = lc.Train(trainData, 
  maxEpochs, numSwarms, numParticles);

E l'accuratezza del modello viene valutato con queste due istruzioni:

double trainAcc = lc.Accuracy(trainData, bestWeights);
double testAcc = lc.Accuracy(testData, bestWeights);

Comprendere l'algoritmo MSO

Ecco l'ottimizzazione MSO in pseudo-codice ad alto livello:

for-each swarm
  initialize each particle to a random position
end-for
for-each swarm
  for-each particle in swarm
    compute new velocity
    use new velocity to compute new position
    check if position is a new best
    does particle die?
    does particle move to different swarm?
  end-for
end-for
return best position found

La parte chiave dell'algoritmo MSO è calcolo della velocità di una particella, che è semplicemente un insieme di valori che il controllo a cui verrà spostata una particella. Ad esempio, per un problema con due sole x-dimensioni, se è una particella (6.0, 8.0) e la velocità è (2.0, 1,0), sarà la nuova posizione della particella in (4.0, 9.0).

Velocità viene calcolato in modo che una particella tende a spostarsi nella direzione di corrente; Cerca di spostare verso la posizione migliore trovata per data; Cerca di spostare verso la posizione migliore trovato da uno qualsiasi dei suoi membri di altri sciame; e cerca di spostare verso la posizione migliore trovato particelle in qualsiasi sciame.

In termini matematici, se x(t) è la posizione di una particella al tempo t, quindi una nuova velocità, v(t+1) viene calcolato come:

v(t+1) = w * v(t) +
         (c1 * r1) * (p(t) - x(t)) +
         (c2 * r2) * (s(t) - x(t)) +
         (c3 * r3) * (g(t) - x(t))

P(t) termine è la posizione più noto della particella. S(t) termine è la posizione migliore di qualsiasi particella in sciame della particella. G(t) termine è la posizione migliore globale di qualsiasi particella in qualsiasi sciame. Termine w è una costante denominata il fattore di inerzia. C3, c2 e c1 termini sono costanti che consentono di stabilire una variazione massima per ogni componente della nuova velocità. Termini r1, r2 e r3 e casuali compresi tra 0 e 1 che forniscono un effetto di casualità per ogni aggiornamento di velocità.

Si supponga che si trova attualmente una particella (20,0, 30,0) e la velocità corrente è (-1.0,-3.0). Inoltre, è la posizione più noto della particella (10.0, 12.0), è la posizione più noto di particelle nello sciame (8.0, 9.0), ed è la posizione più noto di particelle in qualsiasi sciame (5.0, 6.0). E si supponga che w costante con valore 0,7, c2 e c1 costanti sono entrambi 1.4 e costante c3 è 0.4. Infine, si supponga di valori casuali r1, r2 e r3 sono tutti 0.2.

È la nuova velocità della particella (con arrotondamento a un decimale):

v(t+1) = 0.7 * (-1.0, -3.0) +
         (1.4 * 0.2) * ((10.0, 12.0) - (20.0, 30.0)) +
         (1.4 * 0.2) * ((8.0, 9.0) - (20.0, 30.0)) +
         (0.4 * 0.2) * ((5.0, 6.0) - (20.0, 30.0))
       = 0.7 * (-1.0, -3.0) +
         0.3 * (-10.0, -18.0) +
         0.3 * (-12.0, -21.0) +
         0.1 * (-15.0, -24.0)
       = (-8.8, -16.2)

E pertanto la nuova posizione della particella è:

x(t+1) = (20.0, 30.0) + (-8.8, -16.2)
       = (11.2, 13.8)

Il grafico in nella figura 3 illustra il processo MSO per un problema con i valori x di due, tre swarms con cinque particelle ogni, e in cui la posizione ottimale (0, 0). Il grafico mostra come la prima particella in ogni sciame scade posizione ottimale. Il movimento a spirale è caratteristica di MSO.

l'algoritmo di ottimizzazione multi-sciame illustrato
Figura 3, l'algoritmo di ottimizzazione multi-sciame illustrato

Nel pseudo-codice di MSO, una particella può muoiono con alcune probabilità bassa. Quando una particella si interrompe, verrà sostituito con una nuova particella in una posizione casuale. Una particella può immigrate con alcune probabilità bassa. Quando si verifica l'immigrazione, una particella viene scambiata con un'altra particella da uno sciame diverso. I meccanismi di morte e immigrazione aggiungere un elemento di casualità per MSO e impedire che l'algoritmo rimangono bloccati in una soluzione non ottimale.

Implementazione di regressione logistica mediante MSO

Come si inizia la definizione di metodo treno:

public double[] Train(double[][] trainData, int maxEpochs,
  int numSwarms, int numParticles)
{
  int dim = numFeatures + 1;
  double minX = -10.0;
  double maxX = 10.0;
  MultiSwarm ms = new MultiSwarm(numSwarms, numParticles, dim);
...

La dimensione del problema è il numero di funzionalità predittive, più uno, per tenere in considerazione la costante b0. MaxX e minX variabili tenere i valori minimo e massimo per ogni singolo valore nella matrice di posizione dell'oggetto di una particella. La classe LogisticClassifier contiene una classe nidificata MultiSwarm. Il costruttore della classe MultiSwarm crea una matrice di matrici di oggetti delle particelle, ciascuno dei quali ha inizialmente una posizione casuale e una velocità casuale. Poiché il metodo di errore di regressione logistica non è direttamente visibile per la definizione delle particelle nidificata, il costruttore MultiSwarm non fornisce il valore di errore per ogni particella, in modo che il metodo treno aggiunge informazioni sull'errore. In primo luogo, ciascuna particella Ottiene un valore di errore:

for (int i = 0; i < numSwarms; ++i)
{
  for (int j = 0; j < numParticles; ++j)
  {
    Particle p = ms.swarms[i].particles[j];
    p.error = Error(trainData, p.position);
    p.bestError = p.error;
    Array.Copy(p.position, p.bestPosition, dim);
...

Successivamente, vengono calcolati errore migliore del sciame corrente e l'errore migliore globale nel complesso:

...
    if (p.error < ms.swarms[i].bestError) // Swarm best?
    {
      ms.swarms[i].bestError = p.error;
      Array.Copy(p.position, ms.swarms[i].bestPosition, dim);
    }
    if (p.error < ms.bestError) // Global best?
    {
      ms.bestError = p.error;
      Array.Copy(p.position, ms.bestPosition, dim);
    }
  } // j
} // i

Il ciclo di formazione principale è pronto, in questo modo:

int epoch = 0;
double w = 0.729; // inertia
double c1 = 1.49445; // particle
double c2 = 1.49445; // swarm
double c3 = 0.3645; // multiswarm
double pDeath = 1.0 / maxEpochs;
double pImmigrate = 1.0 / maxEpochs;
int[] sequence = new int[numParticles];
for (int i = 0; i < sequence.Length; ++i)
  sequence[i] = i;

I valori per le costanti w, c1 e c2 sono il risultato di alcune ricerche PSO. È interessante notare che, rispetto a molti algoritmi di ottimizzazione numerica, PSO e MSO sono relativamente indipendenti dalla lingua per i valori utilizzati per le costanti magica interne (chiamate gratuite parametri o hyper). Esiste una piccola ricerca disponibile per la costante c3, che influenza la tendenza alla fissazione di una particella si muovono verso la posizione più noto disponibile alla data di particelle in qualsiasi sciame. Il valore di che utilizzo, 0.3645, è la metà del valore della costante di inerzia e ha funzionato bene per me in pratica.

La matrice di sequenza contiene indici dei dati di training. Questa matrice verrà alterata in modo che in ogni sciame particelle verranno elaborate in modo diverso in ogni iterazione del ciclo di formazione.

Inizia il ciclo di formazione:

while (epoch < maxEpochs)
{
  ++epoch;
  // Optionally print best error here
  for (int i = 0; i < numSwarms; ++i) // Each swarm
  {
    Shuffle(sequence);
    for (int pj = 0; pj < numParticles; ++pj) // Each particle
    {
      int j = sequence[pj];
      Particle p = ms.swarms[i].particles[j];
...

Sapere quando interrompere l'addestramento è una delle sfide più difficili in apprendimento automatico. In questo caso, viene utilizzato un numero fisso, maxEpochs, di iterazioni. Questo è un approccio semplice, ma esiste un rischio che potrebbe non essere treno sufficientemente. Potrebbe in treno troppo gran parte, con la conseguenza di un modello che corrisponde ai dati di formazione estremamente favorevole, ma funziona male su nuovi dati. Si tratta di raccordi in eccesso. Esistono decine di tecniche che possono essere utilizzati per combattere l'eccesso di raccordo.

Successivamente, viene calcolata la nuova velocità per la particella corrente, come spiegato in precedenza (vedere Figura 4).

Figura 4 la velocità nuova particella corrente viene calcolata

for (int k = 0; k < dim; ++k)
{
  double r1 = rnd.NextDouble();
  double r2 = rnd.NextDouble();
  double r3 = rnd.NextDouble();
  p.velocity[k] = (w * p.velocity[k]) +
    (c1 * r1 * (p.bestPosition[k] - p.position[k])) +
    (c2 * r2 * (ms.swarms[i].bestPosition[k] - p.position[k])) +
    (c3 * r3 * (ms.bestPosition[k] - p.position[k]));
  if (p.velocity[k] < minX)
    p.velocity[k] = minX;
  else if (p.velocity[k] > maxX)
    p.velocity[k] = maxX;
} // k

Dopo la velocità di calcolo, ciascuno dei valori dei relativi componenti viene controllato per verificare se l'ordine di grandezza è grande, e se in questo modo, il valore è necessario tornare. Ciò impedisce che una particella lo spostamento di una distanza molto grande in qualsiasi iterazione di uno. Per alcune attività di formazione ML, eliminando il limite di velocità viene visualizzato per velocizzare la formazione, ma nessun risultato di ricerca continua a esprimere qui eventuali pareri specifici.

Successivamente, la nuova velocità viene utilizzata per calcolare la nuova posizione della particella corrente e errore associato:

for (int k = 0; k < dim; ++k)
{
  p.position[k] += p.velocity[k];
  if (p.position[k] < minX)
    p.position[k] = minX;
  else if (p.position[k] > maxX)
    p.position[k] = maxX;
}

Dopo che ha spostato la particella corrente, viene calcolato il nuovo errore:

p.error = Error(trainData, p.position); // Expensive
if (p.error < p.bestError) // New best position for particle?
{
  p.bestError = p.error;
  Array.Copy(p.position, p.bestPosition, dim);
}

Nuovo errore della particella corrente potrebbe essere meglio uno sciame di nuovo migliore o globale:

if (p.error < ms.swarms[i].bestError) // New best for swarm?
{
  ms.swarms[i].bestError = p.error;
  Array.Copy(p.position, ms.swarms[i].bestPosition, dim);
}
if (p.error < ms.bestError) // New global best?
{
  ms.bestError = p.error;
  Array.Copy(p.position, ms.bestPosition, dim);
}

Dopo la particella corrente è stato spostato, è un'opzione eventualmente abbattere tale particella e crearne uno nuovo. Se un valore casuale è inferiore a soglia alcuni piccolo, viene generata una nuova particella:

double p1 = rnd.NextDouble();
if (p1 < pDeath)
{
  Particle q = new Particle(dim); // A replacement
  q.error = Error(trainData, q.position);
  Array.Copy(q.position, q.bestPosition, dim);
  q.bestError = q.error;

Invece di utilizzare una probabilità fissa di morte, in alternativa è possibile aumentare gradualmente la probabilità di morte, ad esempio:

double pDeath = (maxProbDeath / maxEpochs) * epoch;

Dopo aver creata la particella di sostituzione, tale particella può essere, per fortuna puro, uno sciame di nuovo migliore o globale migliore:

if (q.error < ms.swarms[i].bestError) // Best swarm error by pure luck?
{
  ms.swarms[i].bestError = q.error;
  Array.Copy(q.position, ms.swarms[i].bestPosition, dim);
  if (q.error < ms.bestError) // Best global error?
  {
    ms.bestError = q.error;
    Array.Copy(q.position, ms.bestPosition, dim);
  }
}

Il meccanismo di morte conclude scambiando la particella corrente per la sostituzione, in modo efficace abbattimento la particella corrente:

...
  ms.swarms[i].particles[j] = q;
} // Die

A questo punto, il meccanismo di immigrazione (facoltativo) inizia con:

double p2 = rnd.NextDouble();
if (p2 < pImmigrate)
{
  int ii = rnd.Next(0, numSwarms); // rnd swarm
  int jj = rnd.Next(0, numParticles); // rnd particle
  Particle q = ms.swarms[ii].particles[jj]; // q points to other
  ms.swarms[i].particles[j] = q;
  ms.swarms[ii].particles[jj] = p; // the exchange
...

Il meccanismo di immigrazione è piuttosto grezzo. Il codice seleziona uno sciame casuale e quindi una particella casuale da che swarm e quindi scambia la particella casuale con la particella corrente. Nel codice, non esiste alcuna garanzia che la particella selezionata casualmente sarà in uno sciame diverso dalla particella corrente.

Il meccanismo di immigrazione termina con il controllo per vedere se lo scambio di particelle in due sciami ha restituito una o due nuove posizioni sciame migliore:

...
  if (q.error < ms.swarms[i].bestError) // Curr has new position
  {
    ms.swarms[i].bestError = q.error;
    Array.Copy(q.position, ms.swarms[i].bestPosition, dim);
  }
  if (p.error < ms.swarms[ii].bestError) // Other has new position
  {
    ms.swarms[ii].bestError = p.error;
    Array.Copy(p.position, ms.swarms[ii].bestPosition, dim);
  }
} // Immigrate

Metodo treno conclude restituendo la migliore posizione individuata particelle:

...
      } // j - each particle
    } // i - each swarm
  } // while
  return ms.bestPosition;
} // Train

Il valore restituito è un riferimento a una matrice che rappresenta un insieme di pesi di regressione logistica. Un'alternativa secondaria per ridurre le possibilità di un effetto collaterale indesiderato consiste nel copiare i valori di una matrice locale e restituire un riferimento alla matrice locale.

Conclusioni

In questo articolo e il codice associato deve ottenere operativi se si desidera esplorare classificazione regressione logistica mediante ottimizzazione multi-sciame di formazione. MSO è molto più metaueristiche di un algoritmo. Per che intendo che mso è un insieme di principi di progettazione che può essere implementata in modi diversi. Esistono decine di modifiche alla progettazione di base MSO che è possibile provare a utilizzare.

La regressione logistica è uno dei tipi più semplici di classificazione di apprendimento automatico. Per molti problemi di classificazione, LR non funziona correttamente. Tuttavia, molti professionisti ML, compreso me, iniziano in genere un problema di classificazione mediante LR e quindi utilizzano le tecniche più sofisticate, se necessario.

Rispetto alle tecniche di ottimizzazione numerica meno recenti, basati su calculus come sfumatura discendente e L-BFGS, in base alla mia esperienza, formazione mediante MSO tende a produrre i migliori modelli ML ma MSO è quasi sempre un ordine di grandezza più lente.


Ripristino di emergenza. James McCaffreylavora per Microsoft Research di Redmond, WA  Si è occupato di numerosi prodotti Microsoft, inclusi Internet Explorer e Bing. Ripristino di emergenza. McCaffrey può essere contattato al jammc@microsoft.com.

Grazie ai seguenti esperti Microsoft per la revisione dell'articolo: Todd Bello e Sol Alisson