Regressione lineare e polinomiale : Esempi di regressione lineare e polinomiale in C#

Esempi in C# di regressione lineare e polinomiale.

il
Sviluppatore / Ingegnere informatico / Funzionario, Collaboratore di IProgrammatori

Nell’articolo precedente abbiamo visto che cosa sono la regressione lineare e la regressione polinomiale, da un punto di vista più teorico-matematico.

Vediamo ora un esempio pratico di tracciamento di un grafico in grado di rappresentare una relazione lineare tra diverse coppie di valori, poi vedremo un esempio simile con una regressione polinomiale.

Regressione lineare

Supponiamo di voler prevedere il prezzo di vendita di una casa in base alla sua superficie, basandoci sui dati seguenti:

Superficie (m²)

Prezzo (EUR)

50

180,000

60

210,000

70

240,000

80

270,000

90

300,000

Utilizzando la regressione lineare, possiamo determinare la relazione tra la superficie e il prezzo.

Supponiamo che l'equazione trovata sia:

Prezzo = 30000 + 3000 × Superficie

Proviamo a utilizzare il codice C# per visualizzare il grafico di questa relazione.

Per semplicità creeremo una applicazione di tipo Windows Forms, per cui potete creare voi stessi una nuova applicazione con questo modello. Una volta pronta, sostituite tutto il codice contenuto nel file Program.cs con quello seguente:

// Regressione lineare in C#
using System;
using System.Collections.Generic;
using OxyPlot;
using OxyPlot.Series;
class Program
{
  static void Main(string[] args)
  {
    // Dati
   List<double> superficie = new List<double> { 50, 60, 70, 80, 90 };
   List<double> prezzo = new List<double> { 180000, 210000, 240000, 270000, 300000 };
    // Coefficienti della retta di regressione
    double beta_0 = 30000;
    double beta_1 = 3000;
    // Calcolo della retta di regressione
    List<double> retta_regressione = new List<double>();
    foreach (double x in superficie)
    {
      retta_regressione.Add(beta_0 + beta_1 * x);
    }
    // Creazione del grafico utilizzando OxyPlot
    var plotModel = new PlotModel { Title = "Regressione Lineare: Superficie vs Prezzo" };
    var scatterSeries = new ScatterSeries { MarkerType = MarkerType.Circle, MarkerFill = OxyColors.Blue };
    for (int i = 0; i < superficie.Count; i++)
    {
     scatterSeries.Points.Add(new ScatterPoint(superficie[i], prezzo[i]));
    }
    var lineSeries = new LineSeries { Color = OxyColors.Red };
    for (int i = 0; i < superficie.Count; i++)
    {
      lineSeries.Points.Add(new DataPoint(superficie[i], retta_regressione[i]));
    }
    plotModel.Series.Add(scatterSeries);
    plotModel.Series.Add(lineSeries);
    // Mostra il grafico (è necessario un visualizzatore per grafici OxyPlot)
    var plotView = new OxyPlot.WindowsForms.PlotView
    {
      Model = plotModel,
      Dock = System.Windows.Forms.DockStyle.Fill
    };
    var form = new System.Windows.Forms.Form { ClientSize = new System.Drawing.Size(800, 600) };
   form.Controls.Add(plotView);
   System.Windows.Forms.Application.Run(form);
  }
}

Noterete sicuramente che in alcune istruzioni vengono identificati degli errori. Il motivo è piuttosto semplice: è necessario aggiungere una libreria di nome Oxyplot. Per svolgere questa operazione potete aprire la voce di menu Strumenti > Gestione pacchetti NuGet > Console di Gestione Pacchetti (o in inglese Tools > NuGet Package Manager > Package Manager Console) e digitare nella console il comando seguente:

Install-Package OxyPlot.WindowsForms

Qualche istante di attesa e tutti gli errori saranno risolti, permettendoci di eseguire il programma e di ottenere il seguente risultato (Fig. 1):

Immagine che contiene testo, schermata, linea, Diagramma

Descrizione generata automaticamente

In questo caso possiamo vedere che la retta passa esattamente sui punti, proprio perché esiste una relazione lineare e quindi esiste anche una retta in grado di rappresentare qualsiasi valore secondo l’equazione data.

Regressione polinomiale

Vediamo ora cosa succede con una nuova serie di dati e utilizzando una regressione polinomiale di secondo grado:

Superficie (m²)

Prezzo (EUR)

50

150,000

60

175,000

70

200,000

80

240,000

90

300,000

Noterete sicuramente che alcuni prezzi sono stati modificati: tra poco sarà evidente come questi sono disposti su una curva crescente.

Creiamo una applicazione Windows Forms e sostituiamo il codice di Program.cs con il seguente:

// Regressione polinomiale in C#
using System;
using System.Collections.Generic;
using OxyPlot;
using OxyPlot.Series;
using MathNet.Numerics.LinearRegression;
class Program
{
  static void Main(string[] args)
  {
    // Dati
    double[] superficie = { 50, 60, 70, 80, 90 };
    double[] prezzo = { 150000, 175000, 200000, 240000, 300000 };
    // Trasformazione polinomiale di grado 2
    double[][] superficie_poly = new double[superficie.Length][];
    for (int i = 0; i < superficie.Length; i++)
    {
      superficie_poly[i] = new double[] { 1, superficie[i], superficie[i] * superficie[i] };
    }
    // Modello di regressione polinomiale
    var result = MultipleRegression.QR(superficie_poly, prezzo);
    // Predizioni
    double[] prezzo_predetto = new double[superficie.Length];
    for (int i = 0; i < superficie.Length; i++)
    {
      prezzo_predetto[i] = result[0] + result[1] * superficie[i] + result[2] * superficie[i] * superficie[i];
    }
    // Creazione del grafico utilizzando OxyPlot
    var plotModel = new PlotModel { Title = "Regressione Polinomiale: Superficie vs Prezzo" };
    var scatterSeries = new ScatterSeries { MarkerType = MarkerType.Circle, MarkerFill = OxyColors.Blue };
    for (int i = 0; i < superficie.Length; i++)
    {
     scatterSeries.Points.Add(new ScatterPoint(superficie[i], prezzo[i]));
    }
    var lineSeries = new LineSeries { Color = OxyColors.Red };
    for (int i = 0; i < superficie.Length; i++)
    {
      lineSeries.Points.Add(new DataPoint(superficie[i], prezzo_predetto[i]));
    }
    plotModel.Series.Add(scatterSeries);
    plotModel.Series.Add(lineSeries);
    // Mostra il grafico (è necessario un visualizzatore per grafici OxyPlot)
    var plotView = new OxyPlot.WindowsForms.PlotView
    {
      Model = plotModel,
      Dock = System.Windows.Forms.DockStyle.Fill
    };
    var form = new System.Windows.Forms.Form { ClientSize = new System.Drawing.Size(800, 600) };
   form.Controls.Add(plotView);
   System.Windows.Forms.Application.Run(form);
  }
}

In questo caso dovete aggiungere la libreria Oxyplot, ma anche una libreria che si chiama MathNet.Numerics che ci servirà per utilizzare la sua classe MultipleRegression.

Install-Package MathNet.Numerics

Ecco, quindi, cosa otteniamo dai dati utilizzati:

Immagine che contiene testo, schermata, Diagramma, linea

Descrizione generata automaticamente

Come potete notare, la curva (per semplicità rappresentata da segmenti) non passa esattamente sui punti: infatti l’obiettivo non è quello di trovare esattamente la curva su cui passano tutti i punti (anche perché molto probabilmente non esiste una curva esatta), bensì di trovare la curva che è in grado di approssimare il più possibile l’andamento dei dati, per poter stimare dei valori non presenti nella tabella.

Conclusione

Ovviamente questo è solo un piccolo esempio, per poter comprendere come si possono ottenere informazioni utili dai dati ed essere in grado di formulare delle previsioni, seppure accettando un piccolo grado di errore (come spesso avviene in molti ambiti di lavoro).

Una intelligenza artificiale è in grado di determinare la curva più appropriata, utilizzando una delle tecniche di regressione, e quindi di fare una previsione basata su un valore fornito dall’utente, anche se nei dati forniti nella fase di training quel valore non c’è.