Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   
Bücher:

Studierende:
Praktikant Toolentwicklung Matlab (m/w)
Branche: Technische Dienstleistungen, Fahrzeugtechnik, Fahrzeugteile, Beratung, Expertise
MBtech Group GmbH & Co. KGaA - Fellbach

Abschlussarbeit / Praktikum: Entwicklung Matlab (m/w)
Branche: Informationstechnologie, Elektrotechnik, Elektronik
GIGATRONIK Technologies GmbH - Ulm

Werkstudent (m/w) im Bereich Hochfrequenzmesstechnik
Branche: Mess-, Regel-, Automatisierungstechnik, Telekommunikation, Nachrichtentechnik
ROHDE & SCHWARZ GmbH & Co. KG - München

Praktikum - Funktionsentwicklung im Bereich hochautomatisiertes und autonomes Fahren
Branche: mehrere
IAV GmbH - Ingenieurgesellschaft Auto und Verkehr - Chemnitz

Praktikum - Embedded Software für Multicore Architekturen
Branche: mehrere
IAV GmbH - Ingenieurgesellschaft Auto und Verkehr - Gifhorn

weitere Angebote

Partner:


Vermarktungspartner


Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Fitten von Modell an (Mess-)Daten ohne Toolbox-Abhängigkeit

 

Nras
Forum-Meister

Forum-Meister


Beiträge: 608
Anmeldedatum: 21.02.12
Wohnort: ---
Version: 7.12.0.635 (R2011a)
     Beitrag Verfasst am: 06.07.2015, 12:24     Titel: Fitten von Modell an (Mess-)Daten ohne Toolbox-Abhängigkeit
  Antworten mit Zitat      
Hallo zusammen,

es kommt immer häufiger vor, dass Leute gegebene (Mess-)Daten an ein vorgelegtes Modell fitten wollen und dafür die optimalen Parameter finden möchten. Oftmals führt als Lösung der Weg über die statistics- oder die curve-fitting-Toolbox.

Was aber, wenn man für die angegebenen Toolboxen keine Lizenzen verfügt, beispielsweise jenseits der Universität? Es gibt für genau so einen Fall die Funktion fminsearch . Da ich diesen Weg schon einige Male gegangen bin, habe ich einen Standardfall vorbereitet, der aus gegebenen Daten und einer Modellfunktion mit Angabe einer ersten Schätzung für die Parameter optimale Parameter zurückliefert.

Der damalige Anwendungsfall war das Finden der optimalen Lage der Kontrollpunkte für Bézierkurven. Die Variable order gab dafür die Anzahl der Kontrollpunkte an. In der Variable p standen die x- und y-Koordinaten dieser Kontrollpunkte. Diese Details waren jedoch alle in der fit_function (s.u.) platziert, sodass das anfängliche Rahmenwerk sehr allgemein ist. Aber ganz so kompliziert möchte ich es hier nicht machen.

In dem angegebenen Beispiel erzeuge ich zufällige Daten für x und für y verrauschte Daten eines Polynoms. Anschließend möchte ich die optimalen Parameter (Koeffizienten des Polynoms) finden. Natürlich macht man das eigentlich mit polyfit . Das mache ich aber absichtlich nicht, da ich gerne fminsearch benutzen möchte.

In der fit_function habe ich noch andere Fälle als Kommentar angefügt, die verdeutlichen sollen, dass grundsätzlich alles denkbare damit gelöst werden kann. Ich kann damit durch die Messdaten auch eine Summe eines Sinus und einer Normalparabel legen - sofern ich denn möchte. Es müssen nur die Parameter aus p entsprechend benutzt werden.

Viel Spaß und viel Erfolg mit dem Beispiel.

Code:
function main
% Beispiel für eine Optimierung der Parameter für einen Fit an Messdaten mit fmisearch - ohne Abhängigkeit zu irgendeiner Toolbox.

%% ----- BEISPIELDATEN ERZEUGEN----- %
% Wir erzeugen als Beispieldaten einige zufällige x-Werte und als
% zugehörige y-Werte ein Polynom verrauscht mit Zufallszahlen.
% In einem echten Fall hat man für gewöhnlich bereits Messdaten für x und y
% vorliegen. Beispielsweise könnte x die Zeit beschreiben und y eine
% gemessene Größe (Temperatur, Druck, Windgeschwindigkeit, ...).
x = sort(rand(30, 1))*4;
p_original = [1.5, -1.5, -5, 1];
noise = rand(size(x)) - 0.5;
y = polyval(p_original,x) + noise;

%% ----- WEITERE OPTIMIERUNGSPARAMETER ----- %
% Für bestimmte Fälle, insbesondere bei komplizierten fit-Funktionen will
% man weitere Optimierungsparameter übergeben. Als Beispiel übergeben wir
% noch den Grad des Polynoms, das wir an die Daten fitten wollen.
order = 3;  

%% ----- FINDEN DER PARAMETER ----- %
% In diesem Abschnitt werden die optimalen Parameter gesucht. Wenn wir
% wirklich ein Polynom vom grad order fitten wollen, würde man das
% selbstverständlich mit polyfit() erledigen:
%
% p_fit = polyfit(x, y, order);
%
% Wir wollen jedoch in diesem Beispiel mit fminsearch arbeiten. So haben
% wir die Möglichkeit, ohne die Abhängigkeit von speziellen Toolboxen
% beliebig komplexe fit-Funktionen zu fitten. Dafür rufen wir die eigens
% geschriebene Funktion optimierung() mit unseren Daten x und y, sowie dem
% zusätzlichen Argument "order" auf.
p_fit = optimierung(x, y, order);

%% ----- OPTIONAL: ERGEBNISSE DARSTELLEN ----- %
% Anschließend bietet es sich an, das Ergebnis zu visualisieren.
figure
x_fit = linspace(min(x), max(x), 100); % Mehr Stützstellen für weichen plot
plot(x, y, 'ko')  % Original gestörte Daten
hold on
plot(x_fit, polyval(p_original, x_fit), 'k-')  % Original Polynom
plot(x_fit, fit_function(x_fit, p_fit), 'g')  % Ergebnis von fminsearch
legend('location', 'northwest', 'Gestörte Datenpunkte', ...
       'Originales Polynom', 'Lösung mit Optimierer')
end

%% Hilfsfunktionen
function p_fit = optimierung(x, y, order)
% In dieser Methode wird die Optimierung durchgeführt, indem fminsearch
% mit der zu minimierenden Funktion objFun und zusätzlich einem Startwert
% p0 aufgerufen wird.
% Wir legen der Einfachheit halbe einer Polynom oder Ordnung order durch x
% und y. Dafür brauchen wir order+1 Koeffizienten.
p0 = ones(1, order+1); % wir raten: alle Koeffizienten sind 1
p_fit = fminsearch(@objFun, p0);

% ----- BEGIN: NESTED objFUN -----%
function e = objFun(p)
% Die Funktion objFun bekommt nur p als Parameter übergeben und liefert den
% Wert e zurück, welcher dabei minimiert wird. e ist dabei das Maß, das
% beschreibt, wie gut die aktuell gefundenen Parameter sind, um mit dem
% Modell (fit_function) die Daten (x und y) zu beschreiben. Dafür
% vergleicht man das Ergebnis der fit_function mit den Meswerten. Meistens
% ist dafür "least squares" also die Summe der Fehlerquadrate angebracht.
% In dieser "nested function" leben auch x und y (und ebfennalls auch p0,
% und order), sodass dieser Vergleich gemacht werden kann.
    yfitted = fit_function(x, p);
    e = sum((yfitted-y).^2);    
end
% ----- END: NESTED objFUN -----%

end  % end optimierung()


function yfitted = fit_function(x, p)
% In der fit_function steht die gesamte Magie beschrieben, wie aus den
% x-Werten und dem Vektor "p" zu jedem x-Wert ein y-Wert aus unserem Modell
% gemacht wird. Hierbei können beliebig andere Funktionen aufgerufen
% werden, je nach Komplexität des Problems.
%
% Wir wollen in diesem Beispiel ein Polynom fitten (Fall 1). Dabei ist p
% das Polynom in der Matlab-Repräsentation als Vektor der Koeffizienten, das
% an den Stellen x ausgewertet wird.
%
% Zusätzlich sind noch andere Beispiele angeführt (Fall 2 bis 4), deren
% Sinnhaftigkeit aber lieber nicht näher untersucht werden sollte, sie
% dienen bloß zur Veranschaulichung des Prinzips für komplexere
% fit_functions.

% Fall 1: Polynom
   yfitted = polyval(p, x);

% Fall 2-4: Hier kann auch irgendetwas seltsames stehen.
% Das versteckt man alles in dem p, das übergeben wurde. Die fit-function
% muss bloß die Information in dem p richtig deuten.

% Fall 2: Summe aus Sinus-Welle und skalierter Standardparabel
%     A = p(1);
%     w = p(2);
%     f = p(3);
%     sin_wave = A*sin(2*pi*f*x + w);
%     parabola = p(4)*x.^2;
%     yfitted = sin_wave + parabola;

% Fall 3: Summe aus einer Exponentialfunktion und einer beliebigen Gerade
%     exp_fun = p(1)*exp(p(2)*x);
%     straight_line = polyval(p(3:4), x);
%     yfitted =  exp_fun + straight_line;

% Fall 4: Produkt aus Wurzel und Exponentialfunktion + Verschiebung
%     yfitted = p(1)*sqrt(x).*exp(p(2)*x + p(3)) + p(4);
   
end
Private Nachricht senden Benutzer-Profile anzeigen


Winkow
Moderator

Moderator



Beiträge: 3.834
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 06.07.2015, 12:39     Titel:
  Antworten mit Zitat      
hallo nras
sehr schönes tutorial. vielen dank dafür.
ich lass gleich nochmal den link zum kurzen beispiel von matlab da
Optimal Fit of a Nonlinear Function dort wird auch mit fminsearch gearbeitet.
grüße
_________________

richtig Fragen
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 17.523
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2014a
     Beitrag Verfasst am: 06.07.2015, 14:48     Titel:
  Antworten mit Zitat      
Hallo,

ich sehe es so, dass fminsearch dann die Methode der Wahl ist, wenn weder Statistics Toolbox noch Optimization Toolbox zugänglich sind.

Falls eine der Toolboxen zur Verfügung steht, sind lsqcurvefit (Optimization Toolbox) oder fitnlm (Statistics Toolbox; in älteren Versionen NonLinearModel.fit) einfacher in der Anwendung.
Da die Algorithmen hinter lsqcurvefit und fitnlm gradientenbasiert sind, konvergieren sie zudem meist schneller als fminsearch (Direktsuche).
Die von fitnlm erzeugten NonLinearModel-Objekte machen viele Informationen, z.B. R², leicht zugänglich und haben ein paar Methoden, z.B. coefCI zur Berechnung von Konfidenzintervallen, die man darauf anwenden kann:
Code:
properties('NonLinearModel')
methods('NonLinearModel')


Falls die Modellfunktion linear in den Parametern ist, sind lsqlin bzw. fitlm (früher: LinearModel.fit) am besten geeignet und erfordern keine Startwerte.

Die Curve Fitting Toolbox beinhaltet schließlich noch ein interaktives Tool, das keinerlei Programmierkenntnisse erfordert.
Code:


Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nras
Themenstarter

Forum-Meister

Forum-Meister


Beiträge: 608
Anmeldedatum: 21.02.12
Wohnort: ---
Version: 7.12.0.635 (R2011a)
     Beitrag Verfasst am: 06.07.2015, 17:57     Titel:
  Antworten mit Zitat      
Moin Harald,

Harald hat Folgendes geschrieben:
Hallo,

ich sehe es so, dass fminsearch dann die Methode der Wahl ist, wenn weder Statistics Toolbox noch Optimization Toolbox zugänglich sind.



Wie eingangs erwähnt ist dieses Tutorial für genau diesen Fall gedacht.

Gruß,
Nras.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 17.523
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2014a
     Beitrag Verfasst am: 06.07.2015, 19:11     Titel:
  Antworten mit Zitat      
Hallo Nras,

Zitat:
Wie eingangs erwähnt ist dieses Tutorial für genau diesen Fall gedacht.

Das war bei mir angekommen. Ich denke auch, dass das Tutorial diesen Zweck erfüllt.

Es ist aber ja gut möglich, dass Leute auf diesen Thread stoßen, die die benötigten Toolboxen haben. Daher hielt ich diesen Thread für einen guten Platz, auf die Toolbox-Funktionalitäten und ihre Unterschiede zu fminsearch als auch untereinander hinzuweisen.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
flix_r
Forum-Newbie

Forum-Newbie


Beiträge: 3
Anmeldedatum: 02.10.13
Wohnort: ---
Version: R2013B (8.2.0.701) - win64
     Beitrag Verfasst am: 31.03.2017, 14:14     Titel:
  Antworten mit Zitat      
Hallo Nras,

dein Tutorial ist sehr gut erklärt, vielen Dank.

Ich habe versucht deinen Code auf meine Problemstellung zu übertragen. Leider bekomme ich keine Lösung.
Der Unterschied zu deinem Beispiel sind zum einen die Messdaten (Zeilen 10 / 11) und zum anderen die Zielfunktion (Zeile 88 ).

Falls Du oder jemand anders hier im Forum eine Idee hat, wo der Fehler liegt, bitte melden

Code:

function main
% Beispiel für eine Optimierung der Parameter für einen Fit an Messdaten mit fmisearch - ohne Abhängigkeit zu irgendeiner Toolbox.

%% ----- BEISPIELDATEN ERZEUGEN----- %
% Wir erzeugen als Beispieldaten einige zufällige x-Werte und als
% zugehörige y-Werte ein Polynom verrauscht mit Zufallszahlen.
% In einem echten Fall hat man für gewöhnlich bereits Messdaten für x und y
% vorliegen. Beispielsweise könnte x die Zeit beschreiben und y eine
% gemessene Größe (Temperatur, Druck, Windgeschwindigkeit, ...).
x = [0 0.5 1 1.3]*1e-3;
y = [0 0.38 0.55 0.62]*1e-4;

%% ----- WEITERE OPTIMIERUNGSPARAMETER ----- %
% Für bestimmte Fälle, insbesondere bei komplizierten fit-Funktionen will
% man weitere Optimierungsparameter übergeben. Als Beispiel übergeben wir
% noch den Grad des Polynoms, das wir an die Daten fitten wollen.
order = 3;  

%% ----- FINDEN DER PARAMETER ----- %
% In diesem Abschnitt werden die optimalen Parameter gesucht. Wenn wir
% wirklich ein Polynom vom grad order fitten wollen, würde man das
% selbstverständlich mit polyfit() erledigen:
%
% p_fit = polyfit(x, y, order);
%
% Wir wollen jedoch in diesem Beispiel mit fminsearch arbeiten. So haben
% wir die Möglichkeit, ohne die Abhängigkeit von speziellen Toolboxen
% beliebig komplexe fit-Funktionen zu fitten. Dafür rufen wir die eigens
% geschriebene Funktion optimierung() mit unseren Daten x und y, sowie dem
% zusätzlichen Argument "order" auf.
p_fit = optimierung(x, y, order);

%% ----- OPTIONAL: ERGEBNISSE DARSTELLEN ----- %
% Anschließend bietet es sich an, das Ergebnis zu visualisieren.
figure
x_fit = linspace(min(x), max(x), 100); % Mehr Stützstellen für weichen plot
plot(x, y, 'ko')  % Original gestörte Daten
hold on  
plot(x_fit, fit_function(x_fit, p_fit), 'g')  % Ergebnis von fminsearch
legend('location', 'northwest', 'Gestörte Datenpunkte', ...
       'Lösung mit Optimierer')
end

%% Hilfsfunktionen
function p_fit = optimierung(x, y, order)
% In dieser Methode wird die Optimierung durchgeführt, indem fminsearch
% mit der zu minimierenden Funktion objFun und zusätzlich einem Startwert
% p0 aufgerufen wird.
% Wir legen der Einfachheit halbe einer Polynom oder Ordnung order durch x
% und y. Dafür brauchen wir order+1 Koeffizienten.
p0 = ones(1, order+1); % wir raten: alle Koeffizienten sind 1
p_fit = fminsearch(@objFun, p0);

% ----- BEGIN: NESTED objFUN -----%
function e = objFun(p)
% Die Funktion objFun bekommt nur p als Parameter übergeben und liefert den
% Wert e zurück, welcher dabei minimiert wird. e ist dabei das Maß, das
% beschreibt, wie gut die aktuell gefundenen Parameter sind, um mit dem
% Modell (fit_function) die Daten (x und y) zu beschreiben. Dafür
% vergleicht man das Ergebnis der fit_function mit den Meswerten. Meistens
% ist dafür "least squares" also die Summe der Fehlerquadrate angebracht.
% In dieser "nested function" leben auch x und y (und ebfennalls auch p0,
% und order), sodass dieser Vergleich gemacht werden kann.
    yfitted = fit_function(x, p);
    e = sum((yfitted-y).^2);    
end
% ----- END: NESTED objFUN -----%

end  % end optimierung()


function yfitted = fit_function(x, p)
% In der fit_function steht die gesamte Magie beschrieben, wie aus den
% x-Werten und dem Vektor "p" zu jedem x-Wert ein y-Wert aus unserem Modell
% gemacht wird. Hierbei können beliebig andere Funktionen aufgerufen
% werden, je nach Komplexität des Problems.
%
% Wir wollen in diesem Beispiel ein Polynom fitten (Fall 1). Dabei ist p
% das Polynom in der Matlab-Repräsentation als Vektor der Koeffizienten, das
% an den Stellen x ausgewertet wird.
%
% Zusätzlich sind noch andere Beispiele angeführt (Fall 2 bis 4), deren
% Sinnhaftigkeit aber lieber nicht näher untersucht werden sollte, sie
% dienen bloß zur Veranschaulichung des Prinzips für komplexere
% fit_functions.

% Fall 1: Zielfunktion
   yfitted = (p(1).*x+p(2).*x.^1.5)/sqrt(p(3)+p(4).*x.^2);

% Fall 2-4: Hier kann auch irgendetwas seltsames stehen.
% Das versteckt man alles in dem p, das übergeben wurde. Die fit-function
% muss bloß die Information in dem p richtig deuten.

% Fall 2: Summe aus Sinus-Welle und skalierter Standardparabel
%     A = p(1);
%     w = p(2);
%     f = p(3);
%     sin_wave = A*sin(2*pi*f*x + w);
%     parabola = p(4)*x.^2;
%     yfitted = sin_wave + parabola;

% Fall 3: Summe aus einer Exponentialfunktion und einer beliebigen Gerade
%     exp_fun = p(1)*exp(p(2)*x);
%     straight_line = polyval(p(3:4), x);
%     yfitted =  exp_fun + straight_line;

% Fall 4: Produkt aus Wurzel und Exponentialfunktion + Verschiebung
%     yfitted = p(1)*sqrt(x).*exp(p(2)*x + p(3)) + p(4);
   
end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 17.523
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2014a
     Beitrag Verfasst am: 31.03.2017, 21:12     Titel:
  Antworten mit Zitat      
Hallo,

das Problem liegt in der Funktionsauswertung zum Plotten: du schickst einen x-Vektor rein, aber deine Funktion gibt da nur einen Skalar zurück. Wenn du / in der Zielfunktion durch ./ ersetzt, sieht es besser aus.
Davon abgesehen ist es nicht möglich, 4 Parameter sinnvoll durch 3 Datenpunkte zu bestimmen.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.


goMatlab ist ein Teil des goForen-Labels
goForen.de goMATLAB.de goLaTeX.de goPCB.de


 Impressum  | Nutzungsbedingungen  | Datenschutz  | Werbung/Mediadaten | Studentenversion | FAQ | goMatlab RSS Button RSS


Copyright © 2007 - 2017 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
Partner: LabVIEWforum.de

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.