2016-06-21 5 views
0

eine ähnliche Frage früher bekannt gemacht, aber war viel zu vage, hoffen, dass dies meine Frage aufräumt:Optimierung: Suche nach optimalen Eingänge

Ich habe eine Funktion IVcal(rho,alpha,K) und ich möchte die optimalen Werte von rho und alpha so finden, dass die smiledata Datenliste (die Ausgabe der Funktion zum Verändern K) ist die beste Lösung möglich an die Datenliste calibrate:

xaxis = np.linspace(0.006,0.036,20) 
calibrate = [calfun(K) for K in xaxis] 
smiledata = [IVcal(rho,alpha,K) for K in xaxis] 

die Idee ist, dass ich die Kurve plt.plot(xaxis,smiledata, 'b--') zu sein, wie nah eine Anpassung an die grafischen Darstellung plt.plot(xaxis,calibrate, 'r--') will wie möglich durch variieren g nur rho und alpha.

Ich bin mir nicht sicher, wie man diese optimalen Werte finden kann. Ich dachte darüber nach, den Unterschied zwischen smiledata und calibrate zu nehmen und zu minimieren, aber wieder konnte ich keinen guten Weg finden, dies zu tun, zumal ich den Wert der Eingabe brauche und nicht die Ausgabe. Ich würde mich über jeden Rat und jede Entschuldigung freuen, dass ich vorher vage war. Bitte lassen Sie mich wissen, wenn noch etwas Klärung erforderlich ist.

+0

Was ist die Formel von IVcal (und calfun wenn Sie es) wäre? – syntonym

+0

[Bergsteigen] (https://en.wikipedia.org/wiki/Hill_climbing) vielleicht? – Delgan

+0

Sie sind beide ziemlich lange Formeln, die sich auf mehrere zuvor definierte Funktionen/Ausdrücke beziehen. Ich dachte nicht, dass sie relevant wären, aber wenn Sie sie brauchen, kann ich versuchen, sie zu verdichten? Warum willst du sie, wenn es dir nichts ausmacht, dass ich frage? Ich hätte idealerweise einen allgemeineren Ansatz, der für jede Datenliste der gleichen Länge wie die von lilchedata funktionieren würde (calfun ist nur dazu da, um zu verdeutlichen, dass ich mich annähere, um eine "beste Anpassung" an einen anderen Datensatz zu finden). – Hall93

Antwort

1

Unconstrained

Sie könnten versuchen, scipy.optimize.leastsq

Verwendung Dies ist ein Optimierungsverfahren, das die Differenz zwischen einem aktuellen Satz von Werten und ein Ziel von Werten verringert werden soll.

import scipy.optimize as opt 
import numpy as np 


def calfun(k): 
    """Example calibration function""" 
    return k * 2 * 4 

def IVcal(rho, alpha, k): 
    """Example test function""" 
    return rho * alpha * k 

def error_function(x0, **args): 
    """Calculates error between functions with current inputs""" 
    xaxis = np.linspace(0.006, 0.036, 20) 
    calibrate = np.array([calfun(K) for K in xaxis]) 
    smiledata = np.array([IVcal(x0[0], x0[1], K) for K in xaxis]) 

    # Get error between data 
    error = smiledata - calibrate 

    # Print square root of sum of errors 
    print np.sqrt(np.sum(error**2.0)) 

    return error 

# Initial guesses 
rho = 1 
alpha = 1 
x0 = np.array([rho, alpha]) 

# Run optimisation 
result = opt.leastsq(func=error_function, x0=x0)[0] 
print 'opt rho: ', result[0] 
print 'opt alpha: ', result[1] 

Einige Anmerkungen:

  • Die Qualität der Optimierung auf Ihren Startbedingungen sehr abhängig ist!
  • Konvertieren der Ausgänge des calibrate und smiledata von list zu np.array ermöglicht den Fehler zwischen jedem Wert in beiden Arrays ohne durch Listen
  • nur der erste Eintrag in der Ausgabe der opt.leastsq zu Schleife zu berechnen, wird genommen, wie dies ein Array Ihrer optimierten Variablen
  • die Quadratwurzel Summe von Fehlern Drucken zeigt die Konvergenz des Optimierers

Constrained

Es sieht aus wie aus scipy Version 17 an gibt eine eingeschränkte Version von dest scipy.optimize.least_squares

Von dem obigen Link genannt squared:

Untere und obere Schranken für unabhängige Variablen. Standardmäßig sind keine Grenzen gesetzt. Jedes Array muss der Größe von x0 entsprechen oder ein Skalar sein, im letzteren Fall ist eine Grenze für alle Variablen gleich. Verwenden Sie np.inf mit einem geeigneten Vorzeichen, um Schranken für alle oder einige Variablen zu deaktivieren.

Für Ihren Fall glaube ich, diese

bounds = ([rho_lower, rho_higher],[-np.inf, np.inf]) 
+0

Vielen Dank! Vergessen zu erwähnen, dass Rho nur Werte innerhalb eines Bereichs annehmen soll - ist es möglich, die Domäne eines der Eingänge zu beschränken? – Hall93

+0

Einige Informationen in der Antwort hinzugefügt. Ich kann nicht sagen, dass ich es schon ausprobiert habe, aber ich habe andere Optimierungsmethoden verwendet und die Begrenzung erscheint ähnlich – Wokpak