import fasttext from './fasttext-exec';
import colors from 'colors';
import exec from './exec';
import isURL from 'is-url';
import path from 'path';
import fs from 'fs';
const defaultOptions = {
labelCount: 3,
model: 'training-model',
};
/**
* Function to test the trained model against a set of test data.
* If the testData param is a url the fetch the file from the url.
* If the testData param is a file name then read that filename
* Else show an error as you cannot test from small amount of data
*
* @export
* @param {string} testData URL or filename
* @param {string} [options={}] Options for training model
* @property {number} [options.labelCount=3] Number of labels to be returned by the predicting function
* @property {string} [options.model='training-model'] The model name which will be used to export the saved model
* @returns {object} Returns the accuracy of the model according to the given test data set
*/
export default async function testTrainedModel(
testData,
options = {},
fastTextConfig = {}
) {
let filename = testData;
// Check if a url is passed
if (isURL(testData)) {
// Download the data from the url
fastTextConfig.logs &&
console.log(colors.yellow('Downloading testing file...'));
const output = await exec(`curl ${testData} -o test.txt`);
fastTextConfig.logs && console.log(output);
filename = path.join(__dirname, '..', '..', 'test.txt');
}
if (!fs.existsSync(filename)) {
fastTextConfig.logs &&
console.log(
colors.red(
'Test data should be a path/url to some txt file. Check the arguments for FastText.test() function'
)
);
return false;
}
fastTextConfig.logs && console.log(colors.yellow('Training fasttext model'));
const finalOptions = Object.assign(defaultOptions, options);
finalOptions.model =
options.model || fastTextConfig.model || defaultOptions.model;
if (finalOptions.model.indexOf(path.sep) === -1) {
// if only name is provided, then store in parent folder
finalOptions.model = path.join(__dirname, '..', '..', finalOptions.model);
}
const trainingCommand = `test ${finalOptions.model}.bin ${filename} ${finalOptions.labelCount}`;
const { stderr, stdout } = await fasttext(trainingCommand);
const value = `${stdout}\n${stderr}`;
const splits = value.split('\n');
const samples = Number(splits[0].split('\t').pop());
const precision = Number(splits[1].split('\t').pop());
const recall = Number(splits[2].split('\t').pop());
fastTextConfig.logs && console.log(colors.green(`Testing model: ${value}`));
return { samples, precision, recall };
}