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
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:
- The data for this problem has been taken from the Kaggle Repository.