Chao cac ban

(This article is an introduction of Artificial Intelligence and Fuzzy Logic on HERE. If you have interest in this theme you can start to continue there).

What is fuzzy? Fuzzy is in lay language "unsharp", "unclear", "blurred", "vague". Fuzzy Logic is a logic that expresses an statement which is relatively near, but not exactly to the core. It's the nature of human whose expression is usually blurred, unclear and sometimes quite ambiguous. For example: "I don't feel good". The rating of "don't feel good" becomes ambiguous and unsharp, too. Such an "expression" would lead to the question that would be "why you don't feel good?", or "what's wrong?". And the answer for the question is just "a bit" more precise, but still quite ambiguous (e.g. "I drank yesterday too much", or "I got a bad night", etc.). Such an ambiguity is the logic of "free rating" and "free rating" lets no room for an alternative.

Lotfi Zadeh, an American Mathematician, introduced Fuzzy Logic in 1920:

It is based on the observation that people make decisions based on imprecise and non-numerical information, fuzzy models or sets are mathematical means of representing vagueness and imprecise information, hence the term fuzzy.

Impreciseness and Vagueness are the foundation of Fuzzy Logic.

Fuzzy Programming (FP)

It doesn't mean that one has to code "precisely" in Zadeh's FL in order to have FL. Because FL is itself "imprecise" the fuzziness that leads to the goal is decisive. Hence Fuzzy Programming can be materialized with conventional "technique", too. As said, the goal is decisive. The way how to achieve the goal is secondary, peripheral. And that can be done the best in any OOPL such as JAVA or PYTHON or C/C++. CongdongJava is a JAVA community and so Fuzzy Programming is here in JAVA. Fuzzy Programming is useful and so some case the best to reduce the overload (response time) and the excessive use of memory (performance.)

Let start with an example. Suppose we have to build a Web Proxy to interface Browsers and the Web. The traffic between browsers and the Web is immense -big data if you so will. The problems for a web proxy are how

  • to pass efficiently the requests of different browsers (i.e. users) to the web, and
  • to handover the replies from the web to each individual browser.

It's clear that the classic architecture is Client-Server where the clients are the browsers and the web and the server is the Web Proxy. The server produces each thread that serves in between browser and the web. The latent time between browser and the web is crucial. This latent time is the processing time of server or the Web Proxy. The longer the processing time is, the more the latent time becomes. And the latent time is for the users no other thing than the response or reaction time of the server. A long response time is for the user usually inacceptable.

The rule of Fuzzy Programming is simple. It's restricted itself on the knowledge that the data are bound to a known set of values (as keys or commands) and each value is unambiguous. The Browser requests base on the HTTP protocol which has a set of unique commands like GET, PUT, POST, CONNECT, etc. And the Web responses base on the HTTP protocol, too. With this knowledge we are able to implement a Web Proxy in Fuzzy Programming technique.

An example of a Browser's HTTP Request to the Web and the Web's HTTP Response:

// HTTP Request
GET /... HTTP/1.1
...
Connection: keep-alive
Accept: ...
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36....

...
// HTTP Response
HTTP/1.1 200 OK
Date: Fri, 27 May 2016 14:43:04 GMT

...

But a Browser's HTTP Request to the Web Proxy is slightly different:

GET /... HTTP/1.1
...
Proxy-Connection: keep-alive
Accept: ...
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ...
...

The prefix Proxy- is inserted in front of the line "Connection: keep-alive". This prefix is unique and one of the HTTP rules is that the main keywords must always begin at a New Line after Carriage Return ("\r\n"). Knowing that we "fuzzy-program" to intercept the Browser Request and manipulate it so that the Web believes to be connected directly with the browser (not with the Web Proxy):

// Conventional Programming
   ByteBuffer wbuf = ByteBuffer.allocateDirect(2048);
   int len = soc.read(wbuf); // read 2KB from Browser SocketChannel
   ((ByteBuffer)wbuf.flip()).get(buf, 0, len);
   SocketChannel webSoc = SocketChannel.open(new InetSocketAddress(webHost, 80)):
   // search for "Proxy-Connection: keep-alive"
   String req = new String(buf, 0, len); // 1. object more with the size of len
   req = req.replace("Proxy-", ""); // 2. and 3. object more (new req, "Proxy-")
   buf = req.getBytes(); // 4. object more (new buf)
   webSoc.write(buf);
   ...
// Fuzzy Programming
   ByteBuffer wbuf = ByteBuffer.allocateDirect(2048);
   int len = soc.read(wbuf); // read 2KB from Browser SocketChannel
   ((ByteBuffer)wbuf.flip()).get(buf, 0, len);
   SocketChannel webSoc = SocketChannel.open(new InetSocketAddress(webHost, 80)):
   // search for "Proxy-Connection: keep-alive"
   for (int i 15; i < len; ++i) // start after "XYZ / HTTP/1.1\r >= 15
     // Checking for "Proxy-" at position
     // -  0 for byte \n (we know \n is after \r)
     // -  1 for the letter 'P' we look for P(roxy)
     // -  5 for the letter 'y' we look for (Prox)y
     // if all 3 conditions are met we assume that the word "Proxy-" was found.
     if (buf[i] == '\n' && buf[i+1] == 'P' && buf[i+5] == 'y') { // pos.0,1,5
       System.arraycopy(buf, i+7, buf, i+1, len - 6); // remove "Proxy-"
       len -= 6;
       break;
     }
   }
   webSoc.write(buf, 0, len);
   ...

The Conventional Programming technique looks quite simple and clear. But it produces 4 following additional objects that must be later "garbage-collected" (bad for Response Time):

  • String req
  • new String Req (due to String immutability)
  • String "Proxy-"
  • old buf (due to array immunity)

The Fuzzy Programming technique does look a bit "confusing", but faster and almost as precise as CP whereby no additional object was needed (less Garbage Collection.)

Fuzzy Programming Rules
FP bases on two assumptions:

  • Assumption that a keyword (e.g. "Proxy-Connection") or a pattern is then found if n letters match the same positions of the keyword/Pattern (0, 1 and 5). Instead of Checking for the whole keyword/pattern (or part of the keyword/pattern) only n unique letters are check at n determinate positions within the keyword. Pattern Recognition bases on such a Fuzzy Programming.
  • Assumption that the Probability (the "rate of Similarity") with n samples (here: the positions) should be so reliable that a deduction could be optimally achieved (up 0.5).

ALT
Map Reduce Algorithm (source TheGeekStuff.com)

Google Search Engine (GSE) works with Map Reduce Algorithm or MRA which is no other thing than Fuzzy Programming. MRA calculates the so-called "Term Frequency" or TF which is the frequency (or occurrence) of a term (or an expression, e.g. "Proxy") within a document (or object) and then the Inverse Document Frequency or IDF which is the weight of TF within a heap of documents. With TF-IDF GSE is able to deduct some search results whether they are the same or just similar (e.g. how much similar?) The deduction is based on the calculation "CosineSimilarity".

Some words about CosineSimilarity: We know in the trigonometry that cos(0°) is 1 and cos(90°) is 0. A range between [0, 1]. An angle of 90° indicates a perpendicularity. An angle of 0° signifies a parallelism of objects. Parallelism is in the geometry the similarity between two lines: the CosineSimilarity.

Cosine similarity then gives a useful measure of how similar two documents are likely to be in terms of their subject matter...The technique is also used to measure cohesion within clusters in the field of data mining.

(Wikipedia: CosineSimilarity)

And AI bases on Similarness, Commonness, Approximateness and Relativeness.

Back to our Web Proxy: with FP we can enhance our Web Proxy with more features, for example, a blacklist (of perversive ads), Cookie-Filter, a bridge to other networks (e.g. TOR network), etc. The full codes can be downloaded here (either with ZIP or with JZIP).

Fuzzy Logic

The "pure" lore of Fuzzy Logic is the work of Lotfi Zadeh. FL relies on Mathematical Probability and basses on Set Theory (ST) and for "the ease of vague understanding".

Fuzzy Logic is more real than "computer logic" where the reasoning is always unambiguous. EITHER this (result) OR that (alternative). FL is vague and approximate and there's NO alternative. Example:
Computer Logic (CL)

if a == b then c = a // result
else           c = b // alternative

Fuzzy Logic

if a similar b then c is a
  • CL is binary and crisp while FL is ambiguous and vague.
  • CL operators are absolute (==, =, etc) while FL operators are relative (similar, is, etc.)
  • CL object have two distinct states (entities) which are determinable while FL objects possess numerous states which can be vague and overlapping.
  • CL state (or data) is final while FL state (or data) is variable and imprecise.

Because FL is the synonym of Similarity, of Vagueness and of Approximateness FL data are indeterminate, imprecise and so FL variables become ambiguous. Thus Operations with FL data and FL variables are also vague, indeterminate and ambiguous. Such an absoluteness like Equal (==), Greater ( > ), etc. is too precise in oder to render an "ambiguous state" of an object which is in reality very common (e.g. cold, hot, warm, etc.)

FL Operations must be able to operate on the vague state of FL objects so that any transition between the states could be rendered. Because there's NO distinct transition between different states the ST operations (AND, OR, INVERSE, EXCLUSIVE/INCLUSIVE OR, INVERSE, etc.) can be optimally applied to FL. I don't go into details with Set-Theory operations, but hint you to see the given link above, or to Google for more if you want to do some researches on ST issues. Or THIS.

In order to render numerous states of a FL object FL Data must be a set of various ranges. Example: FL data for temperature:

  • cold is between -10° and +10°,
  • cool is between +8° and +18°,
  • fair is between +15° and +20°,
  • warm is between +18° and +26°,
  • hot is between +24° and +34°,

The data of Temperature can be extended, for example, to: very cold, absolute cold, very hot, boiling hot, etc. The state of each data range is floating between 0.0 to 1.0 (a double or a float -1.0 indicates the out of range) and has a form of either a pyramid or a trapezoid as following

ALT

The Y-Axis is the "Fuzzy Axis" and the X-Axis is the Sample-Axis. The perpendicular line that cuts the left or right line of the pyramid (or trapezoid) is the sample line. On the Sample-Axis it's the sampled value. The projection of the cutting point on Fuzzy-Axis gives the Fuzzy value. The calculation of the left and right area is called the "defuzzification". The result is then the final outcome of FL operations. Defuzzification can be computed as the Average which can be "fined-grained" or "coarse", or as the Center (or Centroid). An example of a FL operation:

if temperature is cool AND AirCon is low then room is cool

As we know, FL does not provide an alternative, hence the outcome is singular: room is cool. Nothing more. Nothing less. And the outcome (room) is also vague and ambiguous: cool between 8° and 18°. AI bases on knowledge and knowledge is big data. Data with complex and intricate ramification. Face or fingerprint or linguistic recognition is for example the most intensive R&D of today. However the results are mediocre. It isn't the inability of researchers and developers, it's the intricate ramification. And ramification can only be rendered by similarness and commonness of some certain traits. With FL we could convey some properties which mirror these features of the observing object. Face recognition appraises and measures, for example, the locations and forms of the eyes, mouth and nose and then deduct the face that has the most similar traits with a reference in an existing repository. Such a work is very time-consuming without FL.

Machine-Learning Programming with Fuzzy Logic

Machine Learning is another field that requires lots of detailed data. Big Data. If Face Recognition is extended to include animal faces more references must be established and validated (supervisor or unsupervisor). The locational details of eyes, mouth and nose must be reworked and categorized (human, animals, birds, insects). FL provides here the base for ML: dog-like (coyote, wolf, chihuahua, etc.), feline (lion, tiger, chetah, etc.) and so on.

Some IT developers think that AI needs AI-oriented language, Front-End requires JS and PHP, etc. They are wrong. All programming languages are suited to code AI applications. The knowhow, not the language itself is the key. JAVA or C/C++ is suited for AI as well. PYTHON is an interpretative language which can directly execute (the source codes) without compiling. And that was the lure to code in PYTHON (by researchers or developers who come from other fields than IT) to see how their AI-Idea works. Hence it's simple to work with "type-less" variables (int, float, double, etc.) because their types will be recognized and adjusted by PYTHON during the interpretative phase. And that can be done with JAVA or C/C++, too, as an AI engine which interprets the AI codes and execute them. Similar to an "AI-Engine" FL does not need a special FL language, but an FL engine that interprets the codes and executes them -exactly as PYTHON does.

Example: the following JAVA codes are the reduced codes of my FL-Engine. The excerpts show you how easily a FL-Engine is implemented in JAVA. The interpretive work may look complicated, but it isn't. It's the basic implementation technology of Interpreter. The FL result is FUZZY. Meaning: vague, imprecise. To attain the "crisp" values FL-Variable must be "defuzzified". The Defuzzification is the weighting of all set samples of FL-Variable. The calculation bases on the left and right area of each sample. If the computing is either

  • fine-grained, or
  • coarse, or
  • centroid

FL depends on FuzzyData and how the states (data) are arranged as pyramid or trapezoid. If the arrangements are contradictory FL could deliver contradictory result, too.

The "ancient" naming for "Machine Learning" is "Automatization". Due to limited memory and mediocre processor "ancient" automatized machine is good, but not as intelligent as the modern "Machine" which can learn. Hence: Machine Learning. As discussed in previous chapter ML is AI that bases on a big repository knowledge. And knowledge is Similarness, Commonness, Approximateness and Relativeness. Such requirements suit the best Fuzzy Logic and FuzzyData is a state which describes an entity and ranges from X to Y -not determinate, but floating.

The given example Room.java is a simplified Machine Learning in both modes: Supervisor and Unsupervisor. With 2 parameters Room can be controlled either by a "Supervisor" or "itself" the Supervisor (Unsupervisor).

import fuzzylogic.FuzzyEngine;
// Joe Nartca (C)
// 2 parameters
// - 1st parameter (a double) is the outside temperature
// - 2nd parameter (anything) is for Machine Learning.
// 1 parameter: either a double (outside temperature) or anything (see 2nd parameter)
// NONE: default. -10 Celsius, Supervisor
public class Room {
  public static void main(String... args) throws Exception {
    double outside = -10d;
    boolean auto = false;
    if (args.length > 0) {
      try {
        outside = Double.parseDouble(args[0]);
        if (args.length == 2) auto = true;
      } catch (Exception ex) {
        outside = -10d;
        auto = true;
      }
    }
    // preset Room Temperature between -10 to 35 Celsius
    double temp = outside < -10d? -10d:(outside > 35)? 35:outside;
    ...
    FuzzyEngine eng = new FuzzyEngine();
    // Temperature
    eng.defFuzzyData("cold", -100d, 0d, 10d);
    ...
    eng.defFuzzyVariable("room");
    eng.addFDtoFV("room", "cold");
    ...
    // AirConditioner
    eng.defFuzzyData("min", -10.5d, -8d, -6.5d);
    ...
    eng.defFuzzyVariable("AirCon");
    eng.addFDtoFV("AirCon", "min");
    ...
    // temp
    eng.defFuzzyVariable("temp");
    eng.addFDtoFV("temp", "cold");
    ...
    double rate = 0.0d;
    // the range of values 20d...22d is the "knowledge" (known in repository)
    while (temp < 20d || temp > 22d) {
      eng.setFVSample("room", temp);
      if (auto) { // <<<< Unsupervisor Machine Learning
        eng.execute("if room is cold then AirCon is max");
        eng.execute("if room is cool then AirCon is high");
        eng.execute("if room is fair then AirCon is OFF");
        eng.execute("if room is warm then AirCon is low");
        eng.execute("if room is hot  then AirCon is min");
        // <<<<< self-calibrated AirConditioner >>>>>>
        rate = eng.defuzzy("AirCon", 0);
      }
      eng.setFVSample("AirCon", rate);
      eng.execute("if room is cold and AirCon is min then temp is cold");
      eng.execute("if room is cool and AirCon is min then temp is cold");
      eng.execute("if room is fair and AirCon is min then temp is cold");
      eng.execute("if room is warm and AirCon is min then temp is cool");
      eng.execute("if room is hot  and AirCon is min then temp is fair");

      eng.execute("if room is cold and AirCon is low then temp is cool");
      eng.execute("if room is cool and AirCon is low then temp is cool");
      eng.execute("if room is fair and AirCon is low then temp is fair");
      eng.execute("if room is warm and AirCon is low then temp is fair");
      eng.execute("if room is hot  and AirCon is low then temp is warm");

      eng.execute("if room is cold and AirCon is OFF then temp is cool");
      eng.execute("if room is cool and AirCon is OFF then temp is fair");
      eng.execute("if room is fair and AirCon is OFF then temp is fair");
      eng.execute("if room is warm and AirCon is OFF then temp is warm");
      eng.execute("if room is hot  and AirCon is OFF then temp is hot");

      eng.execute("if room is cold and AirCon is high then temp is cool");
      eng.execute("if room is cool and AirCon is high then temp is fair");
      eng.execute("if room is fair and AirCon is high then temp is warm");
      eng.execute("if room is warm and AirCon is high then temp is warm");
      eng.execute("if room is hot  and AirCon is high then temp is hot");

      eng.execute("if room is cold and AirCon is max then temp is fair");
      eng.execute("if room is cool and AirCon is max then temp is warm");
      eng.execute("if room is fair and AirCon is max then temp is warm");
      eng.execute("if room is warm and AirCon is max then temp is hot");
      eng.execute("if room is hot  and AirCon is max then temp is hot");
      temp = eng.defuzzy("temp", 0); // Defuzzified room's temperature
      if (!auto) { // <<<< Supervisor Machine Learning
        // Supervisor calibrates the scale of AirConditioner
        rate += temp > 25? -1d:temp > 20d? -0.5: temp > 0d? 0.5d:1d;
        rate  = (rate < -10d)? rate + 1d:(rate < 10d)? rate:rate - 0.5;
      }
    }
    System.out.printf("Outside: %2.2f Celsius, Room: %2.2f Celsius, AirCon: %2.2f\n",
                      outside, temp, rate);
    ...
  }
}  

The following excerpt shows you how FuzzyLogic Expressions are interpreted and executed.

package fuzzylogic;
// Joe Nartca (C)
public class FuzzyEngine {
  public FuzzyEngine( ) {
    ...
  }
  public void defFuzzyVariable(String name) {
    ...
  }
  // FD pyramid
  public void defFuzzyData(String name, double left, double top, double right) {
    ...
  }
  // FD trapezoid
  public void defFuzzyData(String name, double left, double ltop, double rtop, double right) {
    ...
  }
  ...
  // Simplify FuzzyEngine with only 2 ST-Operations: AND and OR
  // FL Expresion: if FV1 is FD1 and/or FV2 is FD2 ... then FVr is FDr
  public void execute(String fuzzy) throws Exception {
    String[] terms = fuzzy.split(" ");
    ArrayList<String> fExp = new ArrayList<String>(terms.length);
    for (String s:terms) if (s.length() > 0) fExp.add(s);
    if (fExp.size() < 8) throw new Exception("Incomplete FuzzyExpression:"+fuzzy);
    boolean ok = false; boolean IF = true;// syntax check
    for (int i = 0, mx = fExp.size(); i < mx; ) {
      if (!fExp.get(i++).equalsIgnoreCase("if") && IF)
        throw new Exception("Expected \"if\" but found:"+fExp.get(i-1));    
      if (!FVs.containsKey(fExp.get(i++)))
        throw new Exception("Expected \"FV\" but found:"+fExp.get(i-1));
      if (!fExp.get(i++).equalsIgnoreCase("is"))
        throw new Exception("Expected \"is\" but found:"+fExp.get(i-1));    
      if (!FDs.containsKey(fExp.get(i++)))
        throw new Exception("Expected \"FD\" but found:"+fExp.get(i-1));
      if ((i+1) >= mx) {
        if (!ok) throw new Exception("Invalid Syntax:"+fuzzy);
        break;
      }
      String op = fExp.get(i);
      ok = op.equalsIgnoreCase("then");
      if (!op.equalsIgnoreCase("and") && !op.equalsIgnoreCase("or") &&
          !ok) throw new Exception("Expected \"Operator\" but found:"+op);
      if (i >= mx) throw new Exception("Invalid Syntax:"+fuzzy); 
      IF = false;
    }
    // execute
    IF = true;
    ok = false;
    double result = -1d;
    for (int i = 0, mx = fExp.size(); i < mx; i += 4) {
      String op = fExp.get(i);
      String fvName = fExp.get(i+1);
      String fdName = fExp.get(i+3);
      FuzzyVariable fv = FVs.get(fvName);
      if (IF) {
        IF = false;
        result = fv.isFuzzy(fdName);
      } else if (op.equalsIgnoreCase("then")) {
        if (result != -1d) fv.addPoint(fdName, result);
        return;
      } else {
        double d = fv.isFuzzy(fdName);
        if (op.equalsIgnoreCase("and")) {
          if (d < result) result = d;
        } else { // it's an OR
          if (d > result) result = d;
        }
      }
    }
  }
  ...
}

Download the room.zip (conventional ZIP file) or room.txt (the JZIP file) from HERE/Part 2 and un(j)zip it. The content consists of:

  • FuzzyData.java
  • FuzzyVariable.java
  • FuzzyEngine.java (reduced from Joe's FuzzyEngine.java)
  • Room.java

and if you've successfully compiled the sources and run the "Room" the Room's output is as following:

C:\links\java\AI_FL>javac -g:none -d ./classes Room.java

C:\links\java\AI_FL>java Room 100
Outside: 100,00 Celsius, Room: 20,40 Celsius, AirCon: -10,00

C:\links\java\AI_FL>java Room 30
Outside: 30,00 Celsius, Room: 21,80 Celsius, AirCon: -9,50

C:\links\java\AI_FL>java Room 50
Outside: 50,00 Celsius, Room: 20,40 Celsius, AirCon: -10,00

C:\links\java\AI_FL>java Room -50
Outside: -50,00 Celsius, Room: 21,80 Celsius, AirCon: 7,00

C:\links\java\AI_FL>java Room -10
Outside: -10,00 Celsius, Room: 21,80 Celsius, AirCon: 7,00

C:\links\java\AI_FL>java Room -1
Outside: -1,00 Celsius, Room: 20,40 Celsius, AirCon: 7,00

C:\links\java\AI_FL>java Room -1 auto
Outside: -1,00 Celsius, Room: 21,80 Celsius, AirCon: 7,95

C:\links\java\AI_FL>

Enjoy!