IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Maximisation fonction Somme de plusieurs variable


Sujet :

Calcul scientifique Python

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Points : 12
    Points
    12
    Par défaut Maximisation fonction Somme de plusieurs variable
    Bonsoir à tous,

    J'ai un petit projet en python à finir et je dois dire que mon niveau est pitoyable....
    J'ai un gros problème et je pense que vous aller pouvoir m'aider, comme son nom l'indique mon problème est de maximiser une fonction de plusieurs variables.

    J'ai vu qu'on pouvait utiliser scipy mais je dois dire que je comprend pas toutes les options ni comment remplir l'optimisation.

    Je vous mets la partie de mon code intéressante.

    Y'a quelque chose que je fais mal mais je vois pas trop quoi et j'ai beau chercher mais google n'est pas mon ami sur ce coup là :S

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
    d=0
    x=[beta,alpha,omega]
    def f(x):
     for k in range (65 ,len(y)):
         d=d+math.log(x[1] + x[2]*V_t[k-1] +x[3] *y[k-1]*y[k-1])+y[k]*y[k]/(x[1] + x[2]*V_t[k-1] +x[3] *y[k-1]*y[k-1])
     return d
    beta=0.6
    alpha =0.399
    omega =0.00001
     
    V_t[1]=z.var()
    V_tt[1]=z.var()
     
     
    for k in range(65,len(y)):
        V_t[k]= omega + beta*V_t[k-1] +alpha *y[k-1]*y[k-1]
        z=y[1+k:64+k]
        V_tt[k]=z.var()
        Vol_t[k]=math.sqrt(V_t[k]*252)
        Vol_tt[k]= math.sqrt(V_tt[k]*252)
     
     
    fmin_tnc(d, x)
    Je dois également mettre des contraintes et je vois absolument pas l'emplacement.....

    Thanks for your Help

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    Citation Envoyé par mcalus Voir le message
    Y'a quelque chose que je fais mal mais je vois pas trop quoi
    à peu près tout ... je ne sais pas par où commencer tellement c'est brouillon.
    Faudrait commencer par faire du code plus clair.

  3. #3
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Tant que ça? :S

    La façon de définir la fonction est complètement à coté de la plaque?
    J'ai 2 gros problèmes. Le 1er 'est au niveau de la définition de la fonction d (qui doit être la somme du truc un peu degue qui suit. Et le second problème (de loin le plus important , la minimisation de ma fonction...C'est vraiment à ce niveau là que je ne sais pas trop quoi faire. Le programme compile sans fmin_tnc se qui me laisse penser qu'il a en mémoire ma fonction ,non?

    Désolé pour le code brouillon et pour mes questions un peu bête mais je débute vraiment en python (en même temps vous avez du le voir....)

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    il est sensé faire quoi ce code ?
    quelles libs tu utilises ?
    c'est quoi cette fonction en plein milieu qui n'est jamais appelée ?
    etc ...

  5. #5
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Sorry pour ce manque d'info.

    J'utilise numpy,math et scipy. Pour la fonction en plein milieu, c'est celle là que je dois minimiser suivant les 3 paramètres.

    En fait le but du programme est de déterminer les valeurs optimales oméga,alpha et béta qui minimise la fonction d.
    En gros d c'est la somme de tout les Vol_t.

    Normalement c'est un Garch(1,1) et je cherche donc les paramètres optimaux. Pour Vol_t et Vol_tt je m'en sers pas dans l'optimisation ils servent juste pour tracer le graphe ensuite.

    J'espère que j'ai été clair, si tu as d'autre remarques n'hésite pas (et merci de t'intéresser à mon problème )

  6. #6
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonjour,



    J'espère que j'ai été clair
    Non. Pas du tout.



    Titre de la file, message #1:
    Maximisation fonction Somme de plusieurs variable
    Message #3:
    de loin le plus important , la minimisation de ma fonction...
    Ça la fout mal. Dans une rubrique intitulée “Calcul scientifique“, il serait de bon ton de faire preuve de plus de cohérence logique.

    En premier, donc, merci de nous indiquer si tu veux minimiser la fonction ou la maximiser.





    Deuxièmement, je ne vois dans ton bout de code que des instructions d’affectation, c’est à dire des instructions avec signe =.

    Or pour trouver le minimum d’une fonction, il faut me semble-t-il réitérer une procédure de variation des valeurs passés comme arguments à la fonction jusqu’à trouver les valeurs qui minimisent le résultat renvoyé par la fonction, et pour cela il faut tester une condition quelque part.

    Il n’y a rien de tel dans ton code.

    La réitération est-elle en dehors ? Cherches tu seulement à écrire ta fonction pour le moment ?









    Quelques remarques maintenant pour débroussailler:



    - quelle version de Python utilises-tu ?



    - pourquoi l’indentation est à 1 colonne dans la définition de la fonction et à 4 colonnes plus loin ?



    - visuellement , c’est mieux d’écrire ta définition de fonction ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f(x):
     for k in range (65 ,len(y)):
         d += math.log(    x[1] + x[2]*V_t[k-1] + x[3]*y[k-1]*y[k-1] )\
              +y[k]*y[k]/( x[1] + x[2]*V_t[k-1] + x[3]*y[k-1]*y[k-1] )
     return d


    - ce serait bien aimable à toi de nous dire ce que c’est que var()



    - écrire
    V_t[k] = omega + beta*V_t[k-1] + alpha*y[k-1]*y[k-1]
    puis quelques lignes suivantes
    Vol_t[k] = math.sqrt(V_t[k]*252)
    ne sert qu’à brouiller le code pour un intérêt approchant de zéro.

    Il vaut mieux écrire tout de suite:
    Vol_t[k] = math.sqrt(( omega + beta*V_t[k-1] + alpha*y[k-1]*y[k-1] )*252)

    et même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vol_t[k] = math.sqrt(252) * math.sqrt( omega + beta*V_t[k-1] + alpha*y[k-1]*y[k-1] )


    - de même:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vol_tt[k]= math.sqrt(252) * math.sqrt( y[1+k:64+k].var() )


    - deux noms V_t et V_tt : bonjour la confusion vuisuelle et les risques d’erreur quand on écrit le code !
    Il faut vraiment choisir des noms plus distincts que ceux-là. M’enfin quoi ....



    - les arguments doivent être passés à la fonction de la façon suivante
    def f(beta,alpha,omega):
    et non pas
    def f( [beta,alpha,omega[ ):
    comme ce à quoi revient ton écriture



    - si x=[beta,alpha,omega] alors
    x[1] est alpha
    x[2] est omega
    x[3] prdouit une erreur: index out of range

    beta est x[0]



    - il résulte donc qu’il faut écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f(beta,alpha,omega):
     for k in range (65 ,len(y)):
         prov = beta + alpha*V_t[k-1] + omega*y[k-1]*y[k-1]
         d += math.log(prov) + y[k]*y[k]/(prov)
     return d
    si l’on se fonde sur l’ordre dans x

    mais cela donne des positions de alpha, beta et omega dans l’expression qui ne sont pas les mêmes que dans le bas du code.



    - il y a intérêt, au moins pour la lisibilité, et sans doute pour la rapidité de calcul, d’écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f(x):
     for k in range (65 ,len(y)):
         prov = x[1] + x[2]*V_t[k-1] + x[3]*y[k-1]*y[k-1]
         d += math.log(prov) + y[k]*y[k]/(prov)
     return d


    - pourquoi y a-t-il deux itérations for k in range(65,len(y)): ?



    - qu’est ce que y, z, V_t, V_tt, Vol_t, Vol_tt ?



    - pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for k in range(65,len(y)):
              y[1+k:64+k]
    y[1+k:64+k] va prendre les valeurs y[66:129], [67:130], [68:131]....
    Est-ce bien ce que tu veux ?

  7. #7
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    En fait c'est un problème de maximisation (mais on peut minimiser -f(x) )

    Pour la minimisation, j'ai cru qu'avec fmin_tnc qu'on avait pas besoin de la faire à la main, non?

    Merci pour toute tes remarques qui me font un peu plus voir mon niveau en python....

    le z.var() permet de calculer la variance mais ne sert pas trop le code.

    Afin de t'éviter des reflexions inutiles (et je m'excuse encore du manque de clareté de mon code....), je te mets uniquement le code qui pose problème.

    Donc à partir de la fonction que t'as défini:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f(omega,beta,alpha):
     for k in range (65 ,len(y)):
         prov = omega + beta *V_t[k-1] +alpha * y[k-1]*y[k-1]
         d += math.log(prov) + y[k]*y[k]/(prov)
     return d
    Je cherche a minimiser cette fonction suivant oméga,beta et alpha. Pour te donner un autre d'idée, V_t représente la volatilité estimé au temps k et y le rendement obervé au temps k. En fait on cherche les paramètres qui estime le mieux la volatilité du temps k en sachant la vol et le rendement du temps k-1.
    J'ai trouvé fmin_tnc dans la bibli de scipy mais je n'arrive pas à m'en servir.....

    J'espère avoir été un peu plus clair et te remercie de tes remarques qui me feront sans aucun doute avancer

  8. #8
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonjour,



    En fait c'est un problème de maximisation (mais on peut minimiser -f(x)
    Bon. Excuse moi alors.


    J'ai trouvé fmin_tnc dans la bibli de scipy mais je n'arrive pas à m'en servir.....
    J’ai donc compris que fmin_tnc n’est pas une fonction écrite par toi, mais une fonction disponible dans une bibliothèque scipy.


    Voilà deux renseignements indispensables qu’il aurait fallu donner tout de suite. Personne ne peut tout connaître de la galaxie Python. S’il faut faire des recherches dans un moteur de recherche pour comprendre une question, c’est que la question ne décrit pas assez bien le problème. Tu me diras que si on ne connait pas un sujet, il ne faut pas répondre. Je suis un peu d’accord. Mais même si on ne connait pas un sujet, on peut parfois aider. C’est le cas, j’ai fini par trouver ce que je cherchais. De toutes façons, donner plus de renseignements dans une question ne coûte pas cher.







    Bon, alors, une fois que j’ai compris ce qu’est fmin_tnc, j’ai cherché à coder un exemple qui marche avec cette fonction. Et là, j’ai été comme toi:
    J'ai trouvé fmin_tnc dans la bibli de scipy mais je n'arrive pas à m'en servir.....
    Et on ne peut pas dire que la doc de scipy aide beaucoup de ce point de vue. Je n’y ai trouvé aucun exemple.

    J’ai passé beaucoup de temps à en chercher un ailleurs et je suis finalement tombé sur cette discussion:

    http://old.nabble.com/basic-usage-of...html#a23798939





    1)

    Il semble que tu aies raison pour l’écriture de la fonction à minimiser: il semble qu’on ne peut pas l’écrire autrement que comme une fonction d’une seule variable et désigner ensuite ses arguments comme étant les éléments de x par x[0],x[1],x[2],etc.




    2)

    Le truc avec fmin_tnc, c’est qu’il est nécessaire qu’elle connaisse d’une manière ou d’une autre le gradient de la fonction.
    Du moins c’est ce que j’ai compris.
    Pour une fonction à une seule variable, le gradient c’est la dérivée. Pour une fonction de plusieurs variables, le gradient s'appelle le gradient.



    func : callable func(x, *args)

    Function to minimize. Should return f and g, where f is the value of the function and g its gradient (a list of floats). If the function returns None, the minimization is aborted.

    x0 : list of floats

    Initial estimate of minimum.

    fprime : callable fprime(x, *args)

    Gradient of func. If None, then func must return the function value and the gradient (f,g = func(x, *args)).

    args : tuple

    Arguments to pass to function.

    approx_grad : bool

    If true, approximate the gradient numerically.

    bounds : list

    (min, max) pairs for each element in x, defining the bounds on that parameter. Use None or +/-inf for one of min or max when there is no bound in that direction.

    etc.......




    Et donc, dans le cas orthodoxe, le paramètre fprime de la fonction fmin_tnc doit être renseigné avec la fonction gradient de la fonction func à minimiser.




    Mais la doc dit
    If None, then func must return the function value and the gradient (f,g = func(x, *args)).

    c’est à dire qu’en absence d’argument pour ce paramètre fprime, la fonction minimisée doit retourner la valeur de la fonction et le gradient.

    Plus haut dans la description de fmin_tnc, il est dit déjà de la fonction à minimiser qu’elle “Should return f and g, where f is the value of the function and g its gradient (a list of floats).“ , sans dire que ce n’est que dans le cas du manque de fprime.




    Enfin, la doc balance aussi
    approx_grad : bool
    If true, approximate the gradient numerically.

    Et il faut être doué pour comprendre du premier coup qu’en absence aussi bien d’un argument pour fprime que d’un couple (valeur de la fonction, et son gradient ) comme retour de la fonction minimisée, il est possible d’indiquer à fmin_tnc de se débrouiller à calculer elle-même le gradient qui lui est nécessaire.




    Pas optimale comme docu.



    Tout ça est confirmé par le dernier message du lien sur old.nabble.com:
    Hi, function to be minimized is supposed to return both function value and gradient.
    You can eventually provide a gradient function separately.

    If you do not want or do not have a gradient function to provide, you can always turn to True the approx_gradient
    argument, which compute a numerical approximation of your function.


    ----------------------------------------------------



    Le cas où la fonction à minimiser renvoie sa valeur et son gradient est celui donné dans la première réponse de josef.pktd dans le lien ci-dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import scipy.optimize as so 
    def f(x): 
        return (x[0]*x[1]-1)**2+1, [(x[0]*x[1]-1)*x[1], (x[0]*x[1]-1)*x[0]] 
    g = np.array([0.1,0.1]) 
    b=[(-10,10),(-10,10)] 
    so.fmin_tnc(f,g,bounds=b)
    Mais j’avoue que je ne comprends pas ce bazar.




    Je me suis donc inspiré du second exemple qu’il donne, avec approx_grad=1.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def f0(x): 
        return (x[0]*x[1]-1)**2+1 
    print so.fmin_tnc(f0, g, bounds=b, approx_grad=1)
    Ce qui est encore trompeur, d’ailleurs, car il ne s’agit pas d’une valeur numérique 1 affectée à approx_grad mais de la valeur booléenne True.




    J’ai pris
    le polynôme (x-2)(x-18) qui a un minimum entre ses racines 2 et 18
    et
    le polynôme y(y+10) qui a un minimum entre ses racines -10 et 0.

    Je les ai développés et multipliés pour obtenir une fonction à deux variables:
    x^^*y^^ + 10*x^^*y -20*x*y^^ -200*x*y +36*y^^ + 360*y

    ^^ = puissance 2


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import scipy.optimize as so
     
    def f(x):
        return (x[0]*x[1])**2 + 10*(x[0]**2)*x[1] -20*x[0]*(x[1]**2)\
               - 200*x[0]*x[1] + 36*x[1]**2 + 360*x[1]
     
    g = [0.1,0.1]
    b=[(-10,20),(-2,5)] 
    print so.fmin_tnc(f,g,bounds=b,approx_grad = True)


    Résultat:
    (array([-10., -2.]), 10, 0)
    - le minimum est (array([-10., -2.])

    - 10 est le nombre d’itérations qui ont été nécessaire à fmin_tnc pour trouver la solution

    - 0 est un code, je n’ai pas cherché ce que ça veut dire



    Le second paramètre de fmin_tnc, qui reçoit ici l’argument g = [0.1,0.1], doit être une liste de floats qui représente une estimation du minimum.

    En fait j’ai mis n’importe quoi comme valeur. J’ai l’impression que ce paramètre doit recevoir une liste de floats uniquement pour que fmin_tnc en déduise combien il y a de valeurs de sortie et sous quelle forme se fait la sortie.

    J’ai essayé avec g = [-20000.0,-3000001.0], c’est à dire avec des valeurs bien en dessous du minimum
    (-10,-2) effectif que sort la fonction fmintnc, et ça marche quand même, le résultat reste (-10,-2).
    Mais le nombre d’itérations passe à 1.



    Voilà, j’espère qu’avec ça , tu vas pouvoir avancer.

Discussions similaires

  1. Fonction somme avec cellules variables
    Par juxci dans le forum Excel
    Réponses: 5
    Dernier message: 11/02/2015, 16h16
  2. [XL-2010] Réaliser un fonction somme avec plusieurs critères dont la présence de diagonale
    Par will-1981 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 11/07/2014, 10h48
  3. Réponses: 1
    Dernier message: 12/01/2012, 12h24
  4. fonction qui retourne plusieurs variables
    Par laurentSc dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 11/04/2011, 11h06
  5. Fonction qui renvoie plusieurs variables
    Par _Aravis dans le forum MATLAB
    Réponses: 1
    Dernier message: 28/09/2008, 19h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo