Skip to content

Commit

Permalink
Refactored the evaluation of scorecard models
Browse files Browse the repository at this point in the history
  • Loading branch information
vruusmann committed Mar 23, 2021
1 parent 827364d commit f71ef6e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ private <V extends Number> V calculateContinuousTarget(ValueFactory<V> valueFact

for(InstanceResult<V> instanceResult : instanceResults){
FieldValue value = table.get(instanceResult.getId(), name);

if(FieldValueUtil.isMissing(value)){
throw new MissingValueException(name);
}
Expand Down Expand Up @@ -406,6 +407,7 @@ private <V extends Number> Object calculateCategoricalTarget(ValueFactory<V> val

for(InstanceResult<V> instanceResult : instanceResults){
FieldValue value = table.get(instanceResult.getId(), name);

if(FieldValueUtil.isMissing(value)){
throw new MissingValueException(name);
}
Expand Down Expand Up @@ -461,6 +463,7 @@ private Function<Integer, String> createIdentifierResolver(FieldName name, Table
@Override
public String apply(Integer row){
FieldValue value = table.get(row, name);

if(FieldValueUtil.isMissing(value)){
throw new MissingValueException(name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,66 +110,43 @@ public String getSummary(){

Characteristics characteristics = scorecard.getCharacteristics();
for(Characteristic characteristic : characteristics){
Number baselineScore = null;
PartialScore partialScore = evaluateCharacteristic(characteristic, context);

Number score = partialScore.getValue();

value.add(score);

partialScores.add(partialScore);

if(useReasonCodes){
baselineScore = characteristic.getBaselineScore(scorecard.getBaselineScore());
Number baselineScore = characteristic.getBaselineScore(scorecard.getBaselineScore());
if(baselineScore == null){
throw new MissingAttributeException(characteristic, PMMLAttributes.CHARACTERISTIC_BASELINESCORE);
}
}

PartialScore partialScore = null;
String reasonCode = partialScore.getReasonCode();
if(reasonCode == null){
Attribute attribute = partialScore.getAttribute();

List<Attribute> attributes = characteristic.getAttributes();
for(Attribute attribute : attributes){
Boolean status = PredicateUtil.evaluatePredicateContainer(attribute, context);
if(status == null || !status.booleanValue()){
continue;
throw new MissingAttributeException(attribute, PMMLAttributes.ATTRIBUTE_REASONCODE);
}

Number score = evaluatePartialScore(attribute, context);
if(score == null){
return TargetUtil.evaluateRegressionDefault(valueFactory, targetField);
Number difference;

Scorecard.ReasonCodeAlgorithm reasonCodeAlgorithm = scorecard.getReasonCodeAlgorithm();
switch(reasonCodeAlgorithm){
case POINTS_ABOVE:
difference = Functions.SUBTRACT.evaluate(score, baselineScore);
break;
case POINTS_BELOW:
difference = Functions.SUBTRACT.evaluate(baselineScore, score);
break;
default:
throw new UnsupportedAttributeException(scorecard, reasonCodeAlgorithm);
}

partialScore = new PartialScore(characteristic, attribute, score);

value.add(score);

if(useReasonCodes){
String reasonCode = attribute.getReasonCode(characteristic.getReasonCode());
if(reasonCode == null){
throw new MissingAttributeException(attribute, PMMLAttributes.ATTRIBUTE_REASONCODE);
}

Number difference;

Scorecard.ReasonCodeAlgorithm reasonCodeAlgorithm = scorecard.getReasonCodeAlgorithm();
switch(reasonCodeAlgorithm){
case POINTS_ABOVE:
difference = Functions.SUBTRACT.evaluate(score, baselineScore);
break;
case POINTS_BELOW:
difference = Functions.SUBTRACT.evaluate(baselineScore, score);
break;
default:
throw new UnsupportedAttributeException(scorecard, reasonCodeAlgorithm);
}

reasonCodePoints.add(reasonCode, difference);
}

break;
reasonCodePoints.add(reasonCode, difference);
}

// "If not even a single Attribute evaluates to "true" for a given Characteristic, then the scorecard as a whole returns an invalid value"
if(partialScore == null){
throw new UndefinedResultException()
.ensureContext(characteristic);
}

partialScores.add(partialScore);
}

if(useReasonCodes){
Expand All @@ -184,17 +161,39 @@ public String getSummary(){
}

static
private Number evaluatePartialScore(Attribute attribute, EvaluationContext context){
private PartialScore evaluateCharacteristic(Characteristic characteristic, EvaluationContext context){
List<Attribute> attributes = characteristic.getAttributes();

for(Attribute attribute : attributes){
Boolean status = PredicateUtil.evaluatePredicateContainer(attribute, context);
if(status == null || !status.booleanValue()){
continue;
}

Number value = evaluateAttribute(attribute, context);

return new PartialScore(characteristic, attribute, value);
}

// "If not even a single Attribute evaluates to "true" for a given Characteristic, then the scorecard as a whole returns an invalid value"
throw new UndefinedResultException()
.ensureContext(characteristic);
}

static
private Number evaluateAttribute(Attribute attribute, EvaluationContext context){
ComplexPartialScore complexPartialScore = attribute.getComplexPartialScore();

// "If both are defined, the ComplexPartialScore element takes precedence over the partialScore attribute for computing the score points"
if(complexPartialScore != null){
FieldValue computedValue = ExpressionUtil.evaluateExpressionContainer(complexPartialScore, context);
if(FieldValueUtil.isMissing(computedValue)){
return null;
FieldValue value = ExpressionUtil.evaluateExpressionContainer(complexPartialScore, context);

if(FieldValueUtil.isMissing(value)){
throw new UndefinedResultException()
.ensureContext(complexPartialScore);
}

return computedValue.asNumber();
return value.asNumber();
} else

{
Expand Down

0 comments on commit f71ef6e

Please sign in to comment.