-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Corrige les modalités de calcul de l'âge #1346
base: master
Are you sure you want to change the base?
Conversation
@Morendil Le test ci-dessous (inspiré de - name: PAJE - PPN - Cas N°1
description: Montant PAJE
period: 2018-03
absolute_error_margin: 0.03
input:
famille:
parents: [parent1, parent2]
enfants: [enfant1]
foyer_fiscal:
declarants: [parent1, parent2]
personnes_a_charge: [enfant1]
menage:
personne_de_reference: parent1
conjoint: parent2
enfants: [enfant1]
individus:
parent1:
age_en_mois: 38 * 12
revenu_assimile_salaire:
2015: 28000
2016: 28000
2017: 28000
2018: 28000
parent2:
age: 35
revenu_assimile_salaire:
2015: 15000
2016: 15000
2017: 15000
2018: 15000
enfant1:
age_en_mois: 2
output:
paje: 923.08 / (1 - 0.005) + 92.31 / (1 - 0.005) Testé aussi pour les combinaisons |
@sandcha Oui c'est bien ça. Soit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merci pour cette simplification @Morendil 🙌
Reste effectivement à gérer le test en erreur via API Cache.
Néanmoins, actuellement, il ne passe pas non plus surmaster
.
# Convertit un âge en mois en date de naissance, de sorte que l'âge équivalent se propage à toutes les périodes | ||
def set_input(holder, period, array): | ||
array = holder._to_array(array) | ||
naissance = (datetime64(period.first_month.start).astype('datetime64[M]') - array.astype('timedelta64[M]')).astype('datetime64[D]') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@sandcha Oui le test échoue parce que l'âge et la date de naissance ne sont pas compatibles et comme c'est l'âge qui est saisi en dernier on écrase la date de naissance existante, on n'est donc pas sur une valeur postérieure à avril 2018 mais une en 2017 et on sort donc du cadre d'application des barèmes pour une naissance après avril 2018. Il faudrait supprimer |
J'ai poussé un commit avec quelques corrections de tests, le cas qui est vraiment problématique est le cas "PPN - n°1". Le test suivant est passant sur - name: PAJE - PPN - Cas N°1
description: Montant PAJE
period: 2018-06
absolute_error_margin: 0.03
input:
famille:
parents: [parent1, parent2]
enfants: [enfant1]
foyer_fiscal:
declarants: [parent1, parent2]
personnes_a_charge: [enfant1]
menage:
personne_de_reference: parent1
conjoint: parent2
enfants: [enfant1]
individus:
parent1:
age: 38
revenu_assimile_salaire:
2015: 28000
2016: 28000
2017: 28000
2018: 28000
parent2:
age: 35
revenu_assimile_salaire:
2015: 15000
2016: 15000
2017: 15000
2018: 15000
enfant1:
date_naissance: 2018-04-10
output:
af_nbenf: 0
age: [38, 35, -9999]
prestations_familiales_enfant_a_charge: [False, False, False]
enfant_eligible_paje: [False, False, True]
paje_naissance: 946.39
paje_base: 0
paje_cmg: 0
paje_prepare: 0
paje: 941.66 / (1 - 0.005) + 0 Le nombre d'enfants de cette famille n'est pas zéro mais bien un; le bug sur |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je confirme qu'il reste encore un test qui échoue.
3b757c1
to
3629b22
Compare
Rebased |
@sandcha @maukoquiroga J'ai corrigé les tests PAJE "mécaniquement" c'est-à-dire sans vérifier dans le détail la logique métier que je ne maîtrise pas assez, en partant du principe que les valeurs calculées actuellement par OpenFisca sur la base d'un âge cohérent (0 et plus -9999) reflètent effectivement le droit. C'est peut-être une supposition risquée. Je n'ai pas d'autres changements à apporter à cette PR. @guillett si tu as le temps de revoir ça sous l'angle métier ça me rassurerait là-dessus. |
f5fcc44
to
0b0c645
Compare
Les corrections ont été ajoutées depuis
Rebased |
Rebase en cours. |
0b0c645
to
3485eb6
Compare
) | ||
) | ||
# Convertit un age en date de naissance, de sorte que l'âge équivalent se propage à toutes les périodes | ||
def set_input(holder, period, array): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cette PR résoud le calcul de l'âge 🙌
Toutefois, comme vu plus haut, elle supposerait de contraindre l'expression des âges de la population d'une simulation à une seule variable parmi age
et age_en_mois
.
Ceci supposerait d'informer l'usager du risque d'obtention de valeurs fausses en cas d'inputs mixtes age
/age_en_mois
et peut affecter un usage tel que celui fait par mes-aides. 😕
Il me semble qu'on aurait moyen de conserver des inputs mixtes avec age
et age_en_mois
et faire passer le test proposé dans l'issue à l'origine de cette PR. Dans ce cas, nous aurions besoin :
- De faire appel à des mises à jour multiples sans perte de donnée de
date_naissance
puisque cette variable peut-être affectée parage
etage_en_mois
, - D'autoriser des mises à jour multiples d'une variable en
ETERNITY
puisque c'est la périodicité dedate_naissance
Pour le premier point, nous pourrions utiliser des masques.
Voici un draft pour age
qui se base sur le code de cette PR :
def set_input(holder, period, array):
age = holder._to_array(array)
age[age == -9999] = 48
naissance_par_age = (datetime64(period.first_month.start).astype('datetime64[M]') - (age * 12).astype('timedelta64[M]')).astype('datetime64[D]')
naissance_connue = holder.simulation.calculate('date_naissance', period)
naissance_default_value = datetime64('1970-01-01')
naissance_inconnue = ma.masked_where(naissance_connue == naissance_default_value, naissance_connue)
index_naissance_inconnue = np.where(naissance_inconnue.mask)
naissance_connue[index_naissance_inconnue] = naissance_par_age[naissance_inconnue.mask]
holder.simulation.set_input('date_naissance', period, naissance_connue)
Pour le deuxième point, nous aurions besoin de mettre à jour la gestion des valeurs dans les holders. Ceci peut être facilité par la PR openfisca/openfisca-core#891 que je vous propose de revoir avant celle-ci.
Hello @sandcha, je vois que cette PR est acceptée, est-ce que l'on peut la merger ? Juste pour être sûr ... Le cas échéant cela sera bien de changer son statut et de spécifier dans la review ce qu'il faudrait pour que ce soit le cas. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarification du statut de cette PR : Elle supposerait d'informer l'usager du risque d'obtention de valeurs fausses en cas d'inputs mixtes age
/age_en_mois
. Ce risque me semble trop élevé pour merger le code en l'état.
@sandcha c'est-à-dire que, en l'état, et en absence de l'API cache, ces changements ne sont pas rétro-compatibles, que le risque de confusion rend le bénéfice(x) de cette PR plus faible que son coût(x), et que donc on peut a) soit la fermer sans merger, b) soit indiquer explicitement une dépendance à l'API cache ? |
set_input
qui intercepte les entréesage
etage_en_mois
pour les transformer en une date de naissance.Précédemment, ces deux variables effectuaient un calcul compliqué et qui s'appuyait sur des mécanismes internes de Core (via
population.get_holder
, voir aussi openfisca/openfisca-core#887 qui motive en partie de ne plus accéder directement aux Holder dans France).Il était possible de fournir
age_en_mois
et d'obtenirage
, mais aussi de fournirage
et d'obtenirage_en_mois
; ce qui signifie qu'il existait entre ces variables une relation de dépendance circulaire.Cette PR corrige ces incohérences en passant par un autre mécanisme, à savoir une méthode
set_input
pour ces deux variables. Les tests précédemment passants sur les calculs d'âge sont préservés avec les mêmes caractéristiques, à savoir qu'il est possible de stipuler un âge pour une période quelconque, et qu'il se répercute ensuite à toutes les autres périodes. Cela se traduit en effet par le calcul préalable d'une date de naissance inférée depuis l'âge donné en entrée et la période; les variablesage_en_mois
etage
sont ensuite calculable pour toute autre période puisque la date de naissance est définie pourETERNITY
.Elle corrige également #1345 et les tests associés à la PAJE dont le calcul semblait faux en conséquence.
Une conséquence de ce nouveau fonctionnement est que les cas de tests et les payloads devront spécifier uniformément
age
,age_en_mois
oudate_naissance
pour tous les individus d'un même vecteur; en effet en l'absence d'une notion de variable partiellement renseignée c'est la seule façon de garantir que les effets de ce mode de calcul sont cohérents. Cette PR n'est pas rétro-compatible.Fixes #1345
Ces changements (effacez les lignes ne correspondant pas à votre cas) :
Quelques conseils à prendre en compte :
setup.py
.CHANGELOG.md
.Et surtout, n'hésitez pas à demander de l'aide ! :)