UNPKG

nodeml

Version:

node.js machine learning package

131 lines (100 loc) 3.69 kB
'use strict'; module.exports = function () { let app = this; // logger let assert = (condition, message)=> { if (!condition) { message = message || "Assertion failed"; if (typeof Error !== "undefined") { throw new Error(message); } throw message; } }; let _trained = null; // set previous trained model app.setModel = (trained)=> { assert(trained.constructor == Object, `dataset undefined`); _trained = trained; }; // get trained model app.getModel = ()=> _trained; // training function app.train = (dataset, labels)=> { assert(dataset, `dataset undefined`); assert(labels, `labels undefined`); // check dataset structure if (Array.isArray(dataset) === false) dataset = [dataset]; else if (typeof dataset[0] != 'object') dataset = [dataset]; if (Array.isArray(labels) === false) labels = [labels]; assert(dataset.length === labels.length, `mismatched array length`); if (!_trained) _trained = {}; if (!_trained.dic) _trained.dic = {}; if (!_trained.label) _trained.label = {}; let _dic = _trained.dic; // dictionary map let _label = _trained.label; // labels data // dataset iteration for (let i = 0; i < dataset.length; i++) { let data = dataset[i]; // single data row let label = labels[i]; // data's label let sum = 0; // features in data row for (let key in data) { // if not contained in dictionary, create map data as zero if (!_dic[key]) _dic[key] = {}; if (!_dic[key][label]) _dic[key][label] = 0; // add features value in dictionary _dic[key][label] += data[key] * 1; // add features value sum += data[key] * 1; } // label ratio if (!_label[label]) _label[label] = 0; _label[label] += sum; } return _trained; }; // predict some data, core calculation function in here. app.test = (dataset, options)=> { if (!options) options = {}; assert(dataset, `dataset undefined`); if (Array.isArray(dataset) === false) dataset = [dataset]; else if (typeof dataset[0] != 'object') dataset = [dataset]; // load trained model let _dic = _trained.dic; let _label = _trained.label; let result = []; // test dataset iteration for (let i = 0; i < dataset.length; i++) { let prob = {}; let data = dataset[i]; // calculate prob for each label for (let label in _label) { if (typeof prob[label] === 'undefined') prob[label] = 0; for (let key in data) { let fc = _dic[key] ? _dic[key][label] ? _dic[key][label] * data[key] : 0 : 0; fc += 1; prob[label] += Math.log(fc / _label[label]); } } let max = null; let answer = null; // select max scored label for (let label in prob) { if (!max) { max = prob[label]; answer = label; } if (prob[label] > max) { max = prob[label]; answer = label; } } if (options.score) result.push({answer: answer, score: prob}); else result.push(answer); } if (dataset.length == 1) return result[0]; else return result; }; return app; };