Algorithme génétique en santé (4/5)

🧠 Le coeur du problème#

Comme vous avez pu voir dans l'exemple de l’algorithme génétique (AG) que nous avons présenté dans le dernier article, tout se joue au niveau de la selection des matrices (chromosomes ou agents en fonction de comment on le décrit) que l’on souhaite garder pour les itérations suivantes.

Dans le monde des AG, les caractéristiques d’un individu à s’adapter à son milieu s’appelle fitness. Donc plus cette valeur est élevée, plus on considère que les chances de survie seront meilleures. On cherche donc toujours à maximiser cette valeur.

function_inputs = [4,-2,3.5,5,-11,-4.7] # Function inputs.
desired_output = 44 # Function output.

def fitness_func(solution, solution_idx):
    # Calculating the fitness value of each solution in the current population.
    # The fitness function calulates the sum of products between each input and its corresponding weight.
    output = numpy.sum(solution*function_inputs)
    fitness = 1.0 / numpy.abs(output - desired_output)
    return fitness

Donc le cas précédent on voulait que la fonction : $$ w1x1 + w2x2 + w3x3 + w4x4 + w5x5 + 6wx6 $$ converge vers une valeur donnée desired_output, 44.

function_inputs sont les coefficients (x1….x6) que multiplieront les valeurs que l’ont cherche (w1….w6). Etant donné qu’une population a plusieurs centaines de possibilités, l’algorithme chaque membre de la population, un par un, et calcule la fitness. Chaque membre a des gènes qui ont une valeur. Ces valeurs sont passées dans notre fonction dans une variable qu’on appelle solution. On va ignorer solution_idx car cela n’a pas grand intérêt par la suite.

Donc output est finalement le résultat de : $ w1x1 + w2x2 + w3x3 + w4x4 + w5x5 + 6wx6 $

Donc plus output s’approche de desired_output plus la fitness tend vers l’infini et on selectionnera progressivement les plus élevées (meilleures) d’entre elles pour la prochaine itération.

💡 La solution#

Pour reprendre notre problème, on souhaite trouver le pourcentage que doit représenter chaque acte dans l’activité globale d’un ami médecin afin de l’aider à rembourser le prêt qu’il a demandé pour ouvrir son cabinet.

def all_positive(vec1):
 # Est-ce que toutes les valeurs de la solution sont positives ?
 return len([n for n in vec1 if n >= 0]) == len(vec1)

def dotproduct(vec1, vec2):
 # L'équivalent de la fonction Excel SUMPRODUCT en Python
 return sum(map(operator.mul, vec1, vec2))

def is_percent(solution):
 # Est-ce que la somme de toutes les valeurs est égale à 100 ?
 if(numpy.sum(solution) == 100):
     return True
 else:
     return False

def calc_value(solution):
 actes = [25, 38.40, 40.28, 25, 41.80, 37.46, 68.80]
 temps = [15, 22, 17, 13, 25, 23, 55]
 # Calcul des patients / heure
 temps = [60 / x for x in temps]
 # Calcul du montant moyen / heure réalisé par le médecin avec la solution actuelle
 return dotproduct(solution, actes) * dotproduct(solution, temps)

def fitness_func(solution, solution_idx):
 fitness = 0
 if (is_percent(solution) and all_positive(solution)):
  # Puisqu'on a atteinte une somme de valeurs = 100, on peut commencer à maximiser la valeur de sortie
  fitness = calc_value(solution, True)
 else:
  # On souhaite se rapprocher le plus possible d'une somme de valeurs proche de 100
  if (not is_percent(solution)):
   fitness = 1/(numpy.abs(numpy.sum(solution)-100))
 return fitness

Les résultats sont :

Il lui a fallu 149 cycles à l’algorithme pour trouver la solution.

On remarquera que la solution que nous avions trouvé avec l’optimisation linéaire était de 23 (92%) spirométries et 2 (8%) téléconsultations par jour.

Si on garde le même nombre de consultations par jour (25) :

  • 93% de 25 est 23,25 que l’on va arrondir à 23. Soit 926,44€ en montant cumulé dans la journée en faisant des spirométries
  • 7% de 25 est 1,75 que l’on arrondi à 2. Soit 137,6€ pour l’extraction de naevus
  • Le médecin aura travaillé : 8 heures et 21 minutes

🌍 Mettre en ligne#

Maintenant que nous avons un système qui marche, on va voir lors du prochain article (et dernier article de cette série) comment mettre en ligne une fonction pour se connecter à partir d’un Google Sheet.

comments powered by Disqus

© 2021