[Actualité] Analyse sentimentale avec Azure Text Analytics et Bot Framework v4
par
, 30/03/2019 à 15h49 (6738 Affichages)
Autrefois réservé à un cercle bien défini, l’intelligence artificielle est désormais à la porte de tout développeur voulant mettre en place une solution intelligente.
Cela a été rendu possible grâce à l’évolution des systèmes de calcul et des espaces de stockage d’une part, et d’autre part par la démocratisation du Cloud.
Le Cloud a permis aux géants de l’IT comme Microsoft, Amazon ou encore Google d’ouvrir et mettre à la disposition des développeurs, les investissements qu’ils ont effectués depuis longtemps dans ce domaine. C’est notamment le cas avec les services d’IA prebuilder.
Les IA prebuilder sont un ensemble de services permettant aux développeurs d’intégrer avec souplesse et simplicité des fonctionnalités d’IA dans leurs applications avec peu, voir aucune connaissance en intelligence artificielle. Ces services sont couramment des algorithmes de machine learning, de PNL (programmation neurolinguistique), etc. implémentés et déployés dans le Cloud.
Dans ce registre, on retrouve les services cognitifs de Microsoft. Il s’agit d’un ensemble d’API, de kit de développement (SDK) et de services pouvant être utilisés par les développeurs pour ajouter des fonctionnalités cognitives à leurs applications, comme la reconnaissance faciale, la détection d’émotion, la reconnaissance vocale, la compréhension du langage naturel, etc.
Dans ce billet de blog, nous verrons comment exploiter cette fonctionnalité pour le service cognitif Text Analytics.
Dans ce billet de blog, nous verrons comment mettre en place un bot qui utilise Text Analytics pour analyser les écrits d’un utilisateur et ressortir ses sentiments.
C’est quoi Azure Text Analytics ?
Text Analytics est un service cognitif de traitement en langage naturel de texte brut. Ce service inclut la détection de la langue de l’utilisateur, la détection des mots clés, la détection d’entités et l’analyse des sentiments.
- Détection du langage
Après analyse d’un texte, Text Analytics détermine la langue dans laquelle le texte est écrit et attribut un score à ce dernier, compris entre 0 et 1. Plus le score est proche de 1, plus la réponse retournée par le service est précise. Text Analytics supporte près de 120 langues.
- Détection des sentiments
Text Analytics est capable d’analyser le texte et ressortir le sentiment exprimé par l’auteur du texte. La valeur est comprise entre 0 et 1. Un score proche de 1 est un sentiment position, tandis qu’un score proche de 0 est un sentiment négatif. Cette fonctionnalité est pratique pour analyser les retours des utilisateurs sur un produit donné.
Pour utiliser Text Analytics, vous devez disposer d’un compte Microsoft Azure. Vous pouvez en créer un gratuitement si vous n’en disposez pas d’un.
Création du service Azure Text Analytics
La première chose à faire sera de créer le service Azure Text Analytics en utilisant le portail Azure (https://portal.azure.com/).
Cliquez sur “Créer une ressource”, dans la zone de saisie de la fenêtre qui va s’afficher, saisissez “Text Analytics”, puis sélectionnez ce qui sera affiché dans la liste déroulante :
Cliquez sur Créer.
Dans la fenêtre qui va s’afficher, renseigner les informations sur votre service (nom, emplacement, groupe de ressources et pricing). Prenez F0 pour le pricing. Ce dernier est gratuit. La tarification est fonction de l’utilisation. La tarification gratuite permet un maximum de 5 000 appels au service sur 30 jours.
Une fois les informations renseignées, cliquez sur Créer.
Le service sera créé et déployé dans le groupe de ressources correspondant. Un message de confirmation sera affiché dans le portail.
Dans la vue d’ensemble du service, veuillez noter le endpoint et les clés d’utilisation mis à votre disposition.
Appel du service avec Postman
Le service est exposé via HTTP comme une API Rest. De ce fait, nous pouvons utiliser Postman pour rapidement tester ce dernier.
Vous devez configurer Postman comme suit:
1 - Rype de requête : POST
2 - URL : entrez l’url de votre endpoint, suivi de la fonctionnalité que vous souhaitez utiliser. Pour notre cas, ce sera sentiment. L’URL va donc ressembler à ce qui suit : https:// [region].api.cognitive.microsoft.com/text/analytics/v2.0/sentiment
3 - Les en-têtes (heardes). Dans cette section, vous devez ajouter les paires clé:valeur suivantes :
Ocp-Apim-Subscription-Key: votre clé obtenue depuis le portail.
Content-Type: application/json.
Accept: application/json.
4 - Dans le body, vous allez mettre le contenu JSON suivant :
Code json : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 { "documents": [ { "language": "en", "id": "1", "text": "Hello world. This is some input text that I love." }, { "language": "fr", "id": "2", "text": "Bonjour, vous n'êtes pas bien habillé" }, { "language": "es", "id": "3", "text": "La carretera estaba atascada. Había mucho tráfico el día de ayer." } ] }
Une fois toutes les informations renseignées, cliquez sur send. Vous obtiendrez le résultat suivant :
Vous remarquez que pour la première phrase, le score s’approche de 1, dont le sentiment est positif, tandis que pour la seconde phrase qui est une critique négative, le score s’approche 0.
Voila, vous venez de tester votre service. Voyons maintenant comment l’utiliser dans notre Bot.
Si vous n’êtes pas familier avec le Bot Framework, je vous conseille dans un premier temps de lire mes billets de blog suivants sur le sujet :
Démarrer avec le Bot Builder SDK V4 pour .NET
Bot Builder V4 : mise en place d’une conversation guidée avec la librairie Dialogs
Création du Bot
Nous devons maintenant créer notre bot en utilisant Visual Studio. Vous allez créer une nouvelle application en utilisant le modèle EchoBot.
Une fois l’application créée, nous allons commencer par installer le package Microsoft.Azure.CognitiveServices.Language.Text via le gestionnaire NuGet :
Ensuite, nous devons modifier le fichier de configuration .bot, pour y ajouter les informations de connexion à notre service TextAnalytics :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 { "name": "SentimentBot", "services": [ { "type": "endpoint", "name": "development", "endpoint": "http://localhost:3978/api/messages", "appId": "", "appPassword": "", "id": "1" }, { "type": "textanalytics", "name": "sentiment", "subscriptionKey": "", "endpoint": "", "id": "2" } ], "padlock": "", "version": "2.0" }
Endpoint doit contenir l’adresse du service, sans le numéro de version : https:// [region].api.cognitive.microsoft.com
Subscriptionkey doit contenir la clé de souscription au service obtenu depuis le portail Azure.
Accès au service
Nous allons créer un dossier TextAnalytics. Dans celui-ci, nous allons ajouter l’interface ITextAnalyticsService avec le code suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public interface ITextAnalyticsService { Task<string> Sentiment(string text); }
Le client offert par le SDK pour se connecter et utiliser le service doit être initialisé en passant en paramètre un objet de type ServiceClientCredentials. Il s’agit d’une classe abstraite qui permet d’encapsuler les credentials nécessaires aux clients Rest pour accéder aux services Azure. Vu que c’est une classe abstraite, nous devons donc fournir notre propre implémentation qui dérive de cette dernière.
Nous allons donc ajouter à notre dossier TextAnalytics, un nouveau fichier ApiKeyServiceClientCredentials.cs avec le code suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 public class ApiKeyServiceClientCredentials : ServiceClientCredentials { private string _apiKey; public ApiKeyServiceClientCredentials(string apikey) { this._apiKey = apikey; } public override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) { request.Headers.Add("Ocp-Apim-Subscription-Key", _apiKey); return base.ProcessHttpRequestAsync(request, cancellationToken); } }
Créez maintenant le fichier TextAnalyticsService avec le code suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public class TextAnalyticsService : ITextAnalyticsService { public ITextAnalyticsClient TextAnalytics; public TextAnalyticsService(BotConfiguration botConfiguration) { } public Task<string> Sentiment(string text) { throw new NotImplementedException(); } }
Dans le constructeur de cette classe, nous devons initialiser notre client d’accès à l’API TextAnalytics. Pour cela, nous avons besoin du endpoint et de la clé de souscription inscrits dans le fichier de configuration du Bot. Nos informations sont dans une propriété de type JObject.
Le code pour le faire est le suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 var textAnalyticsConfig = botConfiguration.Services.Where(x => x.Name == "sentiment")?.FirstOrDefault(); var subscriptionKey = textAnalyticsConfig.Properties.SelectToken("subscriptionKey").ToString(); var endPoint = textAnalyticsConfig.Properties.SelectToken("endpoint").ToString();
Ensuite nous devons initialiser notre client, en utilisant ces informations :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 TextAnalytics = new TextAnalyticsClient(new ApiKeyServiceClientCredentials(subscriptionKey)) { Endpoint = endPoint, };
Penchons-nous maintenant sur l’implémentation de la méthode Sentiment(). La méthode SentimentAsync du client permet de retourner le résultat de l’analyse sentimentale. Le code de cette méthode est le suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 public async Task<string> Sentiment(string text) { //Get the sentiment var result = await TextAnalytics.SentimentAsync(multiLanguageBatchInput: new MultiLanguageBatchInput( new List<MultiLanguageInput>() { new MultiLanguageInput("fr", "0", text) })); return result.Documents?[0].Score?.ToString(); }
Le code complet de la classe TextAnalyticsService est le suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public class TextAnalyticsService : ITextAnalyticsService { public ITextAnalyticsClient TextAnalytics; public TextAnalyticsService(BotConfiguration botConfiguration) { var textAnalyticsConfig = botConfiguration.Services.Where(x => x.Name == "sentiment")?.FirstOrDefault(); var subscriptionKey = textAnalyticsConfig.Properties.SelectToken("subscriptionKey").ToString(); var endPoint = textAnalyticsConfig.Properties.SelectToken("endpoint").ToString(); TextAnalytics = new TextAnalyticsClient(new ApiKeyServiceClientCredentials(subscriptionKey)) { Endpoint = endPoint, }; } public async Task<string> Sentiment(string text) { //Get the sentiment var result = await TextAnalytics.SentimentAsync(multiLanguageBatchInput: new MultiLanguageBatchInput( new List<MultiLanguageInput>() { new MultiLanguageInput("fr", "0", text) })); return result.Documents?[0].Score?.ToString(); } }
Mise à jour du Startup.cs
Nous allons modifier la méthode ConfigureServices du fichier Startup.cs pour ajouter la classe TextAnalyticsService. Vous devez ajouter la ligne de code suivante dans cette méthode, après le code permettant de lire le fichier de configuration du bot.
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 //Add TextAnalyticsService services.AddSingleton<ITextAnalyticsService>(sp => new TextAnalyticsService(botConfig));
Appel du service dans le Bot
Nous allons maintenant apporter quelques modifications au fichier contenant le code du Bot ( SentimentBot.cs) pour pouvoir faire appel à TextAnalyticsService.
Pour commencer, ajoutez la propriété suivante à votre code :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part private readonly ITextAnalyticsService _textAnalyticsService;
Ensuite, modifiez le constructeur pour passer en paramètre ITextAnalyticsService, et assignez celui-ci à la propriété _textAnalyticsService.
Le code du constructeur devrait ressembler à ce qui suit :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public SentimentBot(ConversationState conversationState, ILoggerFactory loggerFactory, ITextAnalyticsService textAnalyticsService) { if (conversationState == null) { throw new System.ArgumentNullException(nameof(conversationState)); } if (loggerFactory == null) { throw new System.ArgumentNullException(nameof(loggerFactory)); } _textAnalyticsService = textAnalyticsService ?? throw new System.ArgumentNullException(nameof(textAnalyticsService)); _accessors = new SentimentBotAccessors(conversationState) { CounterState = conversationState.CreateProperty<CounterState>(SentimentBotAccessors.CounterStateName), }; _logger = loggerFactory.CreateLogger<SentimentBot>(); _logger.LogTrace("Turn start."); }
Pour finir, il faudra modifier la méthode OnTurnAsync(). Toute conversation avec le bot appelle cette méthode. Elle prend en paramètre ITurnContext qui contient toutes les données de contexte du bot.
Si l’activité du contexte du Bot est de type Message, nous devons à ce moment récupérer le texte qui a été saisi par l’utilisateur (urnContext.Activity.Text) et procéder à l’analyse sentimentale. Le code contenu dans le bloc if (turnContext.Activity.Type == ActivityTypes.Message) doit ressembler à ce qui :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 if (turnContext.Activity.Type == ActivityTypes.Message) { // Get the conversation state from the turn context. var state = await _accessors.CounterState.GetAsync(turnContext, () => new CounterState()); // Bump the turn count for this conversation. state.TurnCount++; // Set the property using the accessor. await _accessors.CounterState.SetAsync(turnContext, state); // Save the new turn count into the conversation state. await _accessors.ConversationState.SaveChangesAsync(turnContext); var sentimentResult = await _textAnalyticsService.Sentiment(turnContext.Activity.Text); // Echo back to the user whatever they typed. var responseMessage = $"Vous avez saisie '{turnContext.Activity.Text}'. L'analyse sentimentale donne le score suivant '{sentimentResult}'\n"; await turnContext.SendActivityAsync(responseMessage); }
Une fois cela, exécutez votre bot et testez-le en utilisant votre émulateur :
Vous venez de mettre en place un bot capable d’analyser les écrits d’un utilisateur pour détecter ses sentiments. Cette fonctionnalité peut être très pratique pour traiter par exemple, les retours des utilisateurs et prendre des décisions en fonction du résultat obtenu.
Le code d’exemple est disponible sur mon GitHub : https://github.com/hinault/dotnetbot...c/SentimentBot
Bot Builder V4 : mise en place d’une conversation guidée avec la librairie Dialogs
Démarrer avec le Bot Builder SDK V4 pour .NET
Bot Framework : exploiter les fonctionnalités du SDK V3 dans la version 4 du Bot Builder
Documentation officielle du SDK V4
GitHub du Bot Builder SDK V4
GitHub du Bot Framework Emulator V4
Blog Bot Framework