parent
39ff5c7e1b
commit
501e043dd8
@ -0,0 +1,254 @@
|
||||
/**
|
||||
* Simple Javascript eXtension - 1.0
|
||||
* (c) 2011 - 2015 Steve L. Nyemba, steve@the-phi.com
|
||||
* License GPL version 3.0
|
||||
*
|
||||
* dependencies:
|
||||
* utils.js implementation of design patterns and utilities
|
||||
*
|
||||
* This file contains an enhancement of utilities integrated into the jx.math.* built-in package of javascript
|
||||
* Because we implement math and numerical functions it is to be understood that most of the functions will have common preconditions
|
||||
* i.e lxi.constructor == Array && isNumber(lxi) unless specified otherwise
|
||||
|
||||
* jx.math.max
|
||||
* jx.math.min
|
||||
* jx.math.sum
|
||||
* jx.math.prod
|
||||
* jx.math.freq
|
||||
* jx.math.avg
|
||||
* jx.math.mean computes the mean/average of a list of observations (arthmetic mean included too)
|
||||
* jx.math.sd computes the standard deviation of a list of observations
|
||||
* jx.math.var computes the variance of a list of observations
|
||||
* jx.math.diff computes the absolute difference of values in an array
|
||||
* jx.math.fibonacci comptutes the fibonacci value of a given number
|
||||
* jx.math.factorial computes the factorial of a given number
|
||||
*/
|
||||
if(!jx){
|
||||
var jx = {} ;
|
||||
|
||||
}
|
||||
jx.math = {}
|
||||
jx.math.sqrt = Math.sqrt;
|
||||
jx.math.PHI = (1+jx.math.sqrt(5))/2 ;//1.61803399 ;
|
||||
|
||||
/**
|
||||
* @param lxi list of observatins xi
|
||||
*/
|
||||
|
||||
jx.math.max = function(lxi){
|
||||
sortNumber= function(a,b) {
|
||||
return a - b;
|
||||
}
|
||||
index = lxi.length -1 ;
|
||||
max = jx.utils.cast(lxi,Number).sort(sortNumber)[index] ; // perhaps need to cast
|
||||
return max ;
|
||||
}
|
||||
/**
|
||||
* finds the minimum of a list of observation lxi (vector of values)
|
||||
* @param lxi list/vector of values/observations
|
||||
*/
|
||||
jx.math.min = function(lxi){
|
||||
sortNumber = function(a,b){
|
||||
return a- b;
|
||||
}
|
||||
min = jx.utils.cast(lxi,Number).sort(sortNumber)[0] ;
|
||||
return min ;
|
||||
}
|
||||
/**
|
||||
* @pre : values.constructor == Array
|
||||
* @param lxi list of observed values to be summed
|
||||
*/
|
||||
jx.math.sum = function(lxi){
|
||||
return eval(lxi.join('+'));
|
||||
} ;
|
||||
/**
|
||||
* This function will compute the frequency of a vector i.e providing relative values
|
||||
*/
|
||||
jx.math.freq = function(lxi){
|
||||
var N = jx.math.sum(lxi) ;
|
||||
return jx.utils.patterns.visitor(lxi,function(xi){
|
||||
return xi/N ;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* This function will perform the product of a vector
|
||||
* @pre lxi.constructor == Array && isNumber(lxi)
|
||||
*/
|
||||
jx.math.prod = function(lxi){
|
||||
return eval(lxi.join('*')) ;
|
||||
}
|
||||
/**
|
||||
* @pre : lni != null && lxi.length == lni.length
|
||||
* @param lxi list of observed values
|
||||
* @param lni list of the number of times observations of index i have been made
|
||||
*/
|
||||
jx.math.avg = function(lxi,lni){
|
||||
N = lxi.length ;
|
||||
if(lni == null){
|
||||
return jx.math.sum(lxi)/N ;
|
||||
}else{
|
||||
values = []
|
||||
for(var i=0; i < lxi.length; i++){
|
||||
values[i] = Number(lxi[i])*Number(lni[i]) ;
|
||||
}
|
||||
return Number(jx.math.sum(values)/N) ;
|
||||
}
|
||||
};
|
||||
|
||||
jx.math.mean = jx.math.avg ;
|
||||
jx.math.pow = Math.pow
|
||||
jx.math.sd = function(lxi,lni){
|
||||
N = lxi.length ;
|
||||
mean = jx.math.mean(lxi,lni) ;
|
||||
|
||||
sqr = [] ;
|
||||
for(var i=0; i < lxi.length ;i++){
|
||||
console.log(lxi[i])
|
||||
sqr[i] = jx.math.pow((Number(lxi[i])-mean),2 ) ;
|
||||
}
|
||||
|
||||
total = jx.math.sum(sqr);
|
||||
|
||||
return jx.math.sqrt(total/(N-1)) ;
|
||||
} ;
|
||||
|
||||
/**
|
||||
* Computes the factorial of a given value
|
||||
*/
|
||||
jx.math.factorial = function(value){
|
||||
r =value;
|
||||
for(var i =value-1; i > 0; i--){
|
||||
r *= i ;
|
||||
}
|
||||
|
||||
return r;
|
||||
} ;
|
||||
|
||||
/**
|
||||
* Computes the fibonacci value of a given number using the golden ratio
|
||||
*/
|
||||
jx.math.fibonacci = function(value){
|
||||
r = (jx.math.pow(jx.math.PHI,value)/jx.math.sqrt(5)) + 0.5 ;
|
||||
return jx.math.floor(r) ;
|
||||
} ;
|
||||
|
||||
/**
|
||||
* computes the absolute difference of values in a list of observations
|
||||
*/
|
||||
jx.math.diff = function(lxi){
|
||||
var r = [] ;
|
||||
var x,y;
|
||||
for(var i=0; i < lxi.length-1; i++){
|
||||
x = lxi[i] ;
|
||||
y = lxi[i+1] ;
|
||||
r.push(y-x)
|
||||
}
|
||||
return r ;
|
||||
};
|
||||
|
||||
/**
|
||||
* This section implements a few handlers based on sets
|
||||
*/
|
||||
jx.math.sets = {} ;
|
||||
/**
|
||||
* This function will perform a unique operation of values/objects
|
||||
* @param list list/vector of values or objects
|
||||
* @param equals operator to be used, only provide this for complex objects
|
||||
*/
|
||||
jx.math.sets.unique = jx.utils.unique ;
|
||||
/**
|
||||
* This function will perform the union of 2 sets (objects, or values)
|
||||
* @param list1 list/vector of values or objects
|
||||
* @param list2 list/vector of values or objects
|
||||
* @param equals operator to be used to evaluate equality (use this for complex objects)
|
||||
*/
|
||||
jx.math.sets.union = function(list1,list2,equals){
|
||||
runion = [] ;
|
||||
runion = list1.concat(list2) ;
|
||||
runion = jx.math.sets.unique(runion,equals)
|
||||
return runion;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will normalize values within a vector
|
||||
* By definition normalization is (x - u) / sd (assuming population parameters are known)
|
||||
*/
|
||||
jx.math.normalize = function(lvalues){
|
||||
mean = jx.math.mean(lvalues) ;
|
||||
sd = jx.math.sd(lvalues) ;
|
||||
return jx.utils.patterns.visitor(lvalues,function(x){
|
||||
return ((x - mean) / sd)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will scale a feature vector over it's range
|
||||
*/
|
||||
jx.math.scale = function(lvalues,percent){
|
||||
max = jx.math.max(lvalues) ;
|
||||
min = jx.math.min(lvalues) ;
|
||||
return jx.utils.patterns.visitor(lvalues,function(x){
|
||||
var value = (x - min ) / max ;
|
||||
if(percent == true){
|
||||
return (100*value).toFixed(2)
|
||||
}else{
|
||||
return value ;
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* This is a lightweight map reduce infrastructure
|
||||
*/
|
||||
jx.mr = {} ;
|
||||
/**
|
||||
* This function will perform a map on a given id in rec, then will call emit with the
|
||||
*/
|
||||
jx.mr.map = null
|
||||
/**
|
||||
* @param keys
|
||||
* @param values array of values that were mapped
|
||||
*/
|
||||
jx.mr.reduce = null;
|
||||
jx.mr.mapreduce = function(data,fn_map,fn_reduce){
|
||||
if (fn_map == null){
|
||||
throw new "Map function is not defined"
|
||||
}
|
||||
map = {} ;
|
||||
emit = function(id,values){
|
||||
if(map[id] == null){
|
||||
map[id] = []
|
||||
}
|
||||
map[id].push(values);
|
||||
}
|
||||
if(data.constructor != Array){
|
||||
for (id in data){
|
||||
//rec = data[id] ;
|
||||
rec = {}
|
||||
rec['__id'] = id;
|
||||
rec['data'] = data[id] ;
|
||||
fn_map(rec,emit)
|
||||
|
||||
}
|
||||
}else{
|
||||
for (var i=0; i < data.length; i++){
|
||||
rec = data[i];
|
||||
fn_map(rec,emit);
|
||||
//if(i == 2)break;
|
||||
}
|
||||
}
|
||||
if(fn_reduce != null){
|
||||
keys = jx.utils.keys(map) ;
|
||||
m = {}
|
||||
for(var i=0; i < keys.length; i++){
|
||||
id = keys[i] ;
|
||||
values = map[id] ;
|
||||
value = fn_reduce(id,values) ;
|
||||
id = keys[i] ;
|
||||
m[id] = value;
|
||||
|
||||
}
|
||||
map = m
|
||||
|
||||
}
|
||||
return map ;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Simple Javascript eXtension - 1.0, Machine Leanring Module
|
||||
* (c) 2011 - 2015 Steve L. Nyemba, steve@the-phi.com
|
||||
* License GPL version 3.0
|
||||
*
|
||||
* dependencies:
|
||||
* jx.utils collection of utilities and design patterns used
|
||||
* jx.math various math & statistical functions
|
||||
* This file implements a few reusable machine learning models/techniques
|
||||
*
|
||||
* jx.ml.mapreduce Performs a standard/basic mapreduce (single thread for now)
|
||||
* jx.ml.regression Will perform linear & logistic regressions
|
||||
*/
|
||||
*
|
||||
if(!jx){
|
||||
var jx = {} ;
|
||||
}
|
||||
jx.ml = {}
|
||||
/**
|
||||
* The function performs map/reduce and at the very least map i.e the reduce function is optional
|
||||
*/
|
||||
jx.ml.mapreduce = function(data,fn_map,fn_reduce){
|
||||
//
|
||||
// insure that the mapping function has been provided
|
||||
//
|
||||
var __map = {}
|
||||
var emit = function(id,mvalue){
|
||||
if(__map[id] == null){
|
||||
__map[id] = []
|
||||
}
|
||||
__map[id].push(mvalue) ;
|
||||
}//-- end of the emitter
|
||||
if(data.constructor != Array){
|
||||
jx.utils.patterns.visitor(data,function(id){
|
||||
fn_map(data[id],emit) ;
|
||||
});
|
||||
}else{
|
||||
jx.utils.patterns.visitor(data,function(i){
|
||||
fn_map(data[i],emit) ;
|
||||
});
|
||||
}
|
||||
|
||||
if(fn_reduce != null){
|
||||
//
|
||||
// We will be performing a reduce operation at this point
|
||||
|
||||
var ids = jx.utils.keys(__map) ;
|
||||
jx.utils.patterns.visitor(ids,function(id){
|
||||
return __map[id] = fn_reduce(id,__map[id]) ;
|
||||
});
|
||||
}
|
||||
|
||||
return __map ;
|
||||
|
||||
}//--
|
||||
|
||||
/**
|
||||
* The modules developed below will perform linear regression and logistic regression
|
||||
*/
|
||||
jx.ml.regression = {}
|
||||
|
Loading…
Reference in new issue