StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
3.4 KiB
155 lines
3.4 KiB
4 years ago
|
|
||
|
var Emitter = require('events').EventEmitter
|
||
|
var util = require('util')
|
||
|
|
||
|
module.exports = Audit
|
||
|
|
||
|
function Audit(options) {
|
||
|
options = options || {}
|
||
|
this.iters = options.iterations || 1e3
|
||
|
this.pause = options.pause || 100
|
||
|
this.audits = []
|
||
|
}
|
||
|
|
||
|
util.inherits(Audit, Emitter)
|
||
|
|
||
|
Audit.prototype.makeAudit = function(name, audit, async) {
|
||
|
|
||
|
if (!audit) {
|
||
|
audit = name
|
||
|
name = 'Nameless-'+this.audits.length
|
||
|
}
|
||
|
|
||
|
this.audits.push({
|
||
|
name:name,
|
||
|
fn:audit,
|
||
|
async:async
|
||
|
})
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
Audit.prototype.async = function(name, audit) {
|
||
|
return this.makeAudit(name, audit, true)
|
||
|
}
|
||
|
|
||
|
Audit.prototype.sync = function(name, audit) {
|
||
|
return this.makeAudit(name, audit, false)
|
||
|
}
|
||
|
|
||
|
Audit.prototype.runAudit = function(audit, fn) {
|
||
|
var iters = this.iters
|
||
|
var times = []
|
||
|
;(function next(i) {
|
||
|
if (i > iters) {
|
||
|
return fn(audit.name, times)
|
||
|
}
|
||
|
var then = Date.now()
|
||
|
if (audit.async) {
|
||
|
audit.fn(function() {
|
||
|
times.push(Date.now() - then)
|
||
|
next(++i)
|
||
|
})
|
||
|
}else {
|
||
|
var res = audit.fn()
|
||
|
times.push(Date.now() - then)
|
||
|
next(++i)
|
||
|
}
|
||
|
})(0)
|
||
|
}
|
||
|
|
||
|
Audit.prototype.run = function(fn) {
|
||
|
|
||
|
var self = this
|
||
|
, audits = this.audits
|
||
|
, iters = this.iters
|
||
|
, pause = this.pause
|
||
|
, stats = {}
|
||
|
, count = 0
|
||
|
|
||
|
;(function next(i) {
|
||
|
var audit = audits[i]
|
||
|
self.emit('auditing', audit.name)
|
||
|
self.runAudit(audit, function() {
|
||
|
auditComplete.apply(this, arguments)
|
||
|
if (++i >= audits.length) {
|
||
|
return complete()
|
||
|
}
|
||
|
setTimeout(function() {
|
||
|
next(i)
|
||
|
}, pause)
|
||
|
})
|
||
|
})(0)
|
||
|
|
||
|
function complete() {
|
||
|
self.emit('complete', stats)
|
||
|
}
|
||
|
|
||
|
function auditComplete(name, times) {
|
||
|
|
||
|
var _stats = getStats(times)
|
||
|
|
||
|
var auditStats = {
|
||
|
name:name,
|
||
|
elapsed:_stats.elapsed+'ms',
|
||
|
iterations:iters,
|
||
|
opsPerSecond:(iters / _stats.elapsed) * 1000,
|
||
|
mode:_stats.mode,
|
||
|
median:_stats.median,
|
||
|
mean:_stats.mean,
|
||
|
max:_stats.max,
|
||
|
min:_stats.min
|
||
|
}
|
||
|
|
||
|
self.emit('auditcomplete', auditStats)
|
||
|
stats[name] = auditStats
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
function getStats(times) {
|
||
|
|
||
|
var elapsed = times.reduce(function(a, b) {
|
||
|
return a + b
|
||
|
})
|
||
|
|
||
|
var mode = [0, '']
|
||
|
, median = times[~~(times.length/2)]
|
||
|
, mean = elapsed / times.length
|
||
|
, max = [times[0], 0+'ind']
|
||
|
, min = [times[0], 0+'ind']
|
||
|
, maxOcc = 0
|
||
|
, freq = {}
|
||
|
|
||
|
for (var i=0, len=times.length;i<len;i++) {
|
||
|
;(function() {
|
||
|
var item = times[i]
|
||
|
var it = (freq[item] || 0) + 1
|
||
|
freq[item] = it
|
||
|
if (item > max[0]) {
|
||
|
max = [item, i+'ind']
|
||
|
}else if (item < min[0]) {
|
||
|
min = [item, i+'ind']
|
||
|
}
|
||
|
})()
|
||
|
}
|
||
|
|
||
|
for (k in freq) {
|
||
|
if (freq[k] > maxOcc) {
|
||
|
mode = [k+'ms', freq[k]+'occ']
|
||
|
maxOcc = k
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
elapsed:elapsed,
|
||
|
frequency:freq,
|
||
|
mode:mode,
|
||
|
median:median+'ms',
|
||
|
mean:mean+'ms',
|
||
|
max:[max[0]+'ms', max[1]],
|
||
|
min:[min[0]+'ms', min[1]]
|
||
|
}
|
||
|
}
|