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

.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
2026 Visual Studio Live
2025 Summer MLADS Conference
2025 DevIntersection Conference
2025 Machine Learning Week
2025 Ai4 Conference
2025 G2E Conference
2025 iSC West Conference
You must be logged in to post a comment.