Perl: the Markov chain saw PerlMonks

### Comment on

 Need Help??

Greetings Fellow Monks,

This is a 50-minutes 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 tutorial is divided into six parts:

1. Introduction to Image Analysis;
2. Introduction to the Insight Toolkit (a toolkit for image processing, registration, and segmentation);
3. Introduction to Fuzzy Sets (the first part of this seminar)
4. Introduction to the AI::FuzzyInference module (the second part of this seminar);
5. Design strategies for Image Analysis Applications; and
6. Development of an Image Analysis Application.

The operating system is Linux

The students are supposed to have at least a basic knowledge of Perl.

The goal is to have the students walking out of the 50-minutes seminar knowing how to use the AI::FuzzyInference module and ready for a 1-hour 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 as-is or modified) into a piece suitable for the Tutorials section.

Thank you,

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)

Rules-Based 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 rules-based system follows these steps:

1. 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.
2. 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).
3. These results are combined by a process called aggregation. One common approach for the aggregation involves using the “maximum” of the implicated sets.
4. 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 Rules-Based 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.00|BBBB
|    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.00|MMMM
|    M
0.50|     M
|      M
|_______M_____________________
0  20  40  60  80 100

```\$fis->addRule(
'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. 3-7, 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 ],
);

##############
##############
'quality=ok         &   speed=slow'       =>  'award=minimum',
'quality=good       &   speed=slow'       =>  'award=small',
'quality=excellent  &   speed=slow'       =>  'award=small',

'quality=ok         &   speed=regular'    =>  'award=small',
'quality=good       &   speed=regular'    =>  'award=small',
'quality=excellent  &   speed=regular'    =>  'award=excellent',

'quality=ok         &   speed=fast'       =>  'award=good',
'quality=good       &   speed=fast'       =>  'award=good',
'quality=excellent  &   speed=fast'       =>  'award=excellent',

'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";

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
• Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
• Read Where should I post X? if you're not absolutely sure you're posting in the right place.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
• You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
 For: Use: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (2)
As of 2017-08-17 17:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Who is your favorite scientist and why?

Results (290 votes). Check out past polls.

Notices?