Sentiment Analysis using Azure Cognitive Services & Flask

A quick tutorial on using Azure Cognitive Service with Python Flask
Posted by Sarav, 3 years ago on Artificial Intelligence

I was preparing for Microsoft AI - 900 exam and I came across various Cognitive Services offered by Microsoft via Azure. There are many such services such as Computer Vision, Text Analytics, Bot's, LUIS (Language Understanding) conversational AI etc. It is very exciting and fascinating to try out these Cognitive Services and moreover, Microsoft is very generous to offer 200$ credit for first-time users to play with various Microsoft Azure services.

In this article, we are going to look at one such Text Analytics service, the Sentiment Analysis. We are going to create a "Web Application" using Python "Flask" framework and perform Sentiment Analysis using Azure Text Analytics service.

There are multiple ways to access Azure Cognitive Services, here we are going to use REST API and Python SDK to connect with Text Analytics Service.

 

Sentiment Analysis

Sentiment Analysis is one of the Natural Language Processing technique that allows computers and AI programs to understand the underlying sentiment of a text. This is a machine-learned automatic process in which machines can express the sentiment of a given text in terms of it's the intent of writing. This analysis can detect sentiments such as Positive, Negative, Neutral and Mixed.

Behind the scenes of Sentiment Analysis, the AI algorithms perform complex calculation and techniques such as Tokenization of Sentence, Removing Stop Words, Normalizing Words, Vectorizing Text, etc.

There are numerous real-life application for Sentiment Analysis and some of them are,

  • Social media monitoring
  • Customer feedback analysis
  • Restaurant review
  • Movie rating
  • Product analysis and etc.,

 

Final Application

 

In this lesson, we are not going to do all of the complex calculation as mentioned above, instead, we are going use the SaaS (Software as a Service) provided by Microsoft. We are going to build a web application as shown above using the Flask framework, REST API and Python SDK. Before proceeding any further with this article, you need to have the following pre-requisites.

 

Pre-requisites

  • Azure Account.
    As we are going to Azure services, first you need to have Azure account and access to the cognitive services. Follow this link and click on "Try Azure for Free" to get started with Azure Services.

  • Text Analytics Service
    Now, we have our Azure Account setup. Let's look at a step-by-step guide to create a Text Analytics Service

    1. Log into your Azure account. Click Here
    2. In the Dashboard, click on "Create a Resource"
    3. Search for "Text Analytics" and click Create button
    4. In the resource creation form, Enter a unique name, select your subscription, Choose a location.
    5. In the Pricing tier, select F0 - Free tier
    6. Select a resource group or create a new one.
    7. Once you are done, hit on the Create button. Your form should look something like this.
    8. It may take a couple of minutes to create a resource and once it's done, click on "Keys and Endpoint" under the "Resource Management" group. 
    9. Copy and keep the "Endpoint" and "KEY 1" or "KEY 2". We will use it in our next section.

 

The Flask App

The web application has only one index route and two routes that accepts only "POST" request that will connect with Azure service to do the Sentiment Analysis. 

Download the source code and open then project folder using Visual Studio Code. If you need help on setting up python and VS Code, take a look at this article. After the project is loaded, open the .env file and paste the endpoint & keys.

Open a terminal go the project folder and run the following commands to start the web app.

# Create a virtual environment

python -m venv venv

# Activating the virtual environment

venv\Scripts\activate

# Installing requirements

pip install -r requirements.txt

# Running the app

SET FLASK_APP=sentiment.py
SET FLASK_ENV=development

flask run

Great, if everything goes fine you should see web application up and running on local port 5000. Open a web browser and navigate to http://127.0.0.1:5000.

As I mentioned above, we have two routes "/analyze-api" and "/analyze-sdk" to do the heavy lifting for us. Lets look at them one by one.

 

Analyze-API

This route makes a REST API call to Microsoft Aure Service, sends the text for analysis and retuns back a JSON result to our web application.

@app.route('/analyze-api', methods=['POST'])
def analyze_text_api():

    if request.method == 'POST':

        text = request.get_json()
        text = text['text']
        #text = "All of us do not have equal talent. But, all of 
        #us have an equal opportunity to develop our talents"
        
        url = (app.config['MICROSOFT_TEXT_ANALYTICS_URI'] +
                'text/analytics/v3.1-preview.1/sentiment')

        auth = {
            'Content-Type': 'application/json',
            'Ocp-Apim-Subscription-Key':
            app.config['MICROSOFT_TEXT_ANALYTICS_KEY'],
            'Accept': 'application/json'
        }

        data = {
            'documents': [{
                'language': 'en',
                'id': '1',
                'text': text,
            }]
        }

        try:

            response = requests.post(url, headers=auth, json=data)    
            result = response.json()['documents'][0]    
            result_dict = {
                'method' : 'API',
                'sentiment' : result['sentiment'],
                'positive_score' : result['confidenceScores']['positive'],
                'positive_neutral' : result['confidenceScores']['neutral'],
                'positive_negative' : result['confidenceScores']['negative'],
                'sentences' : []
            }

            sentenses = result['sentences']
            
            for sentence in sentenses:
                result_dict['sentences'].append({
                    'sentiment' : sentence['sentiment'],
                    'text' : sentence['text'],
                    'positive_score' : sentence['confidenceScores']['positive'],
                    'positive_neutral' : sentence['confidenceScores']['neutral'],
                    'positive_negative' : sentence['confidenceScores']['negative'],
                })
            
            return jsonify(result_dict)

        except:            
            return jsonify({"error": 'Internal Server Error'}), 500

 

Analyze-SDK

In this article, I wanted to show how to use both REST API method and Python SDK method to do the same text sentiment analysis.

@app.route('/analyze-sdk', methods=['POST'])
def analyze_text_sdk():

    if request.method == 'POST':
        try:
            endpoint = app.config['MICROSOFT_TEXT_ANALYTICS_URI']
            key = app.config['MICROSOFT_TEXT_ANALYTICS_KEY']

            text = request.get_json()
            text = text['text']
            #text = "All of us do not have equal talent. 
            #But, all of us have an equal opportunity to develop our talents"

            data = [text]

            credentials = AzureKeyCredential(key)
            text_analytics_client = TextAnalyticsClient(endpoint=endpoint, credential=credentials)

            result = text_analytics_client.analyze_sentiment(documents=data)[0]
            
            #print(result)
            result_dict = {
                'method' : 'SDK',
                'sentiment' : result.sentiment,
                'positive_score' : result.confidence_scores.positive,
                'positive_neutral' : result.confidence_scores.neutral,
                'positive_negative' : result.confidence_scores.negative,
                'sentences' : []
            }
            for index, sentence in enumerate(result.sentences):
                result_dict['sentences'].append({
                    'text' : sentence.text,
                    'sentiment' : sentence.sentiment,
                    'positive_score' : sentence.confidence_scores.positive,
                    'positive_neutral' : sentence.confidence_scores.neutral,
                    'positive_negative' : sentence.confidence_scores.negative,
                })
            return jsonify(result_dict)
        except:
            return jsonify({"error": 'Internal Server Error'}), 500

 

Client Side Script

Once we made successful connection with Text-Analytics service, the result sent is processed by the following client side Java Script code.

I have use the fetch API to make asynchronous call to our flask server and POST the text entered by the user and do the analysis.

function onSendToServer() {
  var text = document.getElementById("txtInput").value;
  var out = document.getElementById("result");
  var btn = document.getElementById("btnSend");
  var raw = document.getElementById("raw");
  var chkApi = document.getElementById("useAPI");

  entry = {
    text: text,
  };

  btn.disabled = true;
  btn.innerHTML = '<span class="sr-only">Loading please wait..</span>';
  out.innerHTML = "";
  raw.innerHTML = "";

  url = "";

  if (chkApi.checked) {
    url = "/analyze-api";
  } else {
    url = "/analyze-sdk";
  }

  fetch(url, {
    method: "POST",
    body: JSON.stringify(entry),
    cache: "no-cache",
    headers: new Headers({
      "content-type": "application/json",
    }),
  })
    .then(function (response) {
      btn.disabled = false;
      btn.innerHTML = '<span class="sr-only">Review</span>';
      response.json().then(function (data) {
        var err = data["error"];
        if (err) {
          out.innerHTML = "Error fetching data : " + err["message"];
        } else {
          setSentiment(data, out, raw);
        }
      });
    })
    .catch(function (error) {
      out.innerHTML = "Error while fetching the data";
      btn.disabled = false;
      btn.innerHTML = '<span class="sr-only">Review</span>';
    });
}

function setSentiment(data, out, raw) {
  var sentiment = data["sentiment"];
  if (sentiment == "neutral") {
    out.innerHTML =
      "The above sounds, <span class='text-primary'>Neutral</span> to me.";
  } else if (sentiment == "positive") {
    out.innerHTML =
      "It sounds pretty <span class='text-success'>Positive</span>.";
  } else if (sentiment == "negative") {
    out.innerHTML =
      "Too bad, I sense <span class='text-danger'>Negative</span> sentiment.";
  } else {
    out.innerHTML =
      "You know what? I have <span class='text-warning'>Mixed</span> feelings.";
  }
  raw.innerHTML = JSON.stringify(data, null, 2);
}

 

Conclusion

To summarize, we built a Flask web application that connects to Azure Congnitive Services to perform the sentiment analysis. 

Click Here to download the project files.

 

Similar Topics