Your first fuzzy cognitive map

Our first map is taken from:

"Reti neuronali - dal perceptron alle reti caotiche e neuro-fuzzy"
Silvio Cammarata - Etas Libri

You can find the source code of this example in the binary distribution in src/examples/InvestmentsExample.java.

The Map

In this cognitive map we have four concepts:

  • Interest rate;
  • Productive investments;
  • Occupation;
  • Inflation.

 Next, we'll identify some connections between these concepts:

  • an increase of Interest rate results in a decrease of Productive investments with a degree of -80%;
  • an increase of Productive investments results in an increase of Occupation with a degree of +100%;
  • an increase of Occupation results in an increase of Inflation with a degree of +90%;
  • an increase of Inflation results in an increase of Interest rate with a degree of +100%.

These values are taken from experience, interviews with experts, custom research, and so on. The topic itself is huge and interesting, but we can leave it by now. So, here's a nice picture of the conceptual map:

 

 

Conceptual maps can be created in two ways:

  • programmatically, i.e. using JFCM APIs;
  • creating an xml file [TODO link to XSD] that describes the map and load it using the org.megadix.jfcm.utils.FcmIO utility class.

How to create a map programmatically

Here's how to create the map using JFCM APIs:

CognitiveMap map = new CognitiveMap("Investments");
ConceptActivator af = new SignumActivator();

Concept c1 = new Concept("c1", "Interest rate", af, 0.0, 0.0, false);
map.addConcept(c1);
Concept c2 = new Concept("c2", "Productive investments", af, 0.0, 0.0, false);
map.addConcept(c2);
Concept c3 = new Concept("c3", "Occupation", af, 0.0, 0.0, false);
map.addConcept(c3);
Concept c4 = new Concept("c4", "Inflation", af, 0.0, 0.0, false);
map.addConcept(c4);

FcmConnection conn_1 = new WeightedConnection("c1-c2",
        "Interest rate -> Productive investments", -0.8);
map.addConnection(conn_1);
FcmConnection conn_2 = new WeightedConnection("c2-c3",
        "Productive investments -> Occupation", 1.0);
map.addConnection(conn_2);
FcmConnection conn_3 = new WeightedConnection("c3-c4",
        "Occupation -> Inflation", 0.9);
map.addConnection(conn_3);
FcmConnection conn_4 = new WeightedConnection("c4-c1",
        "Inflation -> Interest rate", 1.0);
map.addConnection(conn_4);

map.connect("c1", "c1-c2", "c2");
map.connect("c2", "c2-c3", "c3");
map.connect("c3", "c3-c4", "c4");
map.connect("c4", "c4-c1", "c1");

 

After that, we can:

  • set values of concepts;
  • configure concepts as "fixed";
  • execute the map.

 

Concepts are stored in a java.util.Map, indexed by concept name; this means that each concept must have a unique name, otherwise strange errors would start to happen! The concept Map can be retrieved with the CognitiveMap.getConcepts() method.

How to create a map from an xml file

Here is the xml file that represents the above map:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<maps>
  <map name="Investments">
    <concepts>
      <concept act="SIGNUM" input="0.0" name="Inflation" output="0.0">
        <description>Inflation</description>
        <param name="threshold" value="0.0"/>
      </concept>
      <concept act="SIGNUM" fixed="true" input="0.0" name="Interest rate" output="1.0">
        <description>Interest rate</description>
        <param name="threshold" value="0.0"/>
      </concept>
      <concept act="SIGNUM" input="0.0" name="Occupation" output="0.0">
        <description>Occupation</description>
        <param name="threshold" value="0.0"/>
      </concept>
      <concept act="SIGNUM" input="0.0" name="Productive investments" output="0.0">
        <description>Productive investments</description>
        <param name="threshold" value="0.0"/>
      </concept>
    </concepts>
    <connections>
      <connection from="Inflation" name="Inflation -&gt; Interest rate" to="Interest rate" type="WEIGHTED">
        <description>Inflation -&gt; Interest rate</description>
        <param name="name" value="1.0"/>
      </connection>
      <connection from="Interest rate" name="Interest rate -&gt; Productive investments" to="Productive investments" type="WEIGHTED">
        <description>Interest rate -&gt; Productive investments</description>
        <param name="name" value="-0.8"/>
      </connection>
      <connection from="Occupation" name="Occupation -&gt; Inflation" to="Inflation" type="WEIGHTED">
        <description>Occupation -&gt; Inflation</description>
        <param name="name" value="0.9"/>
      </connection>
      <connection from="Productive investments" name="Productive investments -&gt; Occupation" to="Occupation" type="WEIGHTED">
        <description>Productive investments -&gt; Occupation</description>
        <param name="name" value="1.0"/>
      </connection>
    </connections>
  </map>

Save it somewhere on your computer, then call FcmIO.loadXml() method passing a java.io.InputStream as parameter. Here's a snippet:

CognitiveMap map = FcmIO.loadXml(new FileInputStream("SWDevelopment.xml")).get(0);

We know in advance that the file contains just one map, so we call get(0) on the returned List object to retrieve the first map (as you already know, Lists in Java are 0-based).