In this post, we'll learn how to build a text classification model using TensorFlow.js and Node.js. Text classification is a common task in natural language processing, which is the process of analyzing and working with human language data.
We'll be using a dataset of movie reviews from the website Rotten Tomatoes. The dataset contains text for each review, as well as a label indicating whether the review is positive or negative. We'll use this dataset to train a model that can read new reviews and predict whether they're positive or negative.
Before we get started, there are a few things you'll need:
First, we need to create a new Node.js project. Create a new directory for your project and initialize it with npm:
mkdir text-classification
cd text-classification
npm init -y
This will create a package.json file for your project. Next, we need to install the dependencies we'll be using. We'll be using TensorFlow.js, a library for working with machine learning in JavaScript, and the natural library, which provides some helpful functions for working with human language data.
npm install --save @tensorflow/tfjs natural
With the dependencies installed, we can now start coding. Create a new file called index.js in your project directory and add the following code:
const tf = require('@tensorflow/tfjs');
const natural = require('natural');
// TODO: Add code here
This imports the TensorFlow.js and natural libraries, which we'll be using in the next section.
Before we can train our model, we need to prepare the data. The movie review dataset is in a file called reviews.csv, which you can download here.
Add the following code to index.js to load and prepare the data:
const tf = require('@tensorflow/tfjs');
const natural = require('natural');
// TODO: Add code here
// Load the dataset
const csvUrl = 'https://storage.googleapis.com/tfjs-examples/movie-reviews/data.csv';
const { data, labels } = tf.data.csv(csvUrl);
// Shuffle the data
const shuffledData = data.shuffle();
// Split the data into training and test sets
const [trainData, testData] = shuffledData.split([0.8, 0.2]);
// Convert the labels to a one-hot encoding
const trainLabels = trainData.map((_, i) => labels[i]).oneHot(2);
const testLabels = testData.map((_, i) => labels[i]).oneHot(2);
// Normalize the data
const trainDataNormalized = trainData.map(review => {
// Convert the review to lowercase
const lowered = review.toLowerCase();
// Tokenize the review
const tokens = natural.WordTokenizer().tokenize(lowered);
// Remove stopwords
const filtered = tokens.filter(token => !natural.stopwords.some(stopword => stopword === token));
// Join the tokens back into a string
const text = filtered.join(' ');
// Return the normalized review
return text;
});
const testDataNormalized = testData.map(review => {
// Convert the review to lowercase
const lowered = review.toLowerCase();
// Tokenize the review
const tokens = natural.WordTokenizer().tokenize(lowered);
// Remove stopwords
const filtered = tokens.filter(token => !natural.stopwords.some(stopword => stopword === token));
// Join the tokens back into a string
const text = filtered.join(' ');
// Return the normalized review
return text;
});
Let's take a look at what this code does:
Now that we have the data prepared, we can build the model. We'll be using a Bidirectional Long Short-Term Memory (BiLSTM) model, which is a type of recurrent neural network (RNN).
Add the following code to index.js to build the model:
const tf = require('@tensorflow/tfjs');
const natural = require('natural');
// TODO: Add code here
// Load the dataset
const csvUrl = 'https://storage.googleapis.com/tfjs-examples/movie-reviews/data.csv';
const { data, labels } = tf.data.csv(csvUrl);
// Shuffle the data
const shuffledData = data.shuffle();
// Split the data into training and test sets
const [trainData, testData] = shuffledData.split([0.8, 0.2]);
// Convert the labels to a one-hot encoding
const trainLabels = trainData.map((_, i) => labels[i]).oneHot(2);
const testLabels = testData.map((_, i) => labels[i]).oneHot(2);
// Normalize the data
const trainDataNormalized = trainData.map(review => {
// Convert the review to lowercase
const lowered = review.toLowerCase();
// Tokenize the review
const tokens = natural.WordTokenizer().tokenize(lowered);
// Remove stopwords
const filtered = tokens.filter(token => !natural.stopwords.some(stopword => stopword === token));
// Join the tokens back into a string
const text = filtered.join(' ');
// Return the normalized review
return text;
});
const testDataNormalized = testData.map(review => {
// Convert the review to lowercase
const lowered = review.toLowerCase();
// Tokenize the review
const tokens = natural.WordTokenizer().tokenize(lowered);
// Remove stopwords
const filtered = tokens.filter(token => !natural.stopwords.some(stopword => stopword === token));
// Join the tokens back into a string
const text = filtered.join(' ');
// Return the normalized review
return text;
});
// Build the model
const model = tf.sequential();
model.add(tf.layers.embedding({
inputDim: 1000,
outputDim: 32,
inputLength: 100
}));
model.add(tf.layers.bidirectional({
layer: tf.layers.lstm({
units: 32
})
}));
model.add(tf.layers.dense({
units: 2,
activation: 'softmax'
}));
model.compile({
loss: 'categoricalCrossentropy',
optimizer: 'adam',
metrics: ['accuracy']
});
// Train the model
model.fit(trainDataNormalized, trainLabels, {
epochs: 5,
validationData: [testDataNormalized, testLabels]
}).then(() => {
// Evaluate the model
const results = model.evaluate(testDataNormalized, testLabels);
console.log(results);
});
This code does the following:
Now that we have a trained model, we can use it to make predictions. Add the following code to index.js to make predictions:
const tf = require('@tensorflow/tfjs');
const natural = require('natural');
// TODO: Add code here
// Load the dataset
const csvUrl = 'https://storage.googleapis.com/tfjs-examples/movie-reviews/data.csv';
const { data, labels } = tf.data.csv(csvUrl);
// Shuffle the data
const shuffledData = data.shuffle();
// Split the data into training and test sets
const [trainData, testData] = shuffledData.split([0.8, 0.2]);
// Convert the labels to a one-hot encoding
const trainLabels = trainData.map((_, i) => labels[i]).oneHot(2);
const testLabels = testData.map((_, i) => labels[i]).oneHot(2);
// Normalize the data
const trainDataNormalized = trainData.map(review => {
// Convert the review to lowercase
const lowered = review.toLowerCase();
// Tokenize the review
const tokens = natural.WordTokenizer().tokenize(lowered);
// Remove stopwords
const filtered = tokens.filter(token => !natural.stopwords.some(stopword => stopword === token));
// Join the tokens back into a string
const text = filtered.join(' ');
// Return the normalized review
return text;
});
const testDataNormalized = testData.map(review => {
// Convert the review to lowercase
const lowered = review.toLowerCase();
// Tokenize the review
const tokens = natural.WordTokenizer().tokenize(lowered);
// Remove stopwords
const filtered = tokens.filter(token => !natural.stopwords.some(stopword => stopword === token));
// Join the tokens back into a string
const text = filtered.join(' ');
// Return the normalized review
return text;
});
// Build the model
const model = tf.sequential();
model.add(tf.layers.embedding({
inputDim: 1000,
outputDim: 32,
inputLength: 100
}));
model.add(tf.layers.bidirectional({
layer: tf.layers.lstm({
units: 32
})
}));
model.add(tf.layers.dense({
units: 2,
activation: 'softmax'
}));
model.compile({
loss: 'categoricalCrossentropy',
optimizer: 'adam',
metrics: ['accuracy']
});
// Train the model
model.fit(trainDataNormalized, trainLabels, {
epochs: 5,
validationData: [testDataNormalized, testLabels]
}).then(() => {
// Evaluate the model
const results = model.evaluate(testDataNormalized, testLabels);
console.log(results);
// Make a prediction
const prediction = model.predict(['this movie was great']);
console.log(prediction);
});
This code does the following:
In this post, we learned how to build a text classification model using TensorFlow.js and Node.js. We started by loading and preparing the data, then we built and trained a model. Finally, we used the model to make predictions.
Text classification is a common task in natural language processing, and this post shows how to build a text classification model using TensorFlow.js and Node.js.