Skip to content
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

Implement final algorithm for expected ages #174

Open
lkeegan opened this issue Nov 15, 2024 · 0 comments
Open

Implement final algorithm for expected ages #174

lkeegan opened this issue Nov 15, 2024 · 0 comments
Labels
backend enhancement New feature or request

Comments

@lkeegan
Copy link
Member

lkeegan commented Nov 15, 2024

We have a simple placeholder algorithm for this for now: average the score for each age month, pick the first month with an average score of 3/4 or greater.

def _get_expected_age_from_scores(scores: np.ndarray) -> int:
# placeholder algorithm: returns first age with avg score > 3
return np.argmax(scores >= 3.0)
def _get_average_scores_by_age(
answers: Sequence[MilestoneAnswer], child_ages: dict[int, int]
) -> np.ndarray:
max_age_months = 72
scores = np.zeros(max_age_months + 1)
counts = np.zeros_like(scores)
for answer in answers:
age = child_ages[answer.answer_session_id] # type: ignore
# convert 0-3 answer index to 1-4 score
scores[age] += answer.answer + 1
counts[age] += 1
# divide each score by the number of answers
with np.errstate(invalid="ignore"):
scores /= counts
# replace NaNs (due to zero counts) with zeros
scores = np.nan_to_num(scores)
return scores
def calculate_milestone_age_scores(
session: SessionDep, milestone_id: int
) -> MilestoneAgeScores:
child_ages = _get_answer_session_child_ages_in_months(session)
answers = session.exec(
select(MilestoneAnswer).where(col(MilestoneAnswer.milestone_id) == milestone_id)
).all()
scores = _get_average_scores_by_age(answers, child_ages)
expected_age = _get_expected_age_from_scores(scores)
return MilestoneAgeScores(
expected_age=expected_age,
scores=[
MilestoneAgeScore(
age_months=age,
avg_score=score,
expected_score=(4 if age >= expected_age else 1),
)
for age, score in enumerate(scores)
],
)

Once the website has been populated with the existing data from previous surveys (and possibly some new user data), we should revisit this algorithm and implement the final algorithm to be used in production.

@lkeegan lkeegan added enhancement New feature or request backend labels Nov 15, 2024
@lkeegan lkeegan added this to the Initial production version milestone Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant