Skip to content

Commit

Permalink
Adding anomaly detector and anomaly scores REST API methods
Browse files Browse the repository at this point in the history
  • Loading branch information
mmerce committed Sep 13, 2014
1 parent d74145d commit 64b29b9
Show file tree
Hide file tree
Showing 12 changed files with 649 additions and 8 deletions.
4 changes: 4 additions & 0 deletions History.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
=== 1.1.0 / 2014-09-12

* Adding the anomaly detector and anomaly score REST API methods.

=== 1.0.0 / 2014-08-29

* Adding new missing operators to the local Model predicates. Adapting
Expand Down
201 changes: 201 additions & 0 deletions data/tiny_kdd.csv

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ this will give you access to the following library structure:
- bigml.Cluster Cluster API methods
- bigml.Centroid Centroid API methods
- bigml.BatchCentroid BatchCentroid API methods
- bigml.Anomaly Anomaly detector API methods
- bigml.AnomalyScore Anomaly score API methods
- bigml.LocalModel Model for local predictions
- bigml.LocalEnsemble Ensemble for local predictions

Expand Down Expand Up @@ -301,6 +303,17 @@ classify a dataset of input data. They are the analogous to the batch
predictions generated from models, but for clusters. These resources
are handled through `bigml.BatchCentroid`.

- **anomaly detectors** They are unsupervised learning models
that detect instances in the training dataset that are anomalous.
The information it returns encloses a `top_anomalies` block
that contains a list of the most anomalous
points. For each instance, a `score` from 0 to 1 is computed. The closer to 1,
the more anomalous. These resources are handled
through `bigml.Anomaly`.

- **anomaly scores** Are scores computed for any user-given input data using
an anomaly detector. These resources are handled through `bigml.AnomalyScore`

Creating resources
------------------

Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ module.exports = {
Centroid: require('./lib/Centroid'),
// Batch Centroid REST api interface
BatchCentroid: require('./lib/BatchCentroid'),
// Anomaly REST api interface
Anomaly: require('./lib/Anomaly'),
// Anomaly score REST api interface
AnomalyScore: require('./lib/AnomalyScore'),
// Local Model object for local predictions
LocalModel: require('./lib/LocalModel'),
// Local Ensemble object for local predictions
Expand Down
138 changes: 138 additions & 0 deletions lib/Anomaly.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* Copyright 2014 BigML
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

"use strict";

var BigML = require('./BigML');
var Resource = require('./Resource');
var constants = require('./constants');
var logger = require('./logger');
var utils = require('./utils');
var async = require('async');

function Anomaly(connection) {
Resource.call(this, connection);
}

Anomaly.prototype = new Resource();

Anomaly.prototype.parent = Resource.prototype;

Anomaly.prototype.create = function (datasets, args, retry, cb) {
/**
* Creates an anomaly detector and builds customized error and resource info
*
* Uses HTTP POST to send dataset content.
*
* Returns a BigML resource wrapped in an object that includes
* code: HTTP status code
* resource: The resource/id
* location: Remote location of the resource
* object: The resource itself
* error: An error code and message
*
* @param {string|object|array} datasets Dataset id or array of dataset ids
* (or objects)
* @param {object} args Arguments that should be used in the call. For
* example {name: "my_name"}
* @param {boolean} retry Turns on/off the retries if a resumable
* condition happens
* @param {function} cb Callback function
*/


var self = this, options, resource, resources, datasetsArray = false,
message = 'Failed to create the anomaly. First parameter must be' +
' a dataset or datasets array.',
resourceId,
reqOptions = {
method: 'POST',
resourceType: 'anomaly',
endpoint: '/'
};

if (arguments.length > 0) {
datasetsArray = utils.isArray(datasets);
resource = (datasetsArray) ? datasets[0] : datasets;
resourceId = utils.getResource(resource);
options = utils.optionalCUParams(arguments, message);

if (datasetsArray && resourceId.type === 'dataset') {
resources = datasets;
options.args['datasets'] = datasets;
} else if (resourceId.type === 'dataset') {
resources = [datasets];
options.args['dataset'] = resourceId.resource;
} else {
throw new Error(message);
}
options = utils.setRetries(options);
options.type = reqOptions.resourceType;
options.operation = 'create';
this.resources = resources;
this.options = options
} else {
if (!this.options || !this.resources) {
logger.error("Create has been called with no parameters.");
return;
}
options = this.options;
datasetsArray = this.resources.length > 1;
resource = this.resources[0];
resources = this.resources;
resourceId = utils.getResource(resource);
}
reqOptions.body = options.args;

function sendRequest(error) {
if (error) {
logger.error("Origin resources could not be retrieved: " + error);
} else {
self.connection.request(reqOptions,
function processResponse(error, data, response) {
var code = constants.HTTP_INTERNAL_SERVER_ERROR,
result = utils.makeEmptyResult('resource',
code,
'The resource couldn\'t be created');
return utils.requestResponse('resource', self,
constants.HTTP_CREATED,
constants.HTTP_CREATE_ERRORS,
error, data, response, result,
options.cb);
});
}
}
// The origin resources must be retrieved in a finished state before
// create starts. This is only done when create is called by the user, not
// internally to retry creation.
if (arguments.length > 0) {
async.each(resources, function(resource, done) {
var id = utils.getResource(resource);
new Resource(self.connection).get(id.resource, true, done);
},
sendRequest);
} else {
sendRequest(null);
}

};

Anomaly.prototype.list = function (query, cb) {
this.parent.list.call(this, 'anomaly', query, cb);
};


module.exports = Anomaly;
91 changes: 91 additions & 0 deletions lib/AnomalyScore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Copyright 2014 BigML
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

"use strict";

var BigML = require('./BigML');
var Resource = require('./Resource');
var constants = require('./constants');
var logger = require('./logger');
var utils = require('./utils');

function optionalCUParams(argsArray, message) {
/**
* Checks the arguments given to the create method and
* sets their default values if absent.
*
* @param {array} arguments Arguments array
* @param {string} message Resource-customized error message
*/

var options, newArgs;
newArgs = [argsArray[0]].concat([].slice.call(argsArray, 2));
options = utils.optionalCUParams(newArgs, message);
options.inputData = argsArray[1];
return options;
}

function AnomalyScore(connection) {
Resource.call(this, connection);
}

AnomalyScore.prototype = new Resource();

AnomalyScore.prototype.parent = Resource.prototype;

AnomalyScore.prototype.create = function (anomaly, inputData, args,
retry, cb) {
/**
* Creates an anomaly score and builds customized error and resource info
*
* Uses HTTP POST to send dataset content.
*
* Returns a BigML resource wrapped in an object that includes
* code: HTTP status code
* resource: The resource/id
* location: Remote location of the resource
* object: The resource itself
* error: An error code and message
*
* @param {string} anomaly Anomaly id
* @param {object} inputData Input Data to predict from
* @param {object} args Arguments that should be used in the call. For
* example {name: "my_name"}
* @param {boolean} retry Turns on/off the retries if a resumable
* condition happens
* @param {function} cb Callback function
*/

var options,
message = 'Failed to create the anomaly score. First parameter must be' +
' an anomaly detector id.',
resourceId = utils.getResource(anomaly),
self = this;

options = optionalCUParams(arguments, message);

options.args['input_data'] = options.inputData;
self.parent.create.call(self, 'anomalyscore', ['anomaly'], message,
resourceId.resource,
options.args, options.retry, options.cb);
};

AnomalyScore.prototype.list = function (query, cb) {
this.parent.list.call(this, 'anomalyscore', query, cb);
};


module.exports = AnomalyScore;
6 changes: 3 additions & 3 deletions lib/BigML.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ var constants = require('./constants');
var logger = require('./logger');
var waittime = require('./waittime');


/**
* BigML: connection to the BigML api.
* @constructor
Expand Down Expand Up @@ -61,7 +60,9 @@ function BigML(username, apiKey, devMode) {
'batchprediction': this.url + constants.BATCH_PREDICTION_PATH,
'cluster': this.url + constants.CLUSTER_PATH,
'centroid': this.url + constants.CENTROID_PATH,
'batchcentroid': this.url + constants.BATCH_CENTROID_PATH
'batchcentroid': this.url + constants.BATCH_CENTROID_PATH,
'anomaly': this.url + constants.ANOMALY_PATH,
'anomalyscore': this.url + constants.ANOMALY_SCORE_PATH
};
this.downloadPath = '/download';
}
Expand Down Expand Up @@ -116,7 +117,6 @@ BigML.prototype.request = function (options, retry, cb) {
return cb(error);
}
}

if (body) {
var json;
try {
Expand Down
2 changes: 0 additions & 2 deletions lib/Centroid.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

var BigML = require('./BigML');
var Resource = require('./Resource');
var Ensemble = require('./Ensemble');
var LocalModel = require('./LocalModel');
var constants = require('./constants');
var logger = require('./logger');
var utils = require('./utils');
Expand Down
4 changes: 3 additions & 1 deletion lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ define("BATCH_PREDICTION_PATH", 'batchprediction');
define("CLUSTER_PATH", 'cluster');
define("CENTROID_PATH", 'centroid');
define("BATCH_CENTROID_PATH", 'batchcentroid');
define("ANOMALY_PATH", 'anomaly');
define("ANOMALY_SCORE_PATH", 'anomalyscore');

// Headers
define("SEND_JSON", {'Content-Type': 'application/json;charset=utf-8'});
Expand Down Expand Up @@ -131,7 +133,7 @@ define("RUNNABLE", -3);
// Resource types
define("RESOURCE_TYPES", ['source', 'dataset', 'model', 'ensemble',
'prediction', 'evaluation', 'batchprediction', 'cluster', 'centroid',
'batchcentroid']);
'batchcentroid', 'anomaly', 'anomalyscore']);
define("PUBLIC_RESOURCE_TYPES", ['dataset', 'model']);
define("SHARED_RESOURCE_TYPES", ['dataset', 'model', 'evaluation', 'cluster']);
// Resources syntax patterns
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"bindings",
"BigML"
],
"version": "1.0.0",
"version": "1.1.0",
"author": {
"name": "BigML",
"email": "info@bigml.com"
Expand All @@ -21,7 +21,7 @@
],
"main": "index.js",
"dependencies": {
"request": "2.21.0",
"request": "2.40.0",
"winston": "0.7.1",
"form-data": "0.0.10",
"combined-stream": "0.0.4",
Expand Down
Loading

0 comments on commit 64b29b9

Please sign in to comment.