From 7bd8ab8735be0b76c7bda65642612a52a679b822 Mon Sep 17 00:00:00 2001 From: Lionel Vital Date: Mon, 20 Apr 2020 14:27:52 -0700 Subject: [PATCH 1/4] Remove feature possible values validation aside from type --- static/js/banditMl.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/static/js/banditMl.js b/static/js/banditMl.js index 8ffd60a..3bed70a 100644 --- a/static/js/banditMl.js +++ b/static/js/banditMl.js @@ -257,10 +257,6 @@ banditml.BanditAPI.prototype.validateAndFilterFeaturesInContext = function (cont Array.isArray(possibleValues), `Feature ${featureName} is categorical, but its possible values is not an array. Update the model appropriately in Bandit ML.` ); - self.assert( - possibleValues.includes(context[featureName]), - `Value ${value} is not recognized among possible values for feature ${featureName}. Please update the possible values in Bandit ML.` - ); } else if (featureType === "P") { self.assert( Array.isArray(possibleValues), @@ -270,17 +266,6 @@ banditml.BanditAPI.prototype.validateAndFilterFeaturesInContext = function (cont typeof value === "string" || Array.isArray(value), `Feature ${featureName} is a product set that expects an array or string, but ${value} is not an array or string.` ); - if (Array.isArray(value)) { - self.assert( - value.every(val => possibleValues.includes(val)), - `${value} is not included in ${featureName}'s possible values ${possibleValues}.` - ); - } else { - self.assert( - possibleValues.includes(value), - `${value} is not included in ${featureName}'s possible values ${possibleValues}.` - ); - } } filteredFeatures[featureName] = value; } catch (e) { From 8526219232ad98d13ad609d8f51319e23b4b5937 Mon Sep 17 00:00:00 2001 From: Lionel Vital Date: Mon, 20 Apr 2020 14:43:07 -0700 Subject: [PATCH 2/4] remove all possible values references + validate value is a string for C --- static/js/banditMl.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/static/js/banditMl.js b/static/js/banditMl.js index 3bed70a..35c76b8 100644 --- a/static/js/banditMl.js +++ b/static/js/banditMl.js @@ -244,7 +244,6 @@ banditml.BanditAPI.prototype.validateAndFilterFeaturesInContext = function (cont if (featureExists) { const value = context[featureName]; const featureSpec = contextValidation[featureName]; - const possibleValues = featureSpec.possible_values; const featureType = featureSpec.type; try { if (value == null) { @@ -254,14 +253,10 @@ banditml.BanditAPI.prototype.validateAndFilterFeaturesInContext = function (cont self.assert(typeof value === "number", `Feature ${featureName} is expected to be numeric, but ${value} of type ${valueType} was passed.`); } else if (featureType === "C") { self.assert( - Array.isArray(possibleValues), - `Feature ${featureName} is categorical, but its possible values is not an array. Update the model appropriately in Bandit ML.` + typeof value === "string", + `Feature ${featureName} is a categorical that expects a string, but ${value} is not a string.` ); } else if (featureType === "P") { - self.assert( - Array.isArray(possibleValues), - `Feature ${featureName} is a product set, but its possible values is not an array. Update the model appropriately in Bandit ML.` - ); self.assert( typeof value === "string" || Array.isArray(value), `Feature ${featureName} is a product set that expects an array or string, but ${value} is not an array or string.` From 11907d3854c3e438b523844233a2c955a78580d5 Mon Sep 17 00:00:00 2001 From: Lionel Vital Date: Mon, 20 Apr 2020 15:10:11 -0700 Subject: [PATCH 3/4] Remove possibleValues/delayedReward validation --- static/js/banditMl.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/static/js/banditMl.js b/static/js/banditMl.js index 35c76b8..25bbedf 100644 --- a/static/js/banditMl.js +++ b/static/js/banditMl.js @@ -558,26 +558,12 @@ banditml.BanditAPI.prototype.logDecision = function(context, decisionResponse, e }); }; -banditml.BanditAPI.prototype.isDelayedReward = function(reward, experimentId) { - let contextValidation = this.getItemFromStorage(this.contextValidationKey(experimentId)); - this.assert(contextValidation, "contextValidation is null, possibly from calling logReward without updating context.") - // if every key is in the possible choices (IDs), we categorize as delayed reward - return Object.keys(reward).every(key => contextValidation.choices.possible_values.includes(key)); -}; - banditml.BanditAPI.prototype.logReward = function(reward, experimentId, decision = null, decisionId = null) { const headers = { "Authorization": `ApiKey ${this.banditApikey}` }; this.assert( reward && typeof reward === "object", "Reward needs to be a non-empty object."); - if (this.isDelayedReward(reward, experimentId)) { - this.assert(decision === null, `decision needs to be null for delayed rewards.`); - this.assert(decisionId === null, `decisionId needs to be null for delayed rewards.`); - } else { - this.assert(decision && typeof decision === "string", `For immediate rewards, decision needs to be a single string ID. Got ${decision} instead.`); - this.assert(decisionId && typeof decisionId === "string", `For immediate rewards, decisionId needs to be a single string ID. Got ${decisionId} instead.`); - } this.asyncPostRequest(this.banditLogRewardEndpoint, headers, { decisionId: decisionId, decision: decision, From 59a07c128191a33162e47278a4957f9a7f3d2e6f Mon Sep 17 00:00:00 2001 From: Lionel Vital Date: Mon, 20 Apr 2020 15:25:33 -0700 Subject: [PATCH 4/4] Validate every value in pset array is string --- static/js/banditMl.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/static/js/banditMl.js b/static/js/banditMl.js index 25bbedf..c08b5f3 100644 --- a/static/js/banditMl.js +++ b/static/js/banditMl.js @@ -231,6 +231,16 @@ banditml.BanditAPI.prototype.getContext = function(experimentId) { return this.getItemFromStorage(this.contextName(experimentId)) || {}; }; +banditml.BanditAPI.prototype.isValidArray = function(arr, arrValueType) { + if (!Array.isArray(arr)) { + return false; + } + if (!arrValueType) { + return arr.every(v => { return typeof v === arrValueType; }); + } + return true; +}; + banditml.BanditAPI.prototype.validateAndFilterFeaturesInContext = function (context, contextValidation) { const self = this; let filteredFeatures = {}; @@ -258,7 +268,7 @@ banditml.BanditAPI.prototype.validateAndFilterFeaturesInContext = function (cont ); } else if (featureType === "P") { self.assert( - typeof value === "string" || Array.isArray(value), + typeof value === "string" || self.isValidArray(value, "string"), `Feature ${featureName} is a product set that expects an array or string, but ${value} is not an array or string.` ); }