J'ai utilisé un code trouvé dans la question How to apply piecewise linear fit in Python?, pour effectuer une approximation linéaire segmentée avec un seul point d'arrêt.Ajustement linéaire par morceaux avec n points d'arrêt
Le code est le suivant:
from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15], dtype=float)
y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03])
def piecewise_linear(x, x0, y0, k1, k2):
return np.piecewise(x,
[x < x0],
[lambda x:k1*x + y0-k1*x0, lambda x:k2*x + y0-k2*x0])
p , e = optimize.curve_fit(piecewise_linear, x, y)
xd = np.linspace(0, 15, 100)
plt.plot(x, y, "o")
plt.plot(xd, piecewise_linear(xd, *p))
J'essaie de comprendre comment je peux l'étendre à gérer n points d'arrêt.
J'ai essayé le code suivant pour la méthode piecewise_linear() pour gérer 2 points d'arrêt, mais cela ne modifie en rien les valeurs des points d'arrêt.
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], dtype=float)
y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03, 150, 152, 154, 156, 158])
def piecewise_linear(x, x0, x1, a1, b1, a2, b2, a3, b3):
return np.piecewise(x,
[x < x0, np.logical_and(x >= x0, x < x1), x >= x1 ],
[lambda x:a1*x + b1, lambda x:a2*x+b2, lambda x: a3*x + b3])
p , e = optimize.curve_fit(piecewise_linear, x, y)
xd = np.linspace(0, 20, 100)
plt.plot(x, y, "o")
plt.plot(xd, piecewise_linear(xd, *p))
Toute entrée serait grandement apprécié
'' 'Il n'a pas work''' est à peu près la description inutile. Je pense aussi que vous n'atteindrez pas cela avec curve_fit(), qui devient plus complexe quand il y a plusieurs points d'arrêt (il faudrait des contraintes linéaires pour gérer b0
sascha
Je pense que si je distribue initialement les points de rupture uniformément sur l'axe des abscisses, alors trouver des minimums locaux sera suffisant pour fournir une solution décent non optimale. Connaissez-vous un autre module d'optimisation qui supporte les contraintes linéaires? –
Comme je vous l'ai dit, ce n'est pas seulement à propos de ça. En ignorant la fluidité et la non-convexité potentielle, vous pouvez résoudre ce problème avec les fonctions d'optimisation plus générales de scipy, à savoir COBYLA et SQSLP (les deux seules contraintes de support). La seule vraie approche que je vois serait la programmation convexe mixte-integer, mais le logiciel est clairsemé (bonmin et couenne étant deux solveurs open-source pas très sympa à utiliser de python, pajarito @ julialang, mais cette approche en général a besoin de formulation triviale). – sascha