This is a 50minutes seminar I am giving next week as a part of an Image Analysis tutorial I am teaching. In this seminar, I introduce Fuzzy Sets and the AI::FuzzyInference module to the students.
The students are supposed to have at least a basic knowledge of Perl.
The goal is to have the students walking out of the 50minutes seminar knowing how to use the AI::FuzzyInference module and ready for a 1hour seminar in which we use the module in an image analysis application.
Any comment or suggestion will be appreciated, especially with the goal of making this (either asis or modified) into a piece suitable for the Tutorials section.
Updates:
Update 1:
When calling the “new” method, I am now using a “Direct Object Syntax” (my $fis = AI::FuzzyInference>new;) instead of the “Indirect Object Syntax” I was using before. Thank you to ovid for pointing that out.
Update 2:
I added some comments about what the output of the script is when you run it. Thanks to talexb for pointing that out
Update 3:
Minor gramatical mistake fixed.
From:
Fuzzy Sets are a special type of sets that are able to express the notion of partial membership (as a value in the interval [0, 1] ) of an element to a particular group.
To:
A Fuzzy Set is a special type of set that is able to express the notion of partial membership (as a value in the interval [0, 1] ) of an element to a particular group.
Thanks to runrig for pointing it out
Introduction:
A Fuzzy Set is a special type of set that is able to express the notion of partial membership (as a value in the interval [0, 1] ) of an element to a particular group. Fuzzy Sets were first proposed by Prof. Lotfi Zadeh of the University of California at Berkeley in the 1965 paper “Fuzzy Sets”. Fuzzy Sets have been successfully used in applications that range from image processing and pattern recognition to decision support systems and fuzzy control systems. For a good overview on Fuzzy Sets and related terms (Fuzzy Logic and Fuzzy Control Systems), I encourage you to have a look at the Wikipedia.
Main Operations:
The AND, OR, and NOT operators of boolean logic exist in fuzzy logic. The AND operator is used to find the intersection between two sets (it is usually defined as the minimum between two Fuzzy Sets). The OR operator is used to find the union between two sets (it is usually defined as the maximum between two Fuzzy Sets). The NOT operator is used to find the complement of a set (it is usually defined as the subtraction of a membership function from 1)
RulesBased Systems:
Rules are usually expressed in the form:
IF variable_1 IS fuzzy_set_input_1 AND variable_2 IS fuzzy_set_input_2 THEN action IS fuzzy_set_output
the IF part is called the "antecedent" and the THEN part is called the "consequent".
In this example, the two input variables are "variable_1" and "variable_2". They have values defined as fuzzy sets. The output variable, "action", is also defined by fuzzy sets.
To make a decision based on a set of rules, a rulesbased system follows these steps:
 All the rules that apply are invoked, using the membership functions and truth values obtained from the inputs (by a process called fuzzification), to determine the result of the antecedent.
 This result in turn will be mapped into a membership function and truth value controlling the output variable. This process is known as implication. Two of the more common implication functions are: clipping (the fuzzy set is clipped to a value given by the level of activation of the input variables) and scaling ( the fuzzy set is multiplied by a value given by the level of activation of the input variables).
 These results are combined by a process called aggregation. One common approach for the aggregation involves using the “maximum” of the implicated sets.
 Finally, a process known as defuzzification is used to compute a single value that is representative of the aggregated fuzzy set. A typical defuzzification approach involves computing the centroid of the aggregated fuzzy set
The AI::FuzzyInference module:
Consider a system for assigning awards to Deserving Monks, directed by a Perl script. The script has to make decisions based on the "quality" of the nodes written by the Deserving Monks and the "speed" on which the Deserving Monk answer the cry for help from other monks. Therefore, one could have input variables: "quality" and "speed" and output variable "award".
The variable "quality" in this system can be subdivided into a range of values: "bad", "ok", "good", "excellent". The variable "speed" in this system can be subdivided into a range of values: "slow", "regular", "fast", "fastest". The variable "award" in this system can be subdivided into a range of values: "minimum", "small", "good", "excellent".
Among the rules for computing the 'award', we could have:
IF “quality” IS bad AND “speed” IS slow THEN “award” IS minimum
IF “quality” IS good AND “speed” IS slow THEN “award” IS small
IF “quality” IS ok AND “speed” IS fast THEN “award” IS good
IF “quality” IS excellent AND “speed” IS fast THEN “award” IS excellen
+t
Here, we have a step by step guide to implement the corresponding RulesBased System using the AI::FuzzyInference module:
First, we need to include the module
use AI::FuzzyInference;
Second, we need a FuzzyInference object to work with, so we create a new one
my $fis = AI::FuzzyInference>new;
Third, we define the input variables. For the input variable “quality” we have
$fis>inVar('quality', 0, 10,
bad => [ 0, 1, 2, 1, 4, 0 ],
ok => [ 2, 0, 4, 1, 6, 0 ],
good => [ 4, 0, 6, 1, 8, 0 ],
excelent => [ 6, 0, 8, 1, 10, 1 ],
);
on the first line, from left to right:
 $fis is the object identifier
 inVar indicates that we are entering an input variable
 'quality' is the name of the input variable
 0 is the minimum acceptable value for the input variable
 10 is the maximum acceptable value for the input variable
on the second line, from left to right:
 bad is a fuzzy set identifier
 0 is a value of the input variable
 1 is the membership value for an input value equal to 0
 2 is a value of the input variable
 1 is the membership value for an input value equal to 2
 4 is a value of the input variable
 0 is the membership value for an input value equal to 4
The graphical representation of fuzzy set "bad" is:

1.00BBBB
 B
0.50 B
 B
________B________________
0 2 4 6 8 10
Fourth, we define the output variable.
$fis>outVar('award', 0, 100,
minimum => [ 0,1, 20,1, 40,0 ],
small => [ 20,0, 40,1, 60,0 ],
good => [ 40,0, 60,1, 80,0 ],
excellent => [ 60,0, 80,1, 100,1 ],
);
on the first line, from left to right:
 $fis is the object identifier
 outVar indicates that we are entering an output variable
 'award' is the name of the output variable
 0 is the minimum value for the output variable
 100 is the maximum value for the output variable
on the second line, from left to right:
 minimum is a fuzzy set identifier
 0 is a value of the input variable
 1 is the membership value for an output value equal to 0
 20 is a value of the input variable
 1 is the membership value for an output value equal to 20
 40 is a value of the input variable
 0 is the membership value for an output value equal to 40
The graphical representation of fuzzy set "minimum" is:

1.00MMMM
 M
0.50 M
 M
_______M_____________________
0 20 40 60 80 100
Fifth, we add the rules
$fis>addRule(
'quality=bad & speed=slow' => 'award=minimum',
'quality=ok & speed=slow' => 'award=minimum',
'quality=good & speed=slow' => 'award=small',
'quality=excellent & speed=slow' => 'award=small',
on the first line, from left to right:
 $fis is the object identifier
 addRule indicates that we are entering a set of rules
on the second line, from left to right:
 'quality=bad & speed=slow' is the antecedent
 'award=minimum' is the consequent
Sixth, we compute the value of the “award” for a given set of values for the input variables.
$fis>compute( quality => $quality_of_service,
speed => $speed_of_service);
Finally, to recover the value of the output variable, we use:
my $award = $fis>value('award');
If we wanted to know the values of the main operations and the main functions, we use:
$fis>operation( '&' ); #for the AND operation
$fis>operation( '' ); #for the OR operation
$fis>implication(); #for the implication function
$fis>aggregation(); #for the aggregation function
$fis>defuzzification(); #for the defuzzification
In addition, we could select different values for the operations and the implication function by using:
$fis>operation( '&', 'difference');
$fis>operation( '', 'sum');
$fis>implication( 'scale' );
As a final note, another tutorial for the AI::FuzzyInference module is available in [1]
[1] Ala Qumsieh, “Fuzzy Logic in Perl,” The Perl Journal, pp. 37, June 2003
The complete script to assign the awards to Deserving Monks is given below.
When you run the script, it will ask you first for the quality of service of the Deserving Monk (it should be a number between 0 and 10. This number represents the average quality of the nodes written by the Monk). Let's say that we think the quality of service is "ok" so we enter the value "4". Then, the script will ask you for the speed of service (it should be a number between 0 and 10. This number represents how fast the Monk replies to the requests for help). Let's say that we consider that the Monk answer "very fast" to the requests (the Monk is not the fastest but is closer to the fastest) so we enter the value "7". After you enter that value, the script will show you the value of the award (a number between 0 and 100 representing the percentage of the maximum possible award).
For this example, the award will be 60. In addition to the value of the "award", the script will also inform you of the values of "&", "", "implication", "aggregation", and "defuzzification" it used in the computation. At the end of the script, I show you how to modify the values of "", and "implication". This is why you also see a print out indicating the "new values of  and implication".
Enjoy it!
#!/usr/bin/perl
use warnings;
use strict;
use AI::FuzzyInference;
##############
# problem: to assign an award to a deserving Monk
##############
#my $fis = new AI::FuzzyInference; # this indirect object
# notation was replaced
# for the direct
# notation below as
# suggested by ovid
my $fis = AI::FuzzyInference>new;
##############
# input variables: inVar
# 'service' relates to the quality of the nodes written by the Monk
# 'speed' relates to how fast the Monk offers a hand to a fellow
# monk in need
##############
$fis>inVar('quality', 0, 10,
bad => [ 0, 1, 2, 1, 4, 0 ],
ok => [ 2, 0, 4, 1, 6, 0 ],
good => [ 4, 0, 6, 1, 8, 0 ],
excellent => [ 6, 0, 8, 1,10, 1 ],
);
$fis>inVar('speed', 0, 10,
slow => [ 0, 1, 2, 1, 4, 0 ],
regular => [ 2, 0, 4, 1, 6, 0 ],
fast => [ 4, 0, 6, 1, 8, 0 ],
fastest => [ 6, 0, 8, 1,10, 1 ],
);
##############
# output variable: outVar
# 'award' relates to the quality of the award to be given
##############
$fis>outVar('award', 0, 100,
minimum => [ 0,1, 20,1, 40,0 ],
small => [ 20,0, 40,1, 60,0 ],
good => [ 40,0, 60,1, 80,0 ],
excellent => [ 60,0, 80,1, 100,1 ],
);
##############
# Adding the rules: addRule
##############
$fis>addRule(
'quality=bad & speed=slow' => 'award=minimum',
'quality=ok & speed=slow' => 'award=minimum',
'quality=good & speed=slow' => 'award=small',
'quality=excellent & speed=slow' => 'award=small',
'quality=bad & speed=regular' => 'award=minimum',
'quality=ok & speed=regular' => 'award=small',
'quality=good & speed=regular' => 'award=small',
'quality=excellent & speed=regular' => 'award=excellent',
'quality=bad & speed=fast' => 'award=small',
'quality=ok & speed=fast' => 'award=good',
'quality=good & speed=fast' => 'award=good',
'quality=excellent & speed=fast' => 'award=excellent',
'quality=bad & speed=fastest' => 'award=small',
'quality=ok & speed=fastest' => 'award=good',
'quality=good & speed=fastest' => 'award=excellent',
'quality=excellent & speed=fastest' => 'award=excellent',
);
##############
# Requesting information from the user:
# $quality_of_service, $speed_of_service
##############
my ($quality_of_service, $speed_of_service);
print "Please, enter the quality of service [0, 10]: ";
chomp ($quality_of_service = <STDIN>);
print "Please, enter the speed of service [0, 10]: ";
chomp($speed_of_service = <STDIN>);
##############
# computing the "award" given the "quality_of_service"
# and the "speed_of_service" as entered by the user
#
# Note: we are using the default values for:
# & (min),
#  (max),
# implication (clip),
# aggregation (max), and
# defuzzification (centroid)
##############
$fis>compute( quality => $quality_of_service,
speed => $speed_of_service);
##############
# reading and showing the value of the 'award'
##############
my $award = $fis>value('award');
print "\nAward (quality = $quality_of_service, speed = $speed_of_servi
+ce) [0, 100]: $award\n\n";
##############
# showing the values of:
# &, , implication, aggregation, defuzzification
##############
print "values of &, , implication, aggregation, and defuzzification\n
+";
print "& = ", $fis>operation( '&' ),"\n";
print " = ", $fis>operation( '' ),"\n";
print "implication = ", $fis>implication(), "\n";
print "aggregation = ", $fis>aggregation(), "\n";
print "defuzzification = ", $fis>defuzzification(), "\n\n";
##############
# modifying the values of  and implication
##############
$fis>operation( '', 'sum');
$fis>implication( 'scale' );
##############
# showing the new values of:  and implication
##############
print "new values of  and implication\n";
print " = ", $fis>operation( '' ),"\n";
print "implication = ", $fis>implication(), "\n";