{"id":542,"date":"2020-09-24T10:58:08","date_gmt":"2020-09-24T17:58:08","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=542"},"modified":"2020-10-05T15:22:59","modified_gmt":"2020-10-05T22:22:59","slug":"opinion-mining","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/opinion-mining\/","title":{"rendered":"Opinion Mining with the Text Analytics Client Libraries"},"content":{"rendered":"<p>With v5.1.0, the new Text Analytics client library <a href=\"https:\/\/docs.microsoft.com\/azure\/cognitive-services\/text-analytics\/how-tos\/text-analytics-how-to-sentiment-analysis\">now supports opinion mining<\/a>. In this post, we&#8217;ll introduce you to the opinion mining concept and then jump into some code.<\/p>\n<h2>Introducing Opinion Mining<\/h2>\n<p>You can think of opinion mining as a more granular sentiment analysis, diving even deeper into the individual opinions that shape the overall sentiment. More formally, it provides in-depth analysis of opinions about aspects (i.e. attributes) of a product or a service, and is also referred to as <a href=\"https:\/\/monkeylearn.com\/blog\/aspect-based-sentiment-analysis\/\">Aspect-Based Sentiment Analysis<\/a>.<\/p>\n<p>Since this is a concept most clearly explained with examples, let&#8217;s consider a review (taken directly from the <a href=\"https:\/\/docs.microsoft.com\/azure\/cognitive-services\/text-analytics\/how-tos\/text-analytics-how-to-sentiment-analysis?tabs=version-3#opinion-mining\">Text Analytics service documentation<\/a>): &#8220;The room was great, but the staff was unfriendly&#8221;. Returning an overall sentiment for this review doesn&#8217;t capture the two distinct opinions of aspects of the hotel, so this is a perfect review to dive deeper into. By using opinion mining, we get that while the &#8220;room&#8221; is &#8220;great&#8221;, the &#8220;staff&#8221; is &#8220;unfriendly&#8221;. Here is a visual breakdown (also taken directly from the service documentation) of the information opinion mining will extract from this review:<\/p>\n<table>\n<thead>\n<tr>\n<th>Aspect<\/th>\n<th>Opinion<\/th>\n<th>Sentiment<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>room<\/td>\n<td>great<\/td>\n<td>positive<\/td>\n<\/tr>\n<tr>\n<td>staff<\/td>\n<td>unfriendly<\/td>\n<td>negative<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Let&#8217;s consider a scenario of a hotel manager looking to improve their hotel. This extra layer of opinion mining when conducting sentiment analysis on customer reviews allows them to determine that they should allocate extra resources to train their staff members.<\/p>\n<p>Other scenarios where opinion mining is useful that aren&#8217;t shown in this blog include:<\/p>\n<ul>\n<li>Creating word clouds from the analyzed opinions<\/li>\n<li>Issue automation. For example, routing complaints to different teams based on the aspects that show up in the issues.<\/li>\n<li>Analyzing social media streams<\/li>\n<\/ul>\n<h2>Opinion Mining with the new Text Analytics client library<\/h2>\n<p>Let&#8217;s expand on the previous example with some code! We&#8217;ll continue looking into the hotel manager scenario, where we&#8217;ll focus on identifying complaints in reviews (special thanks to Mari for this usage scenario).<\/p>\n<p>I will use Python in this post, but if you would like a demonstration in a different language, please refer to the following samples in the supported languages for: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/blob\/Azure.AI.TextAnalytics_5.1.0-beta.1\/sdk\/textanalytics\/Azure.AI.TextAnalytics\/samples\/Sample2.1_AnalyzeSentimentWithOpinionMining.md\">.NET<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/blob\/%40azure\/ai-text-analytics_5.1.0-beta.1\/sdk\/textanalytics\/ai-text-analytics\/samples\/typescript\/src\/analyzeSentimentWithOpinionMining.ts\">JavaScript\/TypeScript<\/a>, and <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/blob\/azure-ai-textanalytics_5.1.0-beta.1\/sdk\/textanalytics\/azure-ai-textanalytics\/src\/samples\/java\/com\/azure\/ai\/textanalytics\/AnalyzeSentimentWithOpinionMining.java\">Java<\/a>.<\/p>\n<p>First, here are the reviews the hotel manager has scraped. Just analyzing each review on a sentence level isn&#8217;t enough: different aspects of the hotel have different opinions and sentiments associated with them, and returning an overall sentiment for the review won&#8217;t tell them what they should change about their hotel.<\/p>\n<pre><code class=\"python\">reviews = [\n    \"The room was great, but the staff was unfriendly\",\n    \"The rooms were beautiful. The AC was good and quiet.\",\n    \"The breakfast was good, but the toilet was smelly.\",\n    \"Loved this hotel - good breakfast - nice shuttle service - clean rooms.\",\n    \"I had a great unobstructed view of the Microsoft campus.\",\n    \"Nice rooms but bathrooms were old and the toilet was dirty when we arrived.\",\n    \"The toilet was broken.\"\n]\n<\/code><\/pre>\n<p>Run the following pip command to install the library:<\/p>\n<pre><code class=\"bash\">pip install azure-ai-textanalytics --pre\n<\/code><\/pre>\n<p>To use our Text Analytics client library, the hotel manager first needs to create a service client for their network calls. See <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/tree\/master\/sdk\/textanalytics\/azure-ai-textanalytics#authenticate-the-client\">the client library&#8217;s documentation on how to create and authenticate a client<\/a> for more information.<\/p>\n<pre><code class=\"python\">from azure.core.credentials import AzureKeyCredential\nfrom azure.ai.textanalytics import TextAnalyticsClient\n\ncredential = AzureKeyCredential(\"&lt;api_key&gt;\")\nclient = TextAnalyticsClient(endpoint=\"&lt;endpoint&gt;\", credential=credential)\n<\/code><\/pre>\n<p>Now it is time to conduct opinion mining on these reviews! Since opinion mining is a form of sentiment analysis, the hotel manager needs to call <code>analyze_sentiment<\/code>. To let the service know that they also want opinion mining to be done on top of the analysis, they also need to pass <code>show_opinion_mining=True<\/code> to the call.<\/p>\n<pre><code class=\"python\">analyzed_reviews = client.analyze_sentiment(reviews, show_opinion_mining=True)\n<\/code><\/pre>\n<p>Now that the hotel manager has used our client library to analyze their reviews with opinion mining, they need to extract the information useful for their scenario. Since they&#8217;re looking to improve the experience of their hotel, they are most interested in the content and frequency of complaints.<\/p>\n<pre><code class=\"python\">complaints = {}\nfor review in analyzed_reviews:\n    for sentence in review.sentences:\n        for mined_opinion in sentence.mined_opinions:\n            if mined_opinion.aspect.sentiment == \"negative\":\n                aspect_text = mined_opinion.aspect.text\n                opinions = [opinion.text for opinion in mined_opinion.opinions]\n                if aspect_text in complaints:\n                    complaints[aspect_text].extend(opinions)\n                else:\n                    complaints[aspect_text] = opinions\n<\/code><\/pre>\n<p>With these complaints, they can see what aspects of their hotel people feel negatively about, and how many people agree.<\/p>\n<pre><code class=\"python\">for complaint in complaints:\n    opinions = complaints[complaint]\n    print(f\"There have been '{len(opinions)}' complaint(s) about '{complaint}'\")\n    joined_opinions = \"', '\".join(opinions)\n    print(f\"...The specific complaints are: '{joined_opinions}'\")\n<\/code><\/pre>\n<p>Output:<\/p>\n<pre><code>There have been '1' complaint(s) about 'staff'\n...The specific complaints are: 'unfriendly'\nThere have been '3' complaint(s) about 'toilet'\n...The specific complaints are: 'smelly', 'dirty', 'broken'\nThere have been '1' complaint(s) about 'bathrooms'\n...The specific complaints are: 'old'\n<\/code><\/pre>\n<p>Thanks to the power of opinion mining, the hotel manager can see the above aspects of their hotel need to be improved, and that they especially need to resolve their toilet situation.<\/p>\n<h2>Further Documentation<\/h2>\n<p>If you&#8217;re interested in getting started with our <a href=\"https:\/\/docs.microsoft.com\/azure\/cognitive-services\/text-analytics\/overview\">Text Analytics<\/a> client libraries, here are the links for each language we support<\/p>\n<ul>\n<li>Python <a href=\"https:\/\/azure.github.io\/azure-sdk-for-python\/ref\/Text-Analytics.html\">Reference Documentation<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/blob\/master\/sdk\/textanalytics\/azure-ai-textanalytics\/README.md\">Readme<\/a><\/li>\n<li>.NET <a href=\"https:\/\/azure.github.io\/azure-sdk-for-net\/textanalytics.html\">Reference Documentation<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/blob\/master\/sdk\/textanalytics\/Azure.AI.TextAnalytics\/README.md\">Readme<\/a><\/li>\n<li>JavaScript\/TypeScript <a href=\"https:\/\/azure.github.io\/azure-sdk-for-js\/textanalytics.html\">Reference Documentation<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/blob\/master\/sdk\/textanalytics\/ai-text-analytics\/README.md\">Readme<\/a><\/li>\n<li>Java <a href=\"https:\/\/azure.github.io\/azure-sdk-for-java\/textanalytics.html\">Reference Documentation<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/blob\/master\/sdk\/textanalytics\/azure-ai-textanalytics\/README.md\">Readme<\/a><\/li>\n<\/ul>\n<p><!-- FOOTER: DO NOT EDIT OR REMOVE --> <div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/azsdk\/releases\" target=\"_blank\">Azure SDK Releases<\/a><\/div><\/p>\n<h2>Azure SDK Blog Contributions<\/h2>\n<p>Thank you for reading this Azure SDK blog post! We hope that you learned something new and welcome you to share this post. We are open to Azure SDK blog contributions. Please contact us at <a href=\"&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x61;z&#115;&#x64;&#107;&#x62;&#108;&#x6f;&#103;&#x40;&#109;&#105;&#x63;&#114;&#x6f;&#115;&#x6f;&#102;&#x74;&#46;&#x63;o&#109;\">&#x61;z&#115;&#x64;&#107;&#x62;&#108;&#x6f;&#103;&#x40;&#109;&#105;&#x63;&#114;&#x6f;&#115;&#x6f;&#102;&#x74;&#46;&#x63;o&#109;<\/a> with your topic and we&#8217;ll get you setup as a guest blogger.<\/p>\n<h2>Azure SDK Links<\/h2>\n<ul>\n<li>Azure SDK Website: <a href=\"https:\/\/aka.ms\/azsdk\">aka.ms\/azsdk<\/a><\/li>\n<li>Azure SDK Intro (3 minute video): <a href=\"https:\/\/aka.ms\/azsdk\/intro\">aka.ms\/azsdk\/intro<\/a><\/li>\n<li>Azure SDK Intro Deck (PowerPoint deck): <a href=\"https:\/\/aka.ms\/azsdk\/intro\/deck\">aka.ms\/azsdk\/intro\/deck<\/a><\/li>\n<li>Azure SDK Releases: <a href=\"https:\/\/aka.ms\/azsdk\/releases\">aka.ms\/azsdk\/releases<\/a><\/li>\n<li>Azure SDK Blog: <a href=\"https:\/\/aka.ms\/azsdk\/blog\">aka.ms\/azsdk\/blog<\/a><\/li>\n<li>Azure SDK Twitter: <a href=\"https:\/\/twitter.com\/AzureSDK\">twitter.com\/AzureSDK<\/a><\/li>\n<li>Azure SDK Design Guidelines: <a href=\"https:\/\/aka.ms\/azsdk\/guide\">aka.ms\/azsdk\/guide<\/a><\/li>\n<li>Azure SDKs &amp; Tools: <a href=\"https:\/\/azure.microsoft.com\/downloads\">azure.microsoft.com\/downloads<\/a><\/li>\n<li>Azure SDK Central Repository: <a href=\"https:\/\/github.com\/azure\/azure-sdk#azure-sdk\">github.com\/azure\/azure-sdk<\/a><\/li>\n<li>Azure SDK for .NET: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-net\">github.com\/azure\/azure-sdk-for-net<\/a><\/li>\n<li>Azure SDK for Java: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-java\">github.com\/azure\/azure-sdk-for-java<\/a><\/li>\n<li>Azure SDK for Python: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-python\">github.com\/azure\/azure-sdk-for-python<\/a><\/li>\n<li>Azure SDK for JavaScript\/TypeScript: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-js\">github.com\/azure\/azure-sdk-for-js<\/a><\/li>\n<li>Azure SDK for Android: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-android\">github.com\/Azure\/azure-sdk-for-android<\/a><\/li>\n<li>Azure SDK for iOS: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-ios\">github.com\/Azure\/azure-sdk-for-ios<\/a><\/li>\n<li>Azure SDK for Go: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\">github.com\/Azure\/azure-sdk-for-go<\/a><\/li>\n<li>Azure SDK for C: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-c\">github.com\/Azure\/azure-sdk-for-c<\/a><\/li>\n<li>Azure SDK for C++: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-cpp\">github.com\/Azure\/azure-sdk-for-cpp<\/a><\/li>\n<\/ul>\n<p><!-- FOOTER: DO NOT EDIT OR REMOVE --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>See how to use the new opinion mining offering in our client libraries to get next-level sentiment analysis<\/p>\n","protected":false},"author":38537,"featured_media":679,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[754,750,755,752,753,751],"class_list":["post-542","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-aspectbasedsentimentanalysis","tag-azure-sdk","tag-naturallanguageprocessing","tag-opinionmining","tag-sentimentanalysis","tag-textanalytics"],"acf":[],"blog_post_summary":"<p>See how to use the new opinion mining offering in our client libraries to get next-level sentiment analysis<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/542","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/38537"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=542"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/542\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/679"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=542"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=542"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=542"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}