Recently I am researching the artificial intelligence, I will implement more algorithms. And there is the candidate elimination algorithm for machine learning by JavaScript. Its main reference is this link (Version Space Problem 1).
function GeneralHypotheses(length) {
var data = [];
var i = 0;
for (; i < length; i += 1) {
data.push("?");
}
this.sizeofAttr = length;
this.hypotheses = [];
this.hypotheses.push(new Hypothesis(data));
}
GeneralHypotheses.prototype.specialize = function (hypo, s) {
var newHypotheses = [];
var i = 0, j = 0, m = 0;
for (; i < this.hypotheses.length; i += 1) {
var h = this.hypotheses[i];
for (j = 0; j < h.length(); j += 1) {
var newH = h.clone();
if (h.data[j] === '?') {
if (s.data[j] !== hypo.data[j]) {
newH.data[j] = s.data[j];
var existing = false;
// avoid inserting duplicated hypothesis
for (; m < newHypotheses.length; m += 1) {
if (newH.equalTo(newHypotheses[m])) {
existing = true;
break;
}
}
if (!existing && !newH.include(hypo)) {
newHypotheses.push(newH);
}
}
}
}
}
this.hypotheses = newHypotheses;
};
GeneralHypotheses.prototype.prune = function (hypo) {
var newHypotheses = [];
var i = 0, j = 0; k = null;
for (; i < this.hypotheses.length; i += 1) {
var h = this.hypotheses[i];
if (h.include(hypo)) {
var existing = false;
for (; j < newHypotheses.length; j += 1) {
if (h.equalTo(newHypotheses[j])) {
existing = true;
break;
}
}
if (!existing) {
newHypotheses.push(h);
}
}
}
this.hypotheses = newHypotheses;
};
GeneralHypotheses.prototype.exist = function (hypo) {
var i = 0;
for (; i < this.hypotheses.length; i += 1) {
if (this.hypotheses[i].equalTo(hypo))
return true;
}
return false;
};
GeneralHypotheses.prototype.clone = function () {
var ret = new GeneralHypotheses(this.sizeofAttr);
var i = 0;
for (; i < this.hypotheses.length; i += 1) {
ret.hypotheses[i] = this.hypotheses[i].clone();
}
return ret;
};
GeneralHypotheses.prototype.toString = function () {
var ret = [], i = 0;
for (; i < this.hypotheses.length; i++) {
ret.push(this.hypotheses[i].data);
}
return JSON.stringify(ret);
};
/**
*
*/
function Hypothesis(data) {
this.data = data;
}
Hypothesis.prototype.length = function () {
return this.data.length;
};
Hypothesis.prototype.value = function (index) {
return this.data[index];
};
Hypothesis.prototype.clone = function () {
var data = [];
var i = 0;
for (; i < this.data.length; i += 1) {
data[i] = this.data[i];
}
return new Hypothesis(data);
};
Hypothesis.prototype.generalize = function (hypo) {
var i = 0;
for (; i < this.data.length; i += 1) {
if (this.data[i] !== hypo.data[i])
this.data[i] = "?";
}
};
Hypothesis.prototype.specialize = function (hypo) {
for (; i < this.data.length; i += 1) {
var tmpH = this.clone();
var h = tmpH.value(i);
var e = hypo.value(i);
if (h !== e) {
if (h === "?") {
var dv = this.diff();
}
}
}
};
Hypothesis.prototype.include = function (hypo) {
var i = 0;
for (; i < this.data.length; i += 1) {
if (this.value(i) !== hypo.value(i) && this.value(i) !== "?")
return false;
}
return true;
};
Hypothesis.prototype.equalTo = function (hypo) {
var i = 0;
for (; i < this.data.length; i += 1) {
if (this.data[i] !== hypo.data[i])
return false;
}
return true;
};
Hypothesis.prototype.diff = function (hypo) {
var ret = [], i = 0;
for (; i < this.data.length; i += 1) {
if (this.data[i] !== hypo.data[i])
ret.push(hypo.data[i]);
}
return new Hypothesis(ret);
};
Hypothesis.prototype.toString = function () {
return JSON.stringify(this.data);
};
var trainingSet0 = [
{hypothesis: new Hypothesis(['Japan', 'Honda', 'Blue', '1980', 'Economy']), result: 'Positive'},
{hypothesis: new Hypothesis(['Japan', 'Toyota', 'Green', '1970', 'Sports']), result: 'Negative'},
{hypothesis: new Hypothesis(['Japan', 'Toyota', 'Blue', '1990', 'Economy']), result: 'Positive'},
{hypothesis: new Hypothesis(['USA', 'Chrysler', 'Red', '1980', 'Economy']), result: 'Negative'},
{hypothesis: new Hypothesis(['Japan', 'Honda', 'White', '1980', 'Economy']), result: 'Positive'}
];
function doCandidateElimination(trainingSet) {
var i = 0;
var s = null;
var g = new GeneralHypotheses(trainingSet[0].hypothesis.length());
for (i = 0; i < trainingSet.length; i += 1) {
var d = trainingSet[i];
if (s === null) {
s = d.hypothesis;
continue;
}
console.log("Step " + (i + 1) + " Input[" + d.result + "]:");
console.log(g.toString());
console.log(s.toString());
if (d.result === 'Negative') {
g.specialize(d.hypothesis, s);
} else if (d.result === 'Positive') {
g.prune(d.hypothesis);
s.generalize(d.hypothesis);
}
console.log("Step " + (i + 1) + " Output:");
console.log(g.toString());
console.log(s.toString());
}
return {g: g, s: s};
}
console.log(doCandidateElimination(trainingSet0));