[ Main page | About Your System | Knowledge Bases | Rule Traces | Demand Modelling | About Fuzzy Logic | The Importance of Explainability | Commercialising ]
In my tutorial and the shoe-size expert system,
both linked from the
About Fuzzy Logic page,
you will have seen the very detailed diagnostics that
some of my expert systems give. They plot a graph for
every test of an input against a rule condition, showing
the shape of its fuzzy set membership functions and how
reading along the slopes converts the inputs to memberships.
They also show how the and
and or
operators combine their inputs by taking the minimum
or maximum respectively.
This is fine for one-shot demonstrations. However, it could be slow and memory-intensive when knowledge bases could be fired off repeatedly, as can happen with your simulation. (At least unless I can find a more responsive graphing package. If you want to discuss that or any other improvements, please ask.)
So in this sim, I've simplified the tracing. It still summarises how each rule in a knowledge base does as it matches, but without the graphical overhead. The traces are somewhat harder to read, as you need to look up or plot the fuzzy sets for yourself, but they are also faster and still gives you a check on what should happen. This page leads you through what the traces are saying, and may be a useful first explanation of how the knowledge bases work.
Let's start with the third knowledge base,
๐ผ๐ท or "torb". This is the simplest because it
uses no input sets at all. Instead, it tests the
categorical variable class
for one
of two values: "tourist"
or
"business"
. Here
is a trace:
๐ผ โ๐ 62 ๐ช25 ฮฃ๐ 0.00 ๐ท0 ๐0 ๐ง ๐ผ๐ท if class = "business" [1.00] then price_increase is moderate [1.00]. if class = "tourist" [0.00] then price_increase is low [0.00]. ⌖moderateร[1.00]+lowร[0.00]. ⌖tri(20,50,75)ร[1.00]+down(0,0,25)ร[0.00]. ⌖48.33.
The top line of the trace describes the input variables and the knowledge base used. The variables are:
Note that different knowledge bases use different variables. The above is a complete list of variables, but it doesn't imply that any one rule uses them all.
The second and third lines each show one rule's progress. If a categorical variable is equal to a given value, it's as if it were a fuzzy set with membership 1. Otherwise, it's like a fuzzy set with membership 0. So the second rule gets a weight of 1 for its output, whereas the third rule gets 0. In effect, the pair of rules act as a gate, routing attention fully to the second output or fully to the third.
This means that the only fuzzy set used in making the output ismoderate
. So it gets multiplied by
1 whereas the fuzzy set low
gets multiplied by 0.
This is summarised by the fourth line. I've introduced it
by the symbol ⌖ which looks rather like an engineer's
"centre of gravity" symbol and could plausibly mean "centroid".
The fifth line replaces the set names by their values.
The fuzzy set low
is revealed as a membership
function which slopes down from (0,1) to (25,0); the fuzzy
set moderate
, as a triangle with
base at (20,0) and (75,0), and apex (50,1). This gives me
at least a quick check that that part of the system works
as intended.
Finally, on the sixth line, the weighted fuzzy sets have been added and the result centroided, giving 8.
Categorical variables were added to your system so that we could handle discrete values such as class. Much more common, of course, are fuzzy variables. The trace below illustrates these.
๐ผ โ๐ 62 ๐ช25 ฮฃ๐ 0.00 ๐ท0 ๐0 ๐ง โ๐ if days_to_flight is many_days [1.00] then price_increase is low [1.00]. if days_to_flight is few_days [0.00] then price_increase is moderate [0.00]. ⌖lowร[1.00]+moderateร[0.00]. ⌖down(0,0,25)ร[1.00]+tri(20,50,75)ร[0.00]. ⌖8.00.
Here, the knowledge base is โ๐
or "dtf",
for days to flight. It too has only two rules,
both involving one input fuzzy set. The sets were
chosen so that if days to flight is the
maximum possible, 62, then it belongs to
many_days
with membership 1. It
doesn't belong to few_days
at all.
So although the mechanism is somewhat different, the effect is the same as in the other knowledge base. One rule fires entirely and the other not at all, and we get the same low price. Inspection will show that it is again 8.
Above, one fuzzy set had a membership of 1, and the other of 0. But a well-designed knowledge base will make sets overlap when needed to provide a smooth transition. I did this with the knowledge base โ๐ ๐, "dtflm". The running-person emoji symbolises urgency, "last minute". Here are the rules:
๐ผ โ๐ 62 ๐ช25 ฮฃ๐ 0.00 ๐ท0 ๐0 ๐ง โ๐ ๐ if days_to_flight is many_days [1.00] then price_increase is low [1.00]. if days_to_flight is few_days [0.00] then price_increase is moderate [0.00]. if days_to_flight is last_minute [0.00] then price_increase is high [0.00]. ⌖lowร[1.00]+moderateร[0.00]+highร[0.00]. ⌖down(0,0,25)ร[1.00]+tri(20,50,75)ร[0.00]+up(70,100,100)ร[0.00]. ⌖8.00.
These were run with the same inputs as above, the draggable bar being hard over to the left. So days to flight is its maximum at 62, and as before, only one fuzzy set fires. We get a centroid of 8 again.
But, inspection of the knowledge base will show that both pairs of sets overlap significantly, more so than in โ๐ . This means that if you drag the bar to the right and invoke โ๐ ๐ again, you'll eventually hit one of two transition regions. The sets on both sides will contribute thereto. As it's good practice, I invite you to try this for yourself. Read the fuzzy-set definitions in the knowledge base to see where they overlap. Maybe plot rough graphs of them all. Then drag the bar to one of the regions, invoke โ๐ ๐, and look at the trace.
You will now have noticed that each condition gets tagged with a coloured number in square brackets, which is repeated in at the end of the rule. If you tried the final paragraph above, you'll also have noticed that these are not always just 1 or 0.
These are the membership numbers, and as explained in the fuzzy-logic links, they measure how much the condition holds. It's like saying that I, at 6 foot 4 inches, am tall, whereas Eddie at 5 foot 10 inches, is only a bit tall. Or that my shoes, which are 11 in UK sizes, are large, whereas Eddie's, at 7, are average. English owns no precise definition of "tall" or "large", and no cut-off point such that 6 foot 4 inches (say) is tall but 6 foot 3 inches is not. Similarly with, say, weather. But we can say, a bit vaguely, that something is 10% tall or 70% big or 90% chilly, and that is what we are doing here. Behind the scenes, a rule-evaluator is handling all this, using fuzzy logic to ensure that these numbers get used in a consistent and mathematically respectable way.
Basically, this is a way of having lots of rules that forecast different aspects of a problem, working out how well each one fits the data, and then integrating all their advice, paying most attention to the rules that fit best. My diagnostics colour the memberships so that you can appreciate their influence at a glance: red stands out, and indicates a high value; blue or grey, a lower contribution.
Finally, like normal logic, fuzzy logic has
and
and or
operators.
Each of these takes two membership values and takes
the greatest for or
, or the least for
and
. As membership values ultimately
get used for weighting contributions from a rule's
output, and
is like a gate which gives
control over this to the smaller of its two arguments.
In the extreme case, if one of and
's
arguments is 0, the output can never be more than 0.
So that argument has full control over the output.
Here is the โ๐
๐ผ๐ท knowledge base, demonstrating
and
. Note how, because the class is not tourist, the
two rules that check for it being so get, in effect, switched off.
Looking at it from the other end, since days to flight is many
days but not few days, the two that check for it being
few days get switched off. This leaves one rule, the top one.
It has two reds in its inputs, and hence a red in its output.
๐ผ โ๐ 62 ๐ช25 ฮฃ๐ 0.00 ๐ท0 ๐0 ๐ง โ๐ ๐ผ๐ท if ( class = "business" [1.00] and days_to_flight is many_days [1.00] ) โฎ [1.00] then price_increase is moderate [1.00]. if ( class = "business" [1.00] and days_to_flight is few_days [0.00] ) โฎ [0.00] then price_increase is high [0.00]. if ( class = "tourist" [0.00] and days_to_flight is many_days [1.00] ) โฎ [0.00] then price_increase is low [0.00]. if ( class = "tourist" [0.00] and days_to_flight is few_days [0.00] ) โฎ [0.00] then price_increase is moderate [0.00]. ⌖moderateร[1.00]+highร[0.00]+lowร[0.00]+moderateร[0.00]. ⌖tri(20,50,75)ร[1.00]+up(70,100,100)ร[0.00]+down(0,0,25)ร[0.00]+tri(20,50,75)ร[0.00]. ⌖48.33.