Friday, March 20, 2015

Candidate Elimiination

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


No comments:

Post a Comment