a test of detecting chart type using neural net

This commit is contained in:
Radek Stepan 2014-11-09 13:34:57 -07:00
parent b077510f05
commit 6cf9b37b3e
3 changed files with 62 additions and 1 deletions

View File

@ -78,7 +78,7 @@ namespace :test do
MOCHA = "./node_modules/.bin/mocha"
COVERALLS = "./node_modules/.bin/coveralls"
OPTS = "--compilers coffee:coffee-script/register --ui exports --bail"
OPTS = "--compilers coffee:coffee-script/register --ui exports --timeout 5000 --bail"
desc "Run code coverage, mocha with Blanket.js"
task :coverage do

View File

@ -21,6 +21,8 @@
},
"dependencies": {
"async": "~0.9.0",
"brain": "^0.7.0",
"chance": "^0.6.1",
"d3": "~3.4.13",
"d3-tip": "Caged/d3-tip",
"director": "~1.2.3",

59
test/neural.coffee Normal file
View File

@ -0,0 +1,59 @@
{ assert } = require 'chai'
Chance = require 'chance'
brain = require 'brain'
_ = require 'lodash'
d3 = require 'd3'
chance = new Chance()
module.exports =
'neural net - detect sine chart type': (done) ->
fns =
# A "rough" sine wave.
sine: (x) -> Math.sin chance.floating 'min': Math.max(x - 1, 0), 'max': x + 1
# A linear function.
linear: (x) -> ( chance.floating 'min': Math.max(x - 1, 0), 'max': x + 1 ) + 2
# Generate sample data points.
samples = 10
data = _.map [ 0 ... 10 ], (i) ->
fn = fns[ [ 'linear', 'sine' ][ sine = +(i < (samples / 2)) ] ]
points = ( fn(j) for j in [ 0 ... 100 ] )
{ points, sine }
# Scale the data to just 6 points.
for chart in data then do (chart) ->
step = Math.round (len = chart.points.length) / 5
chart.points = ( chart.points[ Math.min(i, len - 1) ] for i in _.range(0, len + step, step) )
# Scale the values for each chart.
for chart in data then do (chart) ->
scale = d3.scale.linear().range([ 0, 1 ]).domain([ d3.min(chart.points), d3.max(chart.points) ])
chart.points = _.map chart.points, scale
# Split the dataset.
training = data[ 1...9 ]
testing = [ data[0] ].concat data[9]
net = new brain.NeuralNetwork()
keys = [ 0, 0.2, 0.4, 0.6, 0.8, 1 ]
input = for chart in training then do (chart) ->
'input': _.zipObject keys, chart.points
'output':
'sine': chart.sine
net.train input,
'errorThresh': 0.005 # error threshold to reach
'iterations': 5e4 # maximum training iterations
'log': no # console.log() progress periodically
'logPeriod': 1e3 # number of iterations between logging
'learningRate': 0.2 # learning rate
# Now test it.
for sample in testing
out = net.run _.zipObject keys, sample.points
assert sample.sine is Math.round(out.sine), "Network says #{out.sine} but sample says #{sample.sine}"
do done