JFCM - Java Fuzzy Cognitive Maps

Navigation

If JFCM was beneficial to your activity, please consider making a donation via PayPal to demonstrate your appreciation and willing to support next developments.

The amount to donate is up to your choice. Thank you!

Support This Project

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 samples package:

http://jfcm.svn.sourceforge.net/viewvc/jfcm/JFCM-samples/trunk/

 

in InvestmentsExample.java.

The Map

In this cognitive map we have four concepts:

  • c1: Interest rate;
  • c2: Productive investments;
  • c3: Occupation;
  • c4: 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:

 

Fuzzy Cognitive Map: Investments example

 

Conceptual maps can be created in two ways:

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

How to create a map programmatically

The code below is an excerpt from jfcm-samples, a project on GitHub that contains this and other examples of JFCM usage.

The complete code for this particular example can be found in InvestmentsExample.java source file.

 

CognitiveMap map = new CognitiveMap("Investments");
SignumActivator af = new SignumActivator();
af.setIncludePreviousOutput(false);

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

Configure concepts as "fixed":

map.getConcepts().get("c1").setFixedOutput(true);

Or simply execute the map:

map.execute();

 

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.

Important Note: this example uses the new 1.1 XML format, used since version 1.1.0 of the library.

<?xml version="1.0" encoding="UTF-8"?>
<jfcm:maps xmlns:jfcm="http://www.megadix.org/standards/JFCM-map-v-1.2.xsd">
  <map name="Investments">
    <description>Example inspired by S. Cammarata "Reti neuronali - dal perceptron alle reti caotiche e neuro-fuzzy" (1997) Etas Libri</description>
    <concepts>
      <concept act="SIGNUM" input="0.0" name="c1" output="0.0">
        <description>Interest rate</description>
        <params>
          <param name="includePreviousOutput" value="false" />
        </params>
      </concept>
      <concept act="SIGNUM" input="0.0" name="c2" output="0.0">
        <description>Productive investments</description>
        <params>
          <param name="includePreviousOutput" value="false" />
        </params>
      </concept>
      <concept act="SIGNUM" input="0.0" name="c3" output="0.0">
        <description>Occupation</description>
        <params>
          <param name="includePreviousOutput" value="false" />
        </params>
      </concept>
      <concept act="SIGNUM" input="0.0" name="c4" output="0.0">
        <description>Inflation</description>
        <params>
          <param name="includePreviousOutput" value="false" />
        </params>
      </concept>
    </concepts>
    <connections>
      <connection from="c1" name="c1 -&gt; c2" to="c2" type="WEIGHTED">
        <description>Interest rate -&gt; Productive investments</description>
        <params>
          <param name="weight" value="-0.8" />
        </params>
      </connection>
      <connection from="c2" name="c2 -&gt; c3" to="c3" type="WEIGHTED">
        <description>Productive investments -&gt; Occupation</description>
        <params>
          <param name="weight" value="1.0" />
        </params>
      </connection>
      <connection from="c3" name="c3 -&gt; c4" to="c4" type="WEIGHTED">
        <description>Occupation -&gt; Inflation</description>
        <params>
          <param name="weight" value="0.9" />
        </params>
      </connection>
      <connection from="c4" name="c4 -&gt; c1" to="c1" type="WEIGHTED">
        <description>Inflation -&gt; Interest rate</description>
        <params>
          <param name="weight" value="1.0" />
        </params>
      </connection>
    </connections>
  </map>
</jfcm:maps>

Save it, then call FcmIO.loadXml():

CognitiveMap map = FcmIO.loadXml("/PATH/TO/InvestmentsExample.xml").get(0);

/PATH/TO/InvestmentsExample.xml is the absolute or relative path to the XML file shown above. Because the file contains just one map, we call get(0) on the returned List object to retrieve the first map (Lists positions in Java are 0-based).