Tsetlin Machine Binary Classification Example Using JavaScript

The goal of a machine learning binary classification problem is to predict a variable that has exactly two possible values. For example, you might want to predict the sex of a company employee (male = 0, female = 1) based on salary, height, years of experience, and so on.

There are approximately a dozen common binary classification techniques, such as logistic regression, k-nearest neighbors, random forest, and neural network. A relatively new technique is called Tsetlin Machine binary classification.

(Note that in addition to binary classification, Tsetlin Machine systems can also be adapted for multi-class classification where the variable to predict has three or more possible values, and for regression problems where the variable to predict is a single numeric value. But those are significantly different than binary classification. The term “Tsetlin” refers to a Soviet mathematician who studied some of the ideas related to the underlying algorithm in the 1960s.)

I put together a demo using JavaScript. The demo program begins by loading a two-class subset of the well-known Iris Dataset into memory. The goal is to predict the species of an Iris flower based on four features: sepal length, sepal width, petal length, petal width.

The complete (not subset) raw data looks like:

5.1, 3.5, 1.4, 0.2, Iris-setosa
4.9, 3.0, 1.4, 0.2, Iris-setosa
. . .
7.0, 3.2, 4.7, 1.4, Iris-versicolor
6.4, 3.2, 4.5, 1.5, Iris-versicolor
. . .
6.2, 3.4, 5.4, 2.3, Iris-virginica
5.9, 3.0, 5.1, 1.8, Iris-virginica

For binary classification, I used just the setosa and versicolor items. The resulting encoded data looks like:

0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,  0
. . .
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,  1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,  1

There are 17 values on each line. The first 16 are predictor values that have been binary encoded. The last value is the target species to predict, setosa = 0, versicolor = 1. There are 80 training items and 20 test items. A simultaneous strength and weakness of Tsetlin Machine systems is that predictor values must be binary encoded. I used the encoding scheme from an example on the primary Tsetlin implementation reference at github.com/cair/TsetlinMachine. The mapping is:

[0.0, 1.5] = 0000
[1.6, 3.1] = 0001
[3.2, 4.7] = 0010
[4.8, 6.3] = 0011
[6.4, 7.9] = 0100

The output of my demo is:

Begin Tsetlin binary classification using node.js JavaScript

Loading train (80) and test (20) data from file

First three train X:
 0  0  1  1  0  0  1  0  0  0  0  0  0  0  0  0
 0  0  1  1  0  0  0  1  0  0  0  0  0  0  0  0
 0  0  1  0  0  0  1  0  0  0  0  0  0  0  0  0

First three train y:
0
0
0

Setting nClauses = 20
Setting nFeatures = 16
Setting nStates = 50
Setting s (random update inverse frequency) = 3.0
Setting threshold (voting clip) = 10
Creating Tsetlin Machine binary classifier
Done

Setting training maxEpochs = 100
Starting training
Epoch    0 |  Accuracy = 0.5000
Epoch   20 |  Accuracy = 0.7000
Epoch   40 |  Accuracy = 0.9125
Epoch   60 |  Accuracy = 0.6750
Epoch   80 |  Accuracy = 0.8750
Done

Accuracy (train) = 0.9125
Accuracy (test) = 0.9500

Predicting class for trainX[0]
Predicted y = 0

End Tsetlin demo

Tsetlin Machine systems use a radically different algorithm than all other classification techniques. I have a lot of experience at implementing machine learning systems, and the underying algorithm of the Tsetlin Machine demo was the most complex binary classification techniques I’ve ever worked with.

Tsetlin Machine systems have a small but very enthusiatic group of advocates. They argue that the Tsetlin Machine paradigm is computationally efficient, and hypothetically, advanced AI systems based on Tsetlin Machine designs could use orders of magnitude less energy than current systems based on neural network technolgies.



Tsetlin machine binary classification algorithm has a stochastic/probabilistic/random component. Probability has always fascinated me.

Trade stimulators were gambling machines in disguise during the time when gambling was illegal. Shop owners would have the machines to attact customers. There were dozens of manufacturers and hundreds of different machines. The advertised payouts were often expressed in terms of cigars or sticks of gum, but the real payouts were secretly in money. This is the origin of the term, “close but no cigar.”

Left: The “3-in-1” trade stimulator was manufactured by the Chas Fey Company in 1927. It has six dice. The payout was manual (by the bar/shop owner), which is very cumbersome.

Right: The “Mysterious Eye” trade stimulator was manufactured by the Western Equipment and Supply Company in 1935. It was the first dice machine to have automatic payout. The internal mechanism is likely based on the “Liberty Bell” slot machine (1898) by Chas Fey, which was the first automatic payout slot machine.


Demo program. Replace “lt” (less-than), “gt”, “lte”, “gte”, “and” with Boolean operator symbols. My blog editor often chokes on these symbols.

// tsetlin_machine_binary.js
//
// Tsetlin Machine binary classification on Iris Dataset
//  two-class subset.
// adapted from TsetlinMachine.pyx (Pyrex)
//  at github.com/cair/TsetlinMachine/tree/master.
// intended for node.js environment

let FS = require("fs")  // for loadTxt()

// ==========================================================

class TsetlinMachine
{
  constructor(nClauses, nFeatures,  nStates, s,
    threshold, seed)
  {
    this.nClauses = nClauses;
    this.nFeatures = nFeatures;
    this.nStates = nStates;
    this.s = s;
    this.threshold = threshold;
    this.seed = seed + 0.5;

    this.taState = makeCuboid(nClauses, nFeatures, 2);
    for (let i = 0; i "lt" nClauses; ++i) {
      for (let j = 0; j "lt" nFeatures; ++j) {
        let p1 = this.next();
        if (p1 "lt" 0.50)
          this.taState[i][j][0] = nStates;
        else
          this.taState[i][j][0] = nStates + 1;

        let p2 = this.next();
        if (p2 "lt" 0.50)
          this.taState[i][j][1] = nStates;
        else
          this.taState[i][j][1] = nStates + 1;
      } // j
    } // i

    this.clauseOutput = vecMake(nClauses, 0);
    this.feedbackToClauses = vecMake(nClauses, 0);
    this.clauseSign = vecMake(nClauses, 0);
    for (let j = 0; j "lt" nClauses; ++j) {
      if (j % 2 == 0)
        this.clauseSign[j] = 1; // class 0 items
      else
        this.clauseSign[j] = -1;
    }

  } // ctor

  // --------------------------------------------------------

  predict(x)
  {
    this.calculateClauseOutput(x);
    let outputSum = this.sumClauseVotes();
    if (outputSum "gte" 0)
      return 1;
    else
      return 0;
  }  

  // --------------------------------------------------------

  train(X, y, maxEpochs)
  {
    let nExamples = X.length;
    let xi = vecMake(this.nFeatures, 0);
    let indices = vecMake(nExamples, 0);
    for (let i = 0; i "lt" nExamples; ++i)
      indices[i] = i;

    for (let epoch = 0; epoch "lt" maxEpochs; ++epoch) {
      if (epoch % 20 == 0) {
        let acc = this.accuracy(X, y);
        let s1 = "Epoch " + epoch.toString().padStart(4, ' ');
        let s2 = " |  Accuracy = " + 
          acc.toFixed(4).toString();
        console.log(s1 + s2);
      }
      this.shuffle(indices);
      for (let i = 0; i "lt" nExamples; ++i) {
        let exampleID = indices[i];
        let targetY = y[exampleID];
        for (let j = 0; j "lt" this.nFeatures; ++j) {
          xi[j] = X[exampleID][j];
          this.update(xi, targetY);  // most of the work
        }
      }
    } // epoch

    return;
  } // train()

  // --------------------------------------------------------

  accuracy(X, y)
  {
    let nCorrect = 0; let nWrong = 0;
    for (let i = 0; i "lt" X.length; ++i) {
      let xi = X[i];
      let actualY = y[i];
      let predY = this.predict(xi);
      if (actualY == predY)
        ++nCorrect;
      else
        ++nWrong;
    }
    return (nCorrect * 1.0) / (nCorrect + nWrong);
  }

  // --------------------------------------------------------
  // helpers
  // --------------------------------------------------------

  update(x, y)
  {
    // helper for train(), does most of the work.
    // updates this.taState via feedbackToClauses[]
    this.calculateClauseOutput(x);
    let outputSum = this.sumClauseVotes();
    for (let j = 0; j "lt" this.nClauses; ++j)
      this.feedbackToClauses[j] = 0; // feedback is -1 or +1

    // step 1: compute feedback to clauses
    if (y == 1) {
      for (let j = 0; j "lt" this.nClauses; ++j) {
        if (this.next() "gt" 1.0 *
          (this.threshold - outputSum) /
          (2 * this.threshold))
          continue;
        if (this.clauseSign[j] == +1)
          this.feedbackToClauses[j] = 1; // Type I
        else
          this.feedbackToClauses[j] = -1; // Type II
      } // j
    }
    else if (y == 0) {
      for (let j = 0; j "lt" this.nClauses; ++j) {
        if (this.next() "gt" 1.0 *
          (this.threshold + outputSum) /
          (2 * this.threshold))
          continue;
        if (this.clauseSign[j] == +1)
          this.feedbackToClauses[j] = -1; // Type II
        else
          this.feedbackToClauses[j] = 1; // Type I
      } // j
    }

    // step 2: main processing loop over all clauses
    for (let j = 0; j "lt" this.nClauses; ++j) {
      if (this.feedbackToClauses[j] == 1)
      {
        if (this.clauseOutput[j] == 0)
        {
          for (let k = 0; k "lt" this.nFeatures; ++k) {
            if (this.next() "lte" 1.0 / this.s) {
              if (this.taState[j][k][0] "gt" 1)
                --this.taState[j][k][0];
            }
            if (this.next() "lte" 1.0 / this.s) {
              if (this.taState[j][k][1] "gt" 1)
                --this.taState[j][k][1];
            }
          } // k
        } // clauseOutput[j] == 0

        else if (this.clauseOutput[j] == 1) {
          for (let k = 0; k "lt" this.nFeatures; ++k) {
            if (x[k] == 1) {
              if (this.next() "lte" 1.0 *
                (this.s - 1) / this.s) 
              {
                if (this.taState[j][k][0] "lt"
                  this.nStates * 2)
                  ++this.taState[j][k][0];
              }
              if (this.next() "lte" 1.0 / this.s) {
                if (this.taState[j][k][1] "gt" 1)
                  --this.taState[j][k][1];
              }
            }
            else if (x[k] == 0) {
              if (this.next() "lte" 1.0 *
                (this.s - 1) / this.s)
              {
                if (this.taState[j][k][1] "lt"
                  this.nStates * 2)
                  ++this.taState[j][k][1];
              }
              if (this.next() "lte" 1.0 / this.s) {
                if (this.taState[j][k][0] "gt" 1)
                  --this.taState[j][k][0];
              }
            }
          } // k
        } // clauseOutput[j] == 1

      } // feedbackToClauses[j] "gt" 0

      else if (this.feedbackToClauses[j] == -1) {
        if (this.clauseOutput[j] == 1) {
          for (let k = 0; k "lt" this.nFeatures; ++k) {
            let actionInclude = -1;
            let actionExclude = -1;
            if (this.taState[j][k][0] "lte" this.nStates)
              actionInclude = 0;
            else
              actionInclude = 1;
            if (this.taState[j][k][1] "lte" this.nStates)
              actionExclude = 0;
            else
              actionExclude = 1;

            if (x[k] == 0) {
              if (actionInclude == 0 "and"
                this.taState[j][k][0] "lt"
                this.nStates * 2)
                ++this.taState[j][k][0];
            }
            else if (x[k] == 1) {
              if (actionExclude == 0 "and"
                this.taState[j][k][1] "lt"
                this.nStates * 2)
                ++this.taState[j][k][1];
            }
          } // k

        } // clauseOutput[j] == 1
      } // feedbackToClauses[j] "lt" 0
    } // main loop j

    return;

  } // update()

  // --------------------------------------------------------

  calculateClauseOutput(x)
  {
    // each cell clauseOutput is 0 or 1 
    // but is modified by clauseSign
    for (let j = 0; j "lt" this.nClauses; ++j) {
      this.clauseOutput[j] = 1;
      for (let k = 0; k "lt" this.nFeatures; ++k) {
        let actionInclude = -1;
        let actionExclude = -1;
        if (this.taState[j][k][0] "lte" this.nStates)
          actionInclude = 0;
        else
          actionInclude = 1;
        if (this.taState[j][k][1] "lte" this.nStates)
          actionExclude = 0;
        else
          actionExclude = 1;

        if ((actionInclude == 1 "and" x[k] == 0) ||
          (actionExclude == 1 "and" x[k] == 1)) {
          this.clauseOutput[j] = 0;
          break;
        }
      } // k
    } // j
  }

  // --------------------------------------------------------

   sumClauseVotes()
   {
     // result clipped between -thresh and +thresh
     let outputSum = 0;
     for (let j = 0; j "lt" this.nClauses; ++j) {
       outputSum += this.clauseOutput[j] * 
         this.clauseSign[j];
     }
     if (outputSum "gt" this.threshold)
       outputSum = this.threshold;
     else if (outputSum "lt" -this.threshold)
       outputSum = -this.threshold;
     return outputSum;
   } 

  // --------------------------------------------------------

  next()
  {
    // return sort-of-random type double in [0.0, 1.0)
    let x = Math.sin(this.seed) * 1000;
    let result = x - Math.floor(x);  // [0.0,1.0)
    this.seed = result;  // for next call
    return result;
  }

  // --------------------------------------------------------

  nextInt(lo, hi)
  {
    // random int in [lo,hi) -- lo inclusive to hi exclusive
    let x = this.next();
    return Math.trunc((hi - lo) * x + lo);
  }

  // --------------------------------------------------------

  shuffle(indices)
  {
    // Fisher-Yates
    for (let i = 0; i "lt" indices.length; ++i) {
      let ri = this.nextInt(i, indices.length);
      let tmp = indices[ri];
      indices[ri] = indices[i];
      indices[i] = tmp;
      //indices[i] = i; // for testing
    }
  }

} // class TsetlinMachine

// ==========================================================

// ----------------------------------------------------------
// vector and matrix functions
// ----------------------------------------------------------

function vecMake(n, val)
{
  let result = [];
  for (let i = 0; i "lt" n; ++i) {
    result[i] = val;
  }
  return result;
}

// ----------------------------------------------------------

function makeCuboid(n1, n2, n3)
{
  let result = [];
  for (let i = 0; i "lt" n1; ++i) {
    result[i] = [];
    for (let j = 0; j "lt" n2; ++j) {
      result[i][j] = [];
    }
  }

  for (let i = 0; i "lt" n1; ++i)  // set all cells to 0.0
    for (let j = 0; j "lt" n2; ++j)
      for (let k = 0; k "lt" n3; ++k)
        result[i][j][k] = 0.0;
  return result;
}

// ----------------------------------------------------------

function showCuboid(cuboid, wid)
{
  // assume integer values
  for (let i = 0; i "lt" cuboid.length; ++i) {
    for (let j = 0; j "lt" cuboid[i].length; ++j) {
      for (let k = 0; k "lt" cuboid[i][j].length; ++k) {
        process.stdout.write(cuboid[i][j][k].
          toString().padStart(wid, ' '));
      }
    process.stdout.write("\n");
    }
  process.stdout.write("\n");
  }
}

// ----------------------------------------------------------

function matMake(nRows, nCols, val)  // not used
{
  let result = [];
  for (let i = 0; i "lt" nRows; ++i) {
    result[i] = [];
    for (let j = 0; j "lt" nCols; ++j) {
      result[i][j] = val;
    }
  }
  return result;
}

// ----------------------------------------------------------

function vecShow(vec, dec, wid, nl)
{
  let small = 1.0 / Math.pow(10, dec);
  for (let i = 0; i "lt" vec.length; ++i) {
    let x = vec[i];
    if (Math.abs(x) "lt" small) x = 0.0  // avoid -0.00
    let xx = x.toFixed(dec);
    let s = xx.toString().padStart(wid, ' ');
    process.stdout.write(s);
    process.stdout.write(" ");
  }

  if (nl == true)
    process.stdout.write("\n");
}

// ----------------------------------------------------------

function matShow(A, dec, wid)
{
  let small = 1.0 / Math.pow(10, dec);
  let nr = A.length;
  let nc = A[0].length;
  for (let i = 0; i "lt" nr; ++i) {
    for (let j = 0; j "lt" nc; ++j) {
      let x = A[i][j];
      if (Math.abs(x) "lt" small) x = 0.0;
      let xx = x.toFixed(dec);
      let s = xx.toString().padStart(wid, ' ');
      process.stdout.write(s);
      process.stdout.write(" ");
    }
    process.stdout.write("\n");
  }
}

// ----------------------------------------------------------

function matToVec(M)
{
  let r = M.length;
  let c = M[0].length;
  let result = 	vecMake(r*c, 0.0);
  let k = 0;
  for (let i = 0; i "lt" r; ++i) {
    for (let j = 0; j "lt" c; ++j) {
      result[k++] = M[i][j];
    }
  }
  return result;
}

// ----------------------------------------------------------

function loadTxt(fn, delimit, usecols, comment)
{
  // efficient but mildly complicated
  let all = FS.readFileSync(fn, "utf8");  // giant string
  all = all.trim();  // strip final crlf in file
  let lines = all.split("\n");  // array of lines

  // count number non-comment lines
  let nRows = 0;
  for (let i = 0; i "lt" lines.length; ++i) {
    if (!lines[i].startsWith(comment))
      ++nRows;
  }
  let nCols = usecols.length;
  let result = matMake(nRows, nCols, 0.0); 
 
  let r = 0;  // into lines
  let i = 0;  // into result[][]
  while (r "lt" lines.length) {
    if (lines[r].startsWith(comment)) {
      ++r;  // next row
    }
    else {
      let tokens = lines[r].split(delimit);
      for (let j = 0; j "lt" nCols; ++j) {
        result[i][j] = parseFloat(tokens[usecols[j]]);
      }
      ++r;
      ++i;
    }
  }

  return result;
}

// ----------------------------------------------------------

function main()
{
  console.log("\nBegin Tsetlin Machine binary " +
    "classification using node.js JavaScript ");

  // 1. load data
  console.log("\nLoading train (80) and" +
    " test (20) data from file ");

  let trainFile = ".\\Data\\iris_two_classes_train_80.txt";
  let trainX = loadTxt(trainFile, ",",
    [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], "#");
  let trainY = loadTxt(trainFile, ",", [16], "#");
  trainY = matToVec(trainY);
  
  let testFile = ".\\Data\\iris_two_classes_test_20.txt";
  let testX = loadTxt(testFile, ",",
    [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], "#");
  let testY = loadTxt(testFile, ",", [16], "#");
  testY = matToVec(testY);

  console.log("\nFirst three train X: ");
  for (let i = 0; i "lt" 3; ++i)
    vecShow(trainX[i], 0, 2, true); // true: add newline

  console.log("\nFirst three train y: ");
  for (let i = 0; i "lt" 3; ++i)
    console.log(trainY[i].toString());

  // 2. create model
  let nClauses = 20; // number sort-of rules per class
  let nFeatures = 16;
  let nStates = 50;
  let s = 3.0;  // frequency updates using 1/s
  let threshold = 10;  // aka T clips voting
  let seed = 0.0;

  console.log("\nSetting nClauses = " + nClauses.toString());
  console.log("Setting nFeatures = " + nFeatures.toString());
  console.log("Setting nStates = " + nStates.toString());
  console.log("Setting s (random update " +
    "inverse frequency) = " + s.toFixed(1).toString());
  console.log("Setting threshold (voting clip) = " +
    threshold.toString());

  console.log("Creating Tsetlin Machine binary classifier ");
  let tm = new TsetlinMachine(nClauses, nFeatures,
    nStates, s, threshold, seed);
  console.log("Done ");

  // 3. train model
  let maxEpochs = 100;
  console.log("\nSetting training maxEpochs = " +
    maxEpochs.toString());
  console.log("Starting training ");
  tm.train(trainX, trainY, maxEpochs);
  console.log("Done ");

 // 4. evaluate model
 let trainAcc = tm.accuracy(trainX, trainY);
 console.log("\nAccuracy (train) = " +
   trainAcc.toFixed(4).toString());

 let testAcc = tm.accuracy(testX, testY);
 console.log("Accuracy (test) = " +
   testAcc.toFixed(4).toString());

  // 5. use model
  console.log("\nPredicting class" +
    " for trainX[0] ");
  let pred_y = tm.predict(trainX[0]);
  console.log("Predicted y = " + pred_y.toString());

  console.log("\nEnd Tsetlin demo");
}

main();
 

Training data:

# iris_two_classes_train_80.txt
#
# sepal length (cols 0,1,2,3)
# sepal width (cols 4,5,6,7)
# petal length (cols 8,9,10,11)
# petal width (cols 12,13,14,15)
# species (col 16) setosa = 0, versicolor = 1
# (no virginica)
#
# raw data: archive.ics.uci.edu/dataset/53/iris
# encoded data: github.com/cair/TsetlinMachine
#
# apparent feature encoding:
# [0.0, 1.5] = 0000
# [1.6, 3.1] = 0001
# [3.2, 4.7] = 0010
# [4.8, 6.3] = 0011
# [6.4, 7.9] = 0100
#
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1

Test data:

# iris_two_classes_test_20.txt
#
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
#
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1
0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1
This entry was posted in JavaScript, Machine Learning. Bookmark the permalink.

Leave a Reply