Nordlicht Reisen gets about 300 customer reviews a day (an assumption of the exercise). Nobody reads them all. What is wanted is a small helper that presorts the reviews: What is good, what is bad, what is it about? That is text analysis, and it is the first capability you build into an application in this lesson. The code is not run against Azure; this is how Microsoft Learn shows it. The output of the service is therefore not printed.
Two paths
There are two paths to the goal. A language model (your deployment reise-chat from lesson 2.1) gets the review and the task in the prompt. Or you use a service for text analysis: Azure Language in Foundry Tools (Azure Language for short). It returns fixed results instead of free text.
| Azure Language | Language model with a prompt | |
|---|---|---|
| Result | labels, scores, lists in a fixed form | free text, form set by the prompt |
| Fits | consistent, repeatable tasks in large numbers | open-ended tasks that were not planned in advance |
| Setup | resource, key or Entra sign-in | deployment, prompt, checking the answers |
This is how Microsoft's decision guide sums it up: Azure Language for consistent, repeatable tasks such as sentiment analysis at scale, models for unplanned language tasks with flexible prompting. Reviews are many texts of the same kind, so Azure Language comes first.
What Azure Language can do
Learn lists these features, among others. To try them without code, the Foundry portal offers most of them.
- Sentiment analysis and opinion mining: positive, negative, neutral, at document and sentence level. Opinion mining assigns sentiments to things, such as "room" or "staff".
- Key phrase extraction: the main topics of a text as a list.
- Named entity recognition (NER): finding names, places, dates and other categories in the text.
- Summarization: extractive picks important sentences from the text, abstractive writes new, short sentences.
- Language detection: which language a text is in. Useful, because some of Nordlicht's messages are in English.
A classification you should know: on its overview page, Learn lists named entity recognition, language detection and detection of personal data as core features that are recommended for new development. Sentiment analysis, key phrases and summarization are listed there under legacy features that are "supported for existing implementations". How long that stays so, the page does not say: open. The exam asks about these features anyway.
Sentiment analysis in detail
According to Learn, it returns labels and scores (confidence scores) per sentence and per document. Labels: positive, negative, neutral, and at document level also mixed. The three scores of a sentence add up to 1. A score near 1 means high certainty of the service, not strong sentiment.
Four notes from Learn that matter for Nordlicht:
- Without a language, the service assumes English. German is supported according to Learn, but must be specified. How you set the language in the C# call, the quickstart page does not show: open, see the API reference.
- Sentiment analysis works better with small pieces of text, key phrases with larger ones.
- The model was trained on product and service reviews. With other texts, for example about people, it can be wrong. Travel reviews are close to what it is meant for.
- It may not recognize irony, and an overall score can differ from what a person would read as the overall impression.
The code
Learn's C# quickstart for sentiment analysis uses the NuGet package Azure.AI.TextAnalytics (the page names version 5.2.0, versions change) and reads key and address from environment variables. For production, Learn recommends Entra ID with managed identities instead of a key in the code. Excerpt from Learn's example, omitted lines are output:
static string languageKey = Environment.GetEnvironmentVariable("LANGUAGE_KEY");
static string languageEndpoint = Environment.GetEnvironmentVariable("LANGUAGE_ENDPOINT");
private static readonly AzureKeyCredential credentials = new AzureKeyCredential(languageKey);
private static readonly Uri endpoint = new Uri(languageEndpoint);
var documents = new List<string>
{
"The food and service were unacceptable. The concierge was nice, however."
};
AnalyzeSentimentResultCollection reviews = client.AnalyzeSentimentBatch(documents, options: new AnalyzeSentimentOptions()
{
IncludeOpinionMining = true
});
foreach (AnalyzeSentimentResult review in reviews)
{
Console.WriteLine($"Document sentiment: {review.DocumentSentiment.Sentiment}\n");
Console.WriteLine($"\tNegative score: {review.DocumentSentiment.ConfidenceScores.Negative:0.00}");
}
var client = new TextAnalyticsClient(endpoint, credentials);
Line by line:
- The first four lines read
LANGUAGE_KEYandLANGUAGE_ENDPOINTfrom the environment and build credentials and the address of the Language resource from them. documentsis a list of texts, one here. Instead of the English sentence, you put in the content ofbewertung-1.txt. The service accepts several texts in one call (batch).AnalyzeSentimentBatchsends the list to the service.IncludeOpinionMining = trueswitches on opinion mining.foreachgoes through the results:Sentimentis the label of the document,ConfidenceScores.Negativethe score for "negative".TextAnalyticsClientis the client with address and credentials.
What the output looks like, Learn describes this way: per document the label and three scores, per sentence the same, and with opinion mining additionally the things with their assessments. There is no invented result here. For the exam, you read the Python tab of the same page (note in lesson 2.3).
For summarization, Learn has a C# example of its own with the same package, but a prerelease version (Include prerelease).
The case: three reviews
In this exercise, the files bewertung-1.txt to bewertung-3.txt contain these made-up texts:
- "The room was clean and the view of the lake wonderful, but the breakfast was cold."
- "Great advice at the travel agency, everything fit. Gladly again!"
- "The transfer did not come, and nobody helped us at the hotline. We lost a day."
What matters is what Nordlicht does with the result. The helper decides nothing about customers. It sorts: reviews with negative sentiment go onto a list that a person from customer service reads every day (Ms. Berg is responsible, lesson 1.1). It sends no reply and decides nothing about refunds. Learn's notes on sentiment analysis support this: do not automate high-impact actions without people, and test the threshold for "negative" on real data. Anyone who would rather read too many negative reviews than too few sets the threshold for the negative score lower and accepts more false alarms. Which threshold suits Nordlicht is open: Learn requires testing it on real data.
Exercise 1
Assign a feature to each of Nordlicht's tasks (sentiment analysis, key phrases, entity recognition, summarization, language detection) and say who reads the result:
- Which reviews are negative and belong on customer service's list?
- An English message should go to the English-speaking team.
- From 300 reviews, a weekly overview of the most frequently mentioned topics should be produced.
- In review 3, it should be recognized that "transfer" and "hotline" occur.
- A long complaint should be summarized in two sentences for management.
Solution 1
- Sentiment analysis. A person in customer service reads the negative reviews. Opinion mining shows whether "transfer" or "breakfast" is meant.
- Language detection. It returns the language, after which the text goes to the right team. Without a language, sentiment analysis would assume English, which would be wrong for the German texts.
- Key phrases, best across many reviews together, because Learn says this service works better with larger amounts of text. 4. Key phrases return "transfer" and "hotline" as topics. Entity recognition would rather find names, places and dates, so not these words. Whether a service delivers both in a given case, only a test with real texts shows.
- Summarization. A person checks it against the original text, because an abstractive summary writes new sentences and can make mistakes in doing so. Anyone who passes on a summary unchecked takes over these mistakes.