es6-fuzz
es6-fuzz copied to clipboard
Wrong evaluation at limit of trapezoid
Hi, I am trying to use this library, the fuzzification is quite clear but the defuzzification step is not clear to me using this library, anyways, I have this code that gives a wrong evaluation at the upper limit of a trapezoid, It seems to come from this library not from boon-js:
I have this function with two input fuzzy variables (likelihood and impact), the fifth evaluator function is the one that returns True when the input is assess(5, 10), while 10 as a value for impact should trigger the seventh evaluator to return true (securityTest_moderate_restricted ) and this should lead to have the function an output of "high", I tried to slightly modify the trapezoid declaration to make it work by cheating a little bit and pushing the last point of the trapezoid to 11: const restrictedImpact = new fuzzy.Trapezoid(7.5, 8.5, 10, 11); And this gave me a correct result, which makes me think that there is a problem at the higher limit of the trapezoid.
Thanks,
This is the function:
const assess = (likelihood, impact) => {
var logicLikelihood = new fuzzy.Logic();
const lowLikelihood = new fuzzy.Trapezoid(0, 0, 2, 3);
const moderateLikelihood = new fuzzy.Trapezoid(2, 3, 7, 8);
const highLikelihood = new fuzzy.Trapezoid(7, 8, 10, 10);
logicLikelihood.init('low', lowLikelihood)
logicLikelihood.or('moderate', moderateLikelihood)
logicLikelihood.or('high', highLikelihood);
var logicImpact = new fuzzy.Logic();
const publicImpact = new fuzzy.Trapezoid(0, 0, 1.5, 2.5);
const internalImpact = new fuzzy.Trapezoid(1.5, 2.5, 4.5, 5.5);
const confidentialImpact = new fuzzy.Trapezoid(4.5, 5.5, 7.5, 8.5);
const restrictedImpact = new fuzzy.Trapezoid(7.5, 8.5, 10, 10);
logicImpact.init('public', publicImpact)
logicImpact.or('internal', internalImpact)
logicImpact.or('confidential', confidentialImpact);
logicImpact.or('restricted', restrictedImpact);
const tests = [];
// assessment very low
const securityTest_low_public = boon.getEvaluator('likelihood.low AND impact.public');
tests.push(securityTest_low_public);
// assessment low
const securityTest_low_internal = boon.getEvaluator('likelihood.low AND impact.internal');
tests.push(securityTest_low_internal);
// assessment medium
const securityTest_low_confidential = boon.getEvaluator('likelihood.low AND impact.confidential');
tests.push(securityTest_low_confidential);
// assessment high
const securityTest_low_restricted = boon.getEvaluator('likelihood.low AND impact.restricted');
tests.push(securityTest_low_restricted);
// assessment low
const securityTest_moderate_public = boon.getEvaluator('likelihood.moderate AND impact.public');
tests.push(securityTest_moderate_public);
// assessment medium
const securityTest_moderate_internal = boon.getEvaluator('likelihood.moderate AND impact.internal');
tests.push(securityTest_moderate_internal);
// assessment high
const securityTest_moderate_confidential = boon.getEvaluator('likelihood.moderate AND impact.confidential');
tests.push(securityTest_moderate_confidential);
// assessment very high
const securityTest_moderate_restricted = boon.getEvaluator('likelihood.moderate AND impact.restricted');
tests.push(securityTest_moderate_restricted);
// assessment low
const securityTest_high_public = boon.getEvaluator('likelihood.high AND impact.public');
tests.push(securityTest_high_public);
// assessment medium
const securityTest_high_internal = boon.getEvaluator('likelihood.high AND impact.internal');
tests.push(securityTest_high_internal);
// assessment high
const securityTest_high_confidential = boon.getEvaluator('likelihood.high AND impact.confidential');
tests.push(securityTest_high_confidential);
// assessment very high
const securityTest_high_restricted = boon.getEvaluator('likelihood.high AND impact.restricted');
tests.push(securityTest_high_restricted);
const resLikelihood = logicLikelihood.defuzzify(likelihood, 'likelihood');
const resImpact = logicImpact.defuzzify(impact, 'impact');
const jsBoonInput = { ...resLikelihood.boonJsInputs, ...resImpact.boonJsInputs }
const results = [];
for(let i = 0; i < tests.length; i++){
results.push( tests[i](jsBoonInput) );
}
if(results[0]) return "very low";
else if(results[1]) return "low";
else if(results[2]) return "medium";
else if(results[3]) return "high";
else if(results[4]) return "low";
else if(results[5]) return "medium";
else if(results[6]) return "high";
else if(results[7]) return "high";
else if(results[8]) return "low";
else if(results[9]) return "medium";
else if(results[10]) return "high";
else if(results[11]) return "very high";
else return "Unknown";
}
Hi
I will investigate this as soon as possible. Sorry for the inconvenience. As for the unclear defuzz step: please tell me more why it is unclear.
you are right about the right corner. But it is kind of connected to the fact that this is a special trapezoid on the side: the last two X coordinates are the same. Since these are the outer limits, you can always choose (7, 8, 10, 11) and (7.5, 8.5, 10, 11) to get the result from a trapezoid you want in your case
Another working solution would be to use a triangle as outer bound or stacking 2 triangles here. it is basically what you want to express here.
looking at trapezoid edge cases I am thinking I missed those as the whole api is a very very basic implementation.
Thanks a lot for this explanation, I used the trapezoid with 10.1 coordinate and I am having a working solution, I will try the triangle solution also.
Instead of the code that I posted above, I have developed a class that would make the code much cleaner, I can send you the code and maybe if you like it, I can contribute it to your nice framework so that the user can concentrate only on the rules. ([email protected])
Thanks
fork it and contribute back .... we can talk about any proposal. Maybe start small and then get bigger.
I think I will have to talk to someone who actually saw a university from inside and enjoyed maths (looking at your cv this might be you) if I can pick the 1 in our case (and what to do with the other trapezoid forms).
will keep this open until I have at least added a explanation and documentation.
I will fork it as you said, and show you the "small" contribution, it is a simple way to associate rules to evaluations to outputs (3-tuples of { rule, evaluation, output } ) + a batch evaluation loop that would fill the evaluation member, which makes the client code much shorter than the one I have added above. Regarding the math issue, I do not remember much about my "logique floue" course (fuzzy logic in french) I took a long time ago, but we'll see as I need it currently for this small project....
This comment from @JK-0 came to email from [email protected]. It's also not the first spam email I've received recently. Most are for crypto nonsense, others are for repos I've never interacted with or seen. If I unsubscribe from [email protected] I assume I'll miss out on real and needed emails. Has anyone else experienced this before?