WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Regression erzeugen bei beschränktem Wachstum

 

sqk88024
Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 14.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.01.2019, 14:01     Titel: Regression erzeugen bei beschränktem Wachstum
  Antworten mit Zitat      
Hallo,
ich möchte eine Regression erzeugen bei beschränktem Wachstum (quasi das "Gegenteil" von exponentieller Regression). Dazu habe ich schon bei Youtube eine für mich ganz brauchbare Erklärung gefunden:
https://www.youtube.com/watch?v=HPV2E8g5v6o
mit dem entsprechenden Code dazu:
https://sites.google.com/site/srcom.....l-curve-fitting-in-matlab
Das Beispiel funktionier auch bei mir. Allerdings möchte ich nun folgende Abwandlung vornehmen. Statt einem exponentiellen Wachstum soll nun ein beschränktes Wachstum vorliegen. D. h. die ersten beiden Zeilen werden wie folgt abgewandelt:
Code:

x = [0.0 1.0 2.0 3.0 4.0] ;  % independent variable quantities
y = [3.5 5.5 6.5 7.0 7.25] ;  % dependent variable quantities
 

An welcher Stelle muss der Code nun verändert werden, damit eine entsprechende Regression erstellt werden kann? Mir fehlt noch die richtige Idee wo da der Unterschied genau ist.

Der geamte Code:
Code:

x = [0.0 1.0 2.0 3.0 4.0] ;  % independent variable quantities
y = [3.5 5.5 6.5 7.0 7.25] ;  % dependent variable quantities

Y = log(y);
X = x ;

s_X = sum(X);
s_Y = sum(Y);

s_X_2 = sum(X.^2);
s_XY = sum(X.*Y);

N = length(X) ;
B = (s_XY-(s_X_2*(s_Y/s_X)))/(s_X-(s_X_2*N/s_X)) ;
A = (s_Y - N*B)/s_X;
C = exp(B);

xx = zeros(1,100) ;
yy = zeros(1,100) ;
jj=1;
span = (max(X)-min(X))/100;
for x_i = 0:span:max(X)
xx(jj) = x_i;
yy(jj) = C*exp(A*x_i);
jj=jj+1;
end

f8 = figure(8);
hold on
plot(x,y,'kh')
plot(xx,yy)
hold off
 
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 03.01.2019, 14:27     Titel:
  Antworten mit Zitat      
Hallo,

in dem Code werden die Koeffizienten explizit berechnet. Es müssten also die Formeln angepasst werden, was aufwändig bis unmöglich sein kann.

Mein Vorschlag wäre stattdessen fitnlm (Statistics and Machine Learning Toolbox). Sollte die Toolbox nicht verfügbar sein, geht auch fminsearch , siehe z.B.
https://www.mathworks.com/help/matl.....ing-via-optimization.html

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
sqk88024
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 14.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.01.2019, 15:12     Titel:
  Antworten mit Zitat      
Letztere Idee fand ich sehr gut. Die Rgression läuft auch schon. Allerdings kommt hier wieder eine Exponentialfunktion heraus. Dabei ist doch folgendes
Code:
yfit = A*exp(-lambda*xx);

eigentlich eine allgemeine Form eines nach oben beschränkten Wachstums.

Code:

clc
clear
close all

xx = [0.0 1.0 2.0 3.0 4.0] ;  % independent variable quantities
yy = [3.5 5.5 6.5 7.0 7.25] ;  % dependent variable quantities

fun = @(x)sseval(x,xx,yy);

x0 = rand(2,1);
bestx = fminsearch(fun,x0)

A = bestx(1);
lambda = bestx(2);
yfit = A*exp(-lambda*xx);
f8 =figure(8);
plot(xx,yy,'*');
hold on
plot(xx,yfit,'r');
xlabel('tdata')
ylabel('Response Data and Curve')
title('Data and Best Fitting Exponential Curve')
legend('Data','Fitted Curve')
hold off


%% Funktion zur Regression
% https://de.mathworks.com/help/matla.....ing-via-optimization.html
%
function sse = sseval(x,tdata,ydata)
A = x(1);
lambda = x(2);
sse = sum((ydata - A*exp(-lambda*tdata)).^2);
end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 03.01.2019, 16:53     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Dabei ist doch folgendes
yfit = A*exp(-lambda*xx);
eigentlich eine allgemeine Form eines nach oben beschränkten Wachstums.

Das ist für mich eine normale Exponentialfunktion, die entweder nach 0 oder inf läuft.

Eine nach oben beschränkte Funktion wäre z.B.
Code:
yfit = A./(1+exp(-B*x + C))


Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
sqk88024
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 14.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.01.2019, 17:44     Titel:
  Antworten mit Zitat      
Das von dir beschriebene ist doch logistisches Wachstum
https://de.wikipedia.org/wiki/Datei:Logistische_Funktion.svg
Was ich aber Suche ist nur nach oben beschränktes Wachstum.
https://de.wikipedia.org/wiki/Datei:Wachstum_nach_oben.png
Ich hätte meinem Verständnis nach folgende Formel dafür als richtig erachtet: https://wikimedia.org/api/rest_v1/m.....12cc2c2e9440981863433c96e

Oder befinde ich mich da auf dem Holzweg?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 03.01.2019, 18:12     Titel:
  Antworten mit Zitat      
Hallo,

ich mag Formeln immer lieber... wer was mit welchen Begriffen genau meint...

Problem ist, dass du die jetzt verlinkte Formel verwendet hast. Die enthält insbesondere drei Parameter, du verwendest nur zwei.

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
sqk88024
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 14.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.01.2019, 18:24     Titel:
  Antworten mit Zitat      
Und ich dachte ein Bild sagt mehr als tausend Worte Wink

Ja was ich habe ist nur "normales" exponentielles Wachstum.
A*e^(-lambda*t)
Für begrenztes Wachstum muss ich irgendwie noch eine Schranke errechnen. Der Anfangswert sollte ja ebenfalls "A" sein und sich nicht verändern.
beschränktes Wachstum: S-(S-B0)*exp(-lambda*t)
wobei: S = Schranke und B0 = Startwert (= A?)
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 03.01.2019, 21:33     Titel:
  Antworten mit Zitat      
Hallo,

wenn ich das richtig verstehe, willst du S-(S-B0)*exp(-lambda*t) mit vorgegebenem S verwenden. Dieses S muss aber dann natürlich in die Gleichung rein.

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
sqk88024
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 14.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.01.2019, 00:23     Titel:
  Antworten mit Zitat      
Ja das ist so schon von der Idee her wie ich mir das vorgestellt habe. Jedoch ist mir S noch unbekannt.
Ich habe nochmal etwas weiter recherchiert und folgendermaßen habe ich das Problem gelöst.
Code:

clc
clear
close all
%
x = [0.0 1.0 2.0 3.0 4.0]' ;  % independent variable quantities
y = [3.5 5.5 6.5 7.0 7.25]' ;  % dependent variable quantities
%
g = fittype('a-(a-b)*exp(-c*x)','dependent',{'y'},'independent',{'x'},'coefficients',{'a','b','c'})

f = fit(x,y,g)

plot(f,x,y)
 

So schaut das Ergebnis zumindest optisch so aus wie ich es gerne hätte. Für mich als Anfänger kommt das so auch irgendwie einfacher vor. Gibt es da jetzt einen Qualitätsnachteil den ich ggf. übersehen habe? Bzw. was hältst du von dieser Lösung?


Sorge bereitet mir auch noch, dass der Startpunkt zufällig ist. Dadurch ist die Regression nicht immer gleich. Manchmal erscheit eine lineare Funktion (zumindest scheint es so auszuschauen).

Code:

Warning: Start point not provided, choosing random start point.
> In curvefit.attention.Warning/throw (line 30)
  In fit>iFit (line 299)
  In fit (line 108)
  In regress_test_20190103d (line 21)
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.01.2019, 02:08     Titel:
  Antworten mit Zitat      
Hallo,

genau das gleiche hättest du mit der anderen Methode auch machen können. Du musst halt die drei Parameter angeben:
Code:
function sse = sseval(x,tdata,ydata)
a = x(1);
b = x(2);
c = x(3);
sse = sum((ydata - a-(a-b)*exp(-c*tdata)).^2);
end

und dann natürlich auch entsprechende Startwerte.

Wenn man auch nur im geringsten ein Gefühl für die Startwerte hat, sollte man welche angeben. Du weißt ja z.B. vermutlich, in welcher Größenordnung die Schranke ist oder auch dass c negativ sein muss, aber meist betragsmäßig relativ klein.

Der fminsearch-Ansatz minimiert die Summe der quadrierten Abweichungen per Direktsuche. Der Algorithmus sieht quasi nur einen gut-schlecht - Wert.
Tendentiell besser ist dein neuer Ansatz oder eben das von mir empfohlene fitnlm. Da wird nämlich direkt ein Least-Squares-Algorithmus verwendet.
Alle Methoden suchen nach einem lokalen Minimum, das nicht das globale sein muss. Wenn also kein ausreichend guter Startwert bekannt ist, kann man selbst über mehrere Startwerte iterieren oder die Global Optimization Toolbox verwenden.

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
sqk88024
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 14.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.01.2019, 19:25     Titel:
  Antworten mit Zitat      
Ja so funktioniert es wunderbar. Gute Idee mit dem Iterieren!

Code:

clc
clear
close all
%
x = [0.0 1.0 2.0 3.0 4.0]' ;  % independent variable quantities
y = [3.5 5.5 6.5 7.0 7.25]' ;  % dependent variable quantities

start = [7.25 3.5 0];  
up = [inf;inf;inf];
low = [-inf;-inf;-inf];
options = fitoptions('Method','NonlinearLeastSquares','Upper',up,'Lower',low,'Display','iter','TolFun',10^-10,'TolX',10^-10,'StartPoint',start);

g = fittype('a-(a-b)*exp(-c*x)','dependent',{'y'},'independent',{'x'},'coefficients',{'a','b','c'},'options',options)
f = fit(x,y,g)
plot(f,x,y)
v=coeffvalues(f)
 
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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.