Classify amazon reviews into positive and negative using OpenNN

Generally, the feedback provided by a customer on a product can be categorized into positive and negative. Interpreting customer feedback through product reviews helps companies evaluate how satisfied the customers are with their products/services. This example aims to assess whether a review of an Amazon product could be positive or negative from its content.

Contents:

  1. Application type.
  2. Data set.
  3. Neural network.
  4. Training strategy.
  5. Testing analysis.
  6. Model seployment.
  7. Full Code.

1. Application type

The variable to be predicted can have two values (positive or negative). Therefore, this is a binary text classification project.

The goal here is to model the probability of a review being positive or negative, conditioned on the words used by the customer.

2. Data set

The first step is to prepare the data set, the source of information for the classification problem. Data set object can be created by

DataSet data_set;

Next, we need to configure the following concepts:

  • Data source.
  • Separator.

The data source is the file amazon_reviews.csv. It contains the data for this example in TXT format and can be loaded as

data_set.set_data_file_name("path_to_source/amazon_cells_labelled.txt");

Our data contains two columns separated by tabulator and 10000 rows. This column separator can be set by

data_set.set_text_separator(DataSet::Separator::Tab);

Once we have set the data file name and the separator, we are ready to load our document. This can be done by

data_set.read_txt();

The reviews are divided into training, selection, and testing subsets. They represent 60% (6000), 20% (2000), and 20% (2000) of the original reviews, respectively, and are split at random using the following command

data_set.split_samples_random();

Now that we have the data ready, we can get data set features like the words contained in the dataset, words number and the target variables number, For this, we use the following commands

const Tensor<string, 1> input_words = data_set.get_input_columns_names();
const Tensor< string, 1> targets_names = data_set.get_target_variables_names();
const Index words_number = data_set.get_input_variables_number();
const Index target_variables_number = data_set.get_target_variables_number();

For more information about the data set methods, see DataSet class.

3. Neural network

The second step is to choose the correct neural network architecture. For text classification problems, it is usually composed by:

  • A scaling layer.
  • Two perceptron layers.
  • A probabilistic layer.
  • An unscaling layer.

The NeuralNetwork class is responsible for building the neural network and adequately organizing the layers of neurons using the following constructor. If you need more complex architectures, you should see NeuralNetwork class.

const Index hidden_neurons_number = 6;
NeuralNetwork neural_network(NeuralNetwork::TextClassification,
    {words_number , hidden_neurons_number, target_variables_number});

Once the neural network has been created, we can introduce information in the layers for a more precise calibration

neural_network.set_inputs_names(inputs_words);
neural_network.set_outputs_names(targets_names);

Therefore, we have already created a good-looking model. Thus we proceed to the learning process with TrainingStrategy.

4. Training strategy

The third step is to set the training strategy, which is composed of:

  • Loss index.
  • Optimization algorithm.

Firstly, we construct the training strategy object

TrainingStrategy training_strategy(&neural_network, &data_set);

then, set the error term

training_strategy.set_loss_method(TrainingStrategy::CROSS_ENTROPY_ERROR);

and finally the optimization algorithm

training_strategy.set_optimization_method(TrainingStrategy::ADAPTIVE_MOMENT_ESTIMATION);

We can now start the training process by using the command

training_strategy.perform_training();

For more information about the training strategy methods, see TrainingStrategy class.

5. Testing analysis

The fourth step is to evaluate our model. For that purpose, we need to use the testing analysis class, whose goal is to validate the model’s generalization performance. Here, we compare the neural network outputs to the corresponding targets in the testing instances of the data set.

We start by building the testing analysis object

TestingAnalysis testing_analysis(&neural_network, &data_set);

and perform the testing, in our case we use binary classification tests

testing_analysis.print_binary_classification_tests();

For more information about the testing analysis methods, see TestingAnalysis class.

6. Model deployment

Once our model is completed, the neural network is ready to predict outputs for inputs it has never seen. This process is called model deployment.

To generate predictions with new data, you can use

neural_network.calculate_outputs();

For instance, the new input review is:

  • «Highly recommend for any one who has a bluetooth phone.»

and in OpenNN we can write it as

string review_1 = "Highly recommend for any one who has a bluetooth phone.";
Tensor<type,1> processed_review_1 = data_set.sentence_to_data(review_1);
string review_2 = "You have to hold the phone at a particular angle for the other party to hear you clearly.";
Tensor<type,1> processed_review_2 = data_set.sentence_to_data(review_2);

Once the reviews are transformed into numeric tensors, their predictions can be calculated utilizing:

Tensor<type,2> input_data(2, words_number);
for(Index i = 0; i < words_number; i++)
{
  input_data(0,i) = processed_review_1(i);
  input_data(1,i) = processed_review_2(i);
}
Tensor<type,2> outputs = neural_network.calculate_outputs(input_data);

You can also save the model using:

neural_network.save_expression_c("../data/expression.txt");
neural_network.save_expression_python("../data/expression.txt");

The model can be implemented in python, php, … .

7. Full Code

Joining all steps, we obtain the following code:

// DataSet
DataSet data_set;
data_set.set_data_file_name("path_to_source/amazon_cells_labelled.txt");
data_set.set_text_separator(DataSet::Separator::Tab);
data_set.read_txt();
data_set.split_samples_random();
const Tensor<string, 1> input_words = data_set.get_input_columns_names();
const Tensor<string, 1> targets_names = data_set.get_target_variables_names();
const Index words_number = data_set.get_input_variables_number();
const Index target_variables_number = data_set.get_target_variables_number();
            
// Neural Network
const Index hidden_neurons_number = 6;
NeuralNetwork neural_network(NeuralNetwork::ProjectType::TextClassification,
    {words_number , hidden_neurons_number, target_variables_number});
            
// Training Strategy
TrainingStrategy training_strategy(&neural_network, &data_set);
training_strategy.set_loss_method(TrainingStrategy::LossMethod::CROSS_ENTROPY_ERROR);
training_strategy.set_optimization_method(TrainingStrategy::OptimizationMethod::ADAPTIVE_MOMENT_ESTIMATION);
training_strategy.perform_training();
            
// Testing Analysis
TestingAnalysis testing_analysis(&neural_network, &data_set);
testing_analysis.print_binary_classification_tests();
            
// Model deployment
string review_1 = "Highly recommend for any one who has a bluetooth phone.";
Tensor<type,1> processed_review_1 = data_set.sentence_to_data(review_1);
string review_2 = "You have to hold the phone at a particular angle for the other party to hear you clearly.";
Tensor<type,1> processed_review_2 = data_set.sentence_to_data(review_2);
Tensor<type,2> input_data(2, words_number);
for(Index i = 0; i < words_number; i++)
{
  input_data(0,i) = processed_review_1(i);
  input_data(1,i) = processed_review_2(i);
}
Tensor<type,2> outputs = neural_network.calculate_outputs(input_data);
            
// Save results
neural_network.save_expression_c("../data/amazon_reviews.txt");
neural_network.save_expression_python("../data/amazon_reviews.py");

This code can be exported to your C++ project.

References: