Skip to main content

· 9 min read
It's 30DaysOfIA

In this article, explore how to create a user feedback analysis application by setting up an Azure environment to deploy and manage the app using Azure Container Apps and Azure AI.

What We'll Cover:​

  • Building and containerizing the intelligent app
  • Analysing user feedback

image of intelligent apps on Azure Container Apps with Azure AI

Deploy an Intelligent App on Azure Container Apps with Azure AI (2)​

In the first part of this article, we explored the concepts of Azure Container Apps and Azure AI, setup an Azure environment to deploy an intelligent app on Azure Container Apps as well as designed the intelligent app.

This article is a continuation to now build the intelligent app, containerize it and analyse user feedback.

Prerequisites​

To follow this tutorial, ensure you have read through the first part of this topic.

Building the Intelligent App​

Now that we’ve set up our basic application, let’s add some intelligence to it. Our initial step involves adding two NuGet packages: Azure.AI.TextAnalytics for granting access to Azure AI and Microsoft.Extensions.Azure for seamlessly injecting the SDK.

image of Azure.AI.TextAnalytics NuGet packages

image of Microsoft.Extensions.Azure NuGet package

Next, we need to register our text analytics client for dependency injection into our application. Before we can do that, the Text Analytics client requires two secrets:

  • An endpoint address
  • An access key

We need to add these into both our development and production environments. In both environments, AI_EndPoint is the endpoint variable name while AI_Key is the access key variable name.

To add these two items to your development environment, right-click on your project and select Manage User Secrets. Next, open your Publish profile, click the three dots ( … ) next to Hosting, and select Manage container app settings to verify that these variables are accessible within your container. Finally, you can add these secrets to your Azure container.

Now, open the Program.cs file and modify the section where we initialize the database context to include the text analytics initialization:

if (builder.Environment.IsDevelopment())
{
builder.Services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(builder.Configuration["userfeedbackdatabaseconnection"]));


builder.Services.AddAzureClients(clientBuilder =>
clientBuilder.AddTextAnalyticsClient(new Uri(builder.Configuration["AI_EndPoint"]),
new Azure.AzureKeyCredential(builder.Configuration["AI_Key"]))
);
}
else
{
builder.Services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTIONSTRING")));

builder.Services.AddAzureClients(clientBuilder =>
clientBuilder.AddTextAnalyticsClient(new Uri(builder.Configuration["AI_EndPoint"]),
new Azure.AzureKeyCredential(builder.Configuration["AI_Key"]))
);
}

Finally, let’s configure our Review Create method to retrieve sentiment analysis results from the Azure AI services API. To do this, add the following to your Review controller constructor:

private readonly TextAnalyticsClient _textClient;

public ReviewsController(DatabaseContext context, TextAnalyticsClient textClient)
{
_context = context;
_textClient = textClient;
}

Then, modify the POST Create Action in your Reviews controller to incorporate a call to the Azure AI services API for analyzing the review text:

        [HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,ProductId,ProductName,ReviewText,PostDate,Sentiment,PositiveValue,NeutralValue,NegativeValue")] Review review)
{
var selectedProductId = int.Parse(HttpContext.Request.Form["Products"].ToString());
var product = await _context.Products.FirstOrDefaultAsync(p => p.Id == selectedProductId);

var sentimentResult = await _textClient.AnalyzeSentimentAsync(review.ReviewText);

review.ProductId = selectedProductId;
review.ProductName = product.Name;
review.PostDate = DateTime.Now.ToString("yyyy-MM-dd");
review.Sentiment = sentimentResult.Value.Sentiment.ToString();
review.PositiveValue = (float)sentimentResult.Value.ConfidenceScores.Positive;
review.NeutralValue = (float)sentimentResult.Value.ConfidenceScores.Neutral;
review.NegativeValue = (float)sentimentResult.Value.ConfidenceScores.Negative;
 
_context.Add(review);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}

In this tutorial, we use the simpler AnalyzeSentimentAsync method. It takes our review text and produces an overall sentiment analysis, assigning positive, neutral, and negative scores.

Azure’s text analytics service also supports opinion mining, a more advanced use case. Opinion mining goes beyond the basics, providing sentiment analysis for specific subjects or keywords within a text.

For instance, if a review reads, “This was a really good product, but the delivery times were way too long. I also had a hard time understanding the manual,” the opinion mining option might break this into distinct subjects and offer sentiment analysis for each:

  • “Product” with a sentiment of positive
  • “Delivery time” with a sentiment of negative
  • “Manual” with a sentiment of negative
info

Watch the on-demand Learn Live serverless series that deconstructs a reference architecture for building intelligent apps using Azure Container Apps and Azure AI.

Using Your Intelligent App to Analyze User Feedback​

Now that we have our AI connected to our application, let’s create a review and see what the AI responds with.

Run the application, navigate to the /Reviews/Create folder to create a review, and click Submit. Select Clippers & Trimmers from the drop-down and write: “This was a really good trimmer for cutting my hair, but it gets caught in my beard.”

Upon inspecting the review you just posted, you’ll notice that Azure AI scored it as positive, albeit with slightly negative and neutral components.

image of review index

Now, try another review. This time, select the Headphones product from the drop-down and write the following review: “These headphones were passable. The foam on the outside was not thick enough and can hurt your head. The price is really cheap.”

This time, the AI scores the review as negative, with no positive score and a slight neutral score.

image of review index after a second review

By incorporating this AI-based scoring, you gain insights into customer feedback trends and can initiate specific actions based on positive or negative feedback. For example, we might want to understand how our product reviews have performed over the last seven days. Let’s update our review list page to present the average reviews during that period.

To achieve this, we’ll navigate to the ReviewContoller and summarize our data to display on the Index page. Then, we’ll load our products and reviews from the database, iterate through them, and average them over eight days (including the current day). Finally, we’ll compile the summarized data in a list and create a table based on the list.

Begin by creating a SentimentTrends model (a cut-down version of our review data) with this code:

namespace UserFeedbackApp.Models
{
public class SentimentTrends
{
public int Id { get; set; }
public string ProductName { get; set; }
public float PositiveValue { get; set; }
public float NeutralValue { get; set; }
public float NegativeValue { get; set; }
public string PostDate { get; set; }
}
}

Next, update the Index method in our ReviewController file using the following code:

public async Task<IActionResult> Index()
{
var reviewList = await _context.Reviews.ToListAsync();
var productList = await _context.Products.ToListAsync();
 
List<SentimentTrends> trends = new List<SentimentTrends>();

foreach(var product in productList)
{
var productReviews = reviewList
.Where(d => d.ProductId == product.Id)
.Where(d => DateTime.ParseExact(d.PostDate, "yyyy-MM-dd", CultureInfo.InvariantCulture) >= (DateTime.Now.AddDays(-8)))
.ToList();

if (productReviews.Count() > 0)
{

float positiveValue = 0;
float neutralValue = 0;
float negativeValue = 0;

foreach (var review in productReviews)
{
positiveValue += review.PositiveValue;
neutralValue += review.NeutralValue;
negativeValue += review.NegativeValue;
}

positiveValue = (float)Math.Round(positiveValue / productReviews.Count(), 2);
neutralValue = (float)Math.Round(neutralValue / productReviews.Count(), 2);
negativeValue = (float)Math.Round(negativeValue / productReviews.Count(), 2);

SentimentTrends trend = new SentimentTrends();

trend.Id = productReviews.First().ProductId;
trend.ProductName = productReviews.First().ProductName;
trend.PostDate = DateTime.Now.AddDays(-8).ToString("yyyy-MM-dd");
trend.PositiveValue = positiveValue;
trend.NeutralValue = neutralValue;
trend.NegativeValue = negativeValue;

trends.Add(trend);
}
}

ViewBag.Trends = trends;
return reviewList != null ?
View(reviewList) :
Problem("Entity set 'DatabaseContext.Reviews' is null.");
}

This code filters our recent reviews, averages them by the number of reviews received, and creates the list before passing it to the view in the ViewBag. To display this data, update the Index.cshtml file in our Views/Reviews folder with the following code:

 <h2>Seven Day Trend</h2> 
<table class="table">
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Positive</th>
<th>Neutral</th>
<th>Negative</th>
</tr>
</thead>
<tbody>
@foreach (SentimentTrends item in ViewBag.trends)
{
<tr>
<td>@item.Id</td>
<td>@item.ProductName</td>
<td>@item.PositiveValue</td>
<td>@item.NeutralValue</td>
<td>@item.NegativeValue</td>
</tr>
}
</tbody>
</table>

This displays our data in a simple table on our reviews page. If we run our code now and navigate to the reviews page, we’ll see the table at the top of the page. Averaging product sentiments this way offers valuable insights into potential product issues based on real user feedback.

image of the table on the reviews page

Conclusion​

Intelligent Apps can add more data and insights into your applications, opening possibilities for even more functionality.

In this two-part article, we built a simple web application using Azure Container Apps. Then, we incorporated sentiment analysis through Azure AI, extending our application’s capabilities to analyze user feedback. This application architecture on Azure enables seamless scalability for both the application and the AI components. This automatic scalability ensures your application can efficiently meet rising demands and scale back down when that demand subsides.

However, sentiment analysis is just one small component of the entire Azure AI suite. Azure AI includes several AI-driven APIs using pre-built models, such as:

  • Language understanding for translation, question answering, or conversational language comprehension
  • Image processing for image recognition or image and video analysis
  • Speech processing, including speech-to-text, text-to-speech, or speech translation
  • Anomaly detection, offensive content detection, and personalization

Begin your journey into Intelligent Apps with Azure, then delve into the next topic to learn how to level up your Intelligent Apps.

Exercise​