2011-11-18 18 views
6

Ho due variabili indipendenti, GSH e Gls. Utilizzando queste due variabili, sto cercando di prevedere un risultato, prob. Utilizzando una funzione della forma:come: solver fondazione quadratica minimi quadrati

prob=a*Gls^2+b*GSH^2+c*Gls+d*GSH+e // (where a,b,c,d,e are coefficients) 

campione di dati:

Gls(2.3 2.3 2.5 2.5 2.5 2.5 2.7 2.7 2.7 2.7 2.7 2.9 2.9 2.9 2.9 2.9 3.1 3.1 3.1 3.1 3.1 3.1 3.3 3.3 3.3 3.3 3.3 3.3 3.5 3.5 3.5 3.5 3.5) 

GSH(0.475 0.525 0.425 0.475 0.525 0.575 0.425 0.475 0.525 0.575 0.625 0.425 0.475 0.525 0.575 0.625 0.375 0.425 0.475 0.525 0.575 0.625 0.375 0.425 0.475 0.525 0.575 0.625 0.425 0.475 0.525 0.575 0.625) 

prob(0.263636 0.324159 0.319328 0.291295 0.286086 0.253994 0.233766 0.284644 0.273818 0.263743 0.175182 0.243986 0.284848 0.28066 0.247863 0.183468 0.181818 0.237288 0.269266 0.2555 0.240924 0.206081 0.209677 0.216949 0.263261 0.25966 0.23588 0.203252 0.239316 0.209184 0.234818 0.242424 0.192118) 

vorrei trovare i migliori valori dei coefficienti per ridurre al minimo la somma dei minimi quadrati.

Ho letto molto sul risolutore di fondotinta, ma non sono riuscito a capire come impostare questo problema nella C# Solver Foundation. Tutti i suggerimenti sul codice sono molto apprezzati.

Grazie

+0

ho capito bene: hai f (gls, gsh) ~ = prob, e vuoi ottimizzare i parametri della funzione del modello? – Efrain

+0

Lavorare su una grande carta teorica può dare un risultato esatto usando la differenziazione.Prova conversione che la carta a una funzione – Dani

risposta

2

Credo che tu non hai bisogno di basi risolutore per questo. Non è necessario l'ottimizzazione numerica, poiché la soluzione (il vettore dei coefficienti polinomiali che riduce al minimo la somma delle distanze verticali quadrate tra le risposte osservate nell'insieme di dati e le risposte previste) esiste in una forma chiusa.

Vedere wikipedia per dettagli.

+1

hi questo è grande per risolvere questo problema (che ho ora fatto utilizzando questo, quindi grazie mille), ma ero anche sperando di imparare come utilizzare fondazione risolutore. – user1054524

0

È possibile utilizzare la fondazione solver. La tua regressione è già non lineare ed è in realtà una generalized linear regression. In R, puoi usare il pacchetto come glm per fare la regressione.

In C#, non sono sicuro che esista un codice open source. Ma comunque, puoi risolvere da solo l'ottimizzazione, e MSF ha un risolutore non lineare in esso! Quindi, basta scrivere due funzioni:

  1. la funzione obiettivo e

  2. suo gradiente

Come esempio veloce, è possibile vedere il mio articolo:

Logistic Regression in F# using Microsoft Solver Foundation

Ma non è necessario conoscere la regressione logistica, nell'articolo, includo anche un esempio più semplice che mostra come ottimizzare una funzione Rosenbrock a 2 variabili.

MSF ha anche un linguaggio specifico di dominio incorporato per C# utilizzando la sua funzione di linguaggio di conversione implicita. [Puoi trovare l'esempio nei documenti di MSF.]

1

La seguente soluzione è molto semplice, solo cercando di trovare il minimo locale utilizzando l'algoritmo che descrivi. Utilizzando io ottenere i seguenti valori

a = ,02,527237 millions, b = ,04,768372 millions, c = -,001549721, d = ,01,382828 millions, e = 0,002026558

con il quadrato totale di ,2139,592 mila.

static void Main(string[] args) 
    { 
     var a = FindLocalMinimum(x => SumSq(x, 0, 0, 0, 0)); 
     var b = FindLocalMinimum(x => SumSq(a, x, 0, 0, 0)); 
     var c = FindLocalMinimum(x => SumSq(a, b, x, 0, 0)); 
     var d = FindLocalMinimum(x => SumSq(a, b, c, x, 0)); 
     var e = FindLocalMinimum(x => SumSq(a, b, c, d, x)); 
    } 

    private static float SumSq(float a, float b, float c, float d, float e) 
    { 
     var gls = new[] 
         { 
          2.3, 2.3, 2.5, 2.5, 2.5, 2.5, 2.7, 2.7, 2.7, 2.7, 2.7, 2.9, 2.9, 2.9, 2.9, 2.9, 3.1, 3.1, 3.1 
          , 3.1, 3.1, 3.1, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.5, 3.5, 3.5, 3.5, 3.5 
         }; 

     var gsh = new[] 
         { 
          0.475, 0.525, 0.425, 0.475, 0.525, 0.575, 0.425, 0.475, 0.525, 0.575, 0.625, 0.425, 0.475, 
          0.525, 0.575, 0.625, 0.375, 0.425, 0.475, 0.525, 0.575, 0.625, 0.375, 0.425, 0.475, 0.525, 
          0.575, 0.625, 0.425, 0.475, 0.525, 0.575, 0.625 
         }; 

     var prob = new[] 
         { 
          0.263636, 0.324159, 0.319328, 0.291295, 0.286086, 0.253994, 0.233766, 0.284644, 0.273818, 
          0.263743, 0.175182, 0.243986, 0.284848, 0.28066, 0.247863, 0.183468, 0.181818, 0.237288, 
          0.269266, 0.2555, 0.240924, 0.206081, 0.209677, 0.216949, 0.263261, 0.25966, 0.23588, 
          0.203252, 0.239316, 0.209184, 0.234818, 0.242424, 0.192118 
         }; 

     var res = 0.0; 
     for (var i = 0; i < prob.Length; i++) 
     { 
      var p = a*Math.Pow(gls[i], 2) + a*Math.Pow(gsh[i], 2) + c*gls[i] + d*gsh[i] + e; 
      res += Math.Pow(p - prob[i], 2); 
     } 
     return (float)res; 
    } 

    private static float FindLocalMinimum(Func<float, float> f) 
    { 
     float bestV = float.MaxValue; 
     float bestX = 0; 
     float x = 0; 
     float lastV = bestV; 
     float diff = 1000.0f; 
     while (Math.Abs(diff) > 0.0001f) 
     { 
      float v = f(x); 
      if (v < bestV) 
      { 
       bestV = v; 
       bestX = x; 
      } 
      else if (v > lastV) 
      { 
       diff *= -0.5f; 
      } 
      lastV = v; 
      x += diff; 
     } 
     return bestX; 
    } 
+0

Buona risposta! Ho trovato un piccolo errore (qui corretto): var p = a * Math.pow (GLS [i], 2) + b * Math.pow (GSH [i], 2) + c * GLS [i] + d * gsh [i] + e; – Hannish