Name
global.CopySolutionStatistics
Description
CopySolutionStatistics Script Include copies user modified precision/coverage values from previous active solution to new solution after training is complete.
Script
var CopySolutionStatistics = Class.create();
CopySolutionStatistics.prototype = {
PRECISION: 'precision',
COVERAGE: 'coverage',
THRESHOLD: 'threshold',
RECALL: 'recall',
ML_SOLUTION: 'ml_solution',
ML_CLASS: 'ml_class',
ML_PC_LOOKUP: 'ml_pc_lookup',
initialize: function() {
this.statisticField = this.PRECISION;
this.log = new GSLog('com.snc.ml.copy.solution.statistics.log', 'CopySolutionStatistics');
this.log.disableDatabaseLogs();
},
copyStatistics: function(/*ml_class GlideRecord*/ current){
try{
var applyPcLookup = new ApplyPcLookup();
this.currentMLClassRecord = current;
if(JSUtil.nil(current) || !(current.isValidRecord())){
this.log.logErr('Invalid record passed. A valid ml_class record is required');
return;
}
this.previousSolutionRecord = this.getPreviousActiveSolution();
//check if corresponding ml_class record exists in the previous solution
//and if user has modified precision/coverage values
if(!this.isCopyRequired()){
this.log.logErr('Skipping for class:'+this.currentMLClassRecord.name,'CopySolutionStatistics');
applyPcLookup.updatePrecCovForSolution(current.solution);
return;
}
var previousSolutionStatisticValue = this.getPreviousSolutionStatisticValue();
var nearestPCLookupRecord = this.getNearestRecord(previousSolutionStatisticValue);
current.setValue('pc_lookup', nearestPCLookupRecord);
current.update();
applyPcLookup.updatePrecCovForSolution(current.solution);
} catch(e){
this.log.logErr('Exception caught: '+e,'CopySolutionStatistics');
}
},
setStatisticReferenceField: function(statisticField){
this.statisticField = statisticField;
},
/**
* getPreviousActiveSolution() method queries ML_SOLUTION table and returns last active solution
*/
getPreviousActiveSolution: function(){
var solutionRecord = new GlideRecord(this.ML_SOLUTION);
solutionRecord.addQuery('active', 'false');
solutionRecord.addQuery('ml_capability_definition', this.currentMLClassRecord.solution.ml_capability_definition.sys_id);
solutionRecord.orderByDesc('sys_updated_on');
solutionRecord.setLimit(1);
solutionRecord.query();
if(solutionRecord.next()){
return solutionRecord;
}
},
/**
* getPreviousSolutionStatisticValue() method queries ml_class record of current class label
* in the previous active solution and if it exists, returns the solution statistic value (eg. precision) of that record
* input: previousSolutionRecord - sys_id of previous active solution record
* output: solution statistic value (integer)
*/
getPreviousSolutionStatisticValue: function(){
var previousSolutionStatisticValue = '';
var mlClassRecord = new GlideRecord(this.ML_CLASS);
mlClassRecord.addQuery('solution', this.previousSolutionRecord.sys_id);
mlClassRecord.addQuery('name', this.currentMLClassRecord.name);
mlClassRecord.query();
while(mlClassRecord.next() && mlClassRecord.getValue('pc_lookup')){
if(this.statisticField == this.PRECISION){
previousSolutionStatisticValue = mlClassRecord.pc_lookup.precision;
}else if(this.statisticField == this.COVERAGE){
previousSolutionStatisticValue = mlClassRecord.pc_lookup.coverage;
}else if(this.statisticField == this.RECALL){
previousSolutionStatisticValue = mlClassRecord.pc_lookup.recall;
}else{
previousSolutionStatisticValue = mlClassRecord.pc_lookup.threshold;
}
}
return previousSolutionStatisticValue;
},
/**
* getNearestRecord() method returns ml_pc_lookup record with closest match in precision
* inputs: classLabel - class label of the current ml_class record
* previousSolutionStatisticValue - precision value of ml_class record set by customer in the previous solution
* output: sys_id of ml_pc_lookup record with closest match in precision
*
*
*/
getNearestRecord: function(previousSolutionStatisticValue){
var nearestRecordSysId = '';
var pcLookupRecord = new GlideRecord(this.ML_PC_LOOKUP);
pcLookupRecord.addQuery('class_name.name',this.currentMLClassRecord.name);
pcLookupRecord.addQuery('solution', this.currentMLClassRecord.solution.sys_id);
pcLookupRecord.orderBy(this.statisticField);
pcLookupRecord.query();
var min = 9999;
while(pcLookupRecord.next()){
var currentValue = pcLookupRecord.getValue(this.statisticField);
var diff = Math.abs(pcLookupRecord.getValue(this.statisticField) - previousSolutionStatisticValue);
if(diff<=min){
// special case for precision == 100, this means that the class will become inactive
// we do not want to make the class inactive if it was active in the previous solution version
if(this.statisticField == this.PRECISION && currentValue == 100 && previousSolutionStatisticValue != 100) {
continue;
}
min = diff;
nearestRecordSysId = String(pcLookupRecord.getUniqueValue());
}
}
return nearestRecordSysId;
},
/**
* isCopyRequired() method checks
* 1. if ml_class record of same class label exists in previous active solution record
* 2. if customer has modified precision coverage values (if sys_mod_count >= 2)
*
*
*/
isCopyRequired: function(){
var mlClassRecord = new GlideRecord(this.ML_CLASS);
mlClassRecord.addQuery('solution', this.previousSolutionRecord.sys_id);
mlClassRecord.addQuery('name', this.currentMLClassRecord.name);
mlClassRecord.addQuery('sys_mod_count','>', 1);
mlClassRecord.query();
return (mlClassRecord.getRowCount() > 0);
},
type: 'CopySolutionStatistics'
};
Sys ID
06c6b35b739113003109102c1bf6a70b