Questions

A question says what you want to know about each case. There are four types. Each one pairs with a typed answer.

Type Asks Answer, per case
yesno "Will this happen?" p, the chance it happens (0 to 1)
score "How likely, as a level?" level (unlikelyvery_likely) and p
choice "Which option?" choice, most_likely, least_likely, and each option's p
rank "Which cases first?" position and p, highest first

Jev's Noul, Score and Choice ask a model to judge the case in front of it. Datagoat's yesno, score and choice ask what the record says about cases like it. rank has no Jev counterpart: it orders a whole record in one call.

Defining a question

Questions go in questions, keyed by an id you choose. The answer comes back under the same id.

"questions": {
  "churn": {"type": "yesno", "outcome_column": "churned", "outcome_is_desirable": false},
  "risk":  {"type": "score", "outcome_column": "churned", "outcome_is_desirable": false}
}
Field
id (the key) letters, digits, _ and -, up to 64 characters
type yesno, score, choice or rank
outcome_column the yes/no column in the record the question is about
outcome_is_desirable true if the outcome is one you want (converted, renewed), false if you want to avoid it (churned, defaulted). Required for choice; optional for the others.
positive_values the values of the outcome column that mean yes, when Datagoat can't tell (details)
refit_of the model_ref of an earlier answer about an older version of this record. Links the two for drift.

Each type adds its own fields: levels and cuts for score, options for choice, top_k for rank.

There are no instructions to write. A Jev question is defined by its instructions. A Datagoat question is defined by the outcome it learns, so the column name is the whole question. Make the outcome column say exactly what you mean: churned_within_90d asks something different from churned.

Choosing a type

  • yesno when the chance itself is what your code uses: a threshold, a sort, an expected value.
  • score when people or rules act on named bands, such as "call everyone likely or above".
  • choice when you control something about the case (a plan, a channel, a team) and want the option least likely to go wrong, or most likely to go right.
  • rank when the question is "who first?": a queue, a shortlist, a top 50.

Asking several questions at once

Put every question about one record in one call, up to eight. Questions about the same outcome, with the same outcome_is_desirable and positive_values, share one fit, so a second question about churned costs no second fit. fits_run in the answer says how many fits the call ran.

An extra question on an outcome you already ask about adds no fit. It bills only its own answered cases. So ask the score beside the yesno if some code path may want it.

Writing good questions

  • One outcome per question. "Churned or downgraded" is two questions, or a new column you build yourself.
  • Say whether you want the outcome. Set outcome_is_desirable whenever you know it. It decides what choice picks, and it records in each Verdict what the outcome meant. Left out (on the other types), the engine reads the outcome column's name instead: a name it recognises as wanted, such as converted, reads as desirable, and anything else as adverse. The answer's polarity says which it used. Datagoat itself never fills it in.
  • Let the outcome be something you actually record. Datagoat learns from labels, not descriptions. If no column says what happened, add one.
  • Keep the decision in your code. Datagoat returns chances and levels. The thresholds, the costs and the action are yours (Patterns).