Evo for Meteor
As a general purpose, tree-based genetic algorithm framework, Evo provides methods of object mutation, crossover, and selection. This smart package implements these features in an accessible fashion while taking advantage of Meteor's reactive functionality & collections.
Checklist
######Evo is fully functional; however, I'd like to do some fine tuning before promoting it on Atmosphere. Here's a rough overview:
- Implement Evolutionary Primitives from Evo.js.
- Add methods to interface with Meteor.Collection
- [~] Arrange a pleasant api of some sort (w/ docs)
- Publish to Atmosphere!
- Create demonstrations & examples
- Refine, improve, and re-design...
API
######Although Evo isn't quite ready for primetime according to my standards, it is perfectly capable of producing evolutionary effects and modeling data.
####Quick-start
-
Navigate to your Meteor project's local directory.
-
Ensure that Meteorite is installed.
-
Add this package via mrt:
mrt add Evojs
-
Take a look at the example below, and you're ready to go!
####Important Objects
1. Leaf - an end node of a genetic tree 2. Node (inherits Leaf) - a node with two children, which can either be leaves or trees 3. Tree (inherits Node) - inherited Node becomes top node of tree - provides primary methods of evolution 4. Population - an end node of a genetic tree.
####Example Implementation
Given objects of the same type along with pre-determined ratings, Evo's 'Population' prototype attempts to model multi-variable inputs. Assume our data has two sources of input, 'x' and 'y', and that we're trying to model the classic XOR problem. Thus, we have the input-output table:
{x: 0, y: 0} --> 0 {x: 0, y: 1} --> 1 {x: 1, y: 1} --> 0 {x: 1, y: 0} --> 1
In order to model this dataset with Evo, we could do the following:
-
Format our data into arrays
// input array of objects inputs = [{x: 0, y: 0}, {x: 0, y: 1}, {x: 1, y: 1}, {x: 1, y: 0}]; // output array of numbers/ratings outputs = [0, 1, 0, 1];
-
Create a population of genetic trees
// 100 individuals in our population ourPop = new Population[inputs, outputs, 100];
-
Impose selection upon them according to our data
// impose 100 generations of evolution ourPop.evolve(100);
-
Assess & utilize resulting model
quantify model success
rmse = ourPop.bestRMSE; // best rmse = ourPop.medRMSE; // median rmse = ourPop.avgRMSE; // average
grab a function that represents the model
ourFunc = ourPop.bestTree.toFunc();
in order to utilize the product:
ourFunc( {x: 0, y: 0} ) --> 0 ourFunc( {x: 1, y: 0} ) --> 1 ourFunc( {x: 0, y: 1} ) --> 1 ourFunc( {x: 1, y: 1} ) --> 0 ...
-
Save & Load Tree, Population
generate string for database insertion:
// for population popStr = JSON.stringify(pop); // for best tree model treeStr = JSON.stringify(pop.bestTree);
loading from previously saved string:
loadedPop = fromJSON.Population(popStr); loadedTree = fromJSON.Tree(treeStr);