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