Product

Text Analysis and C#: Getting Started with AYLIEN Text Analysis API and C#

This edition, the 5th in the series, of our “Getting up and running with AYLIEN Text Analysis API” will focus on working with the API using C#. Previously we published code snippets and getting started guides for node.js, Powershell, Python, Java and Ruby.

As we did in our previous blogs, we’re going to perform some basic Text Analysis like detecting what language a piece of text is written in, analyzing the sentiment of a piece of text, classifying an article and finally generating some hashtags for a URL. The idea here is to make it as easy as possible for developers to get up and running with our API and to showcase how easy it is to get started in your chosen language.

We’re first going to look at the code in action. We’ll then go through the code, section by section, to investigate each of the endpoints used in the code snippet.

What are we going to do?:

  • Detect what language the following text is written in: “What language is this sentence written in?”
  • Analyze the sentiment of the following statement: “John is a very good football player!”
  • Generate a classification (IPTC Code and label) for the URL: “http://www.bbc.com/earth/story/20141110-earths-magnetic-field-flips-more”
  • Generate hashtags for the URL: “http://www.bbc.com/earth/story/20141110-earths-magnetic-field-flips-more”

Note: The getting started page on our website has a range of code snippets in other programming languages you can use if you would prefer not to use C#.

Overview of the code in action

The complete code snippet is given at the end of this blog for you to copy and paste. To get it running, open a text editor of your choice and copy and paste the snippet. Before running the code, make sure you replace the YOUR_APP_ID and YOUR_APP_KEY placeholders in the code with your own application id and application key. You would have been sent these when you signed up as an API user. If you haven’t signed up you can make your way to our sign up page to register for free.

Save the file as TextAPISample.cs and open a developer command prompt. Navigate to the folder where you saved the code snippet and compile the code by typing “csc TextAPISample.cs”. You can now run the executable by typing TextAPISample at the command prompt.

Once you run it, you should receive the following output:


C:srcGettingStarted>TextAPISample


Text     : What Language is this sentence written in?
Language : en (0.9999971593789524)


Text     : John is a very good football player!
Sentiment: positive (0.9999988272764874)


Classification:

Label        :   natural science - geology
IPTC code    :   13004001
Confidence   :   1.0


Hashtags:

#EarthsMagneticField
#RockMusic
#SantaCruzCalifornia
#Lava
#California
#Earth
#Convection
#Iron
#Helsinki
#SpaceColonization
#HistoryOfTheEarth
#Granite
#Finland
#DynamoTheory
#Compass
#SouthMagneticPole
#Hematite
#SolarRadiation

In this case we have detected that the first piece of text is written in English and the sentiment or polarity of the second statement is positive. We have also generated hashtags for the URL and classified the content.

Next, we’ll go through the code snippet, section by section.

Language Detection

Using the Language Detection endpoint you can analyze a piece of text or a URL and automatically determine what language it is written in. In the piece of code we have used in this blog, the “parameter” variable controls whether the call is made specifying the text directly or as a URL.


parameters.text = "What Language is this sentence written in?";
var language = CallApi("language", parameters);

In this case we have specified that, we want to analyze the following text “What language is this sentence written in?” and as you can see from the output below, it determined that the text is written in English and it gave a 0.999993 confidence score that the language was detected correctly. For all of the endpoints, the API returns the text which was analyzed for reference and we have included it in the results in each case.

Result:


Text     : What Language is this sentence written in?
Language : en (0.999997599332592)

Sentiment Analysis

Similarly, the Sentiment Analysis endpoint takes a piece of text or a URL and analyzes it to determine whether it is positive, negative or even neutral it also provides a confidence score in the results.


parameters.text = "John is a very good football player!";
var sentiment = CallApi("sentiment", parameters);

Analyzing the following text; “John is a very good football player!”. The API has determined that the sentiment of the piece of text is positive, we can also be pretty sure it’s correct based on the confidence score returned of 0.999998.

Result:


Text     : John is a very good football player!
Sentiment: positive (0.9999988272764874)

Hashtag Suggestions

The Hashtag Suggestion endpoint, analyses a URL and generates a list of hashtag suggestions which can be used to ensure that your content or URL’s are optimally shared on social media:


parameters.url = "http://www.bbc.com/earth/story/20141110-earths-magnetic-field-flips-more";
var hashtags = CallApi("hashtags", parameters);

For hashtag suggestions, we have used an article about changes in the orientation of the Earth’s magnetic field published on the BBC news website “http://www.bbc.com/earth/story/20141110-earths-magnetic-field-flips-more”. The hashtag suggestion endpoint first extracts the text from the URL and then analyzes that text and generates hashtag suggestions for it.

Result:


Hashtags:
#EarthsMagneticField
#RockMusic
#SantaCruzCalifornia
#Lava
#California
#Earth
#Convection
#Iron
#Helsinki
#SpaceColonization
#HistoryOfTheEarth
#Granite
#Finland
#DynamoTheory
#Compass
#SouthMagneticPole
#Hematite
#SolarRadiation

Article Classification

The classification endpoint automatically assigns or tags an article or piece of text to one or more categories making it easier to manage and sort. The classification endpoint is based on IPTC International Subject News Codes and can identify up to 500 categories.


parameters.url = "http://www.bbc.com/earth/story/20141110-earths-magnetic-field-flips-more";
var classify = CallApi("classify", parameters);

When we analyze the url pointing to the BBC news story, we receive the results as shown below. As you can see it has labelled the article as “natural science- geology” with a corresponding IPTC code of 13004001 and a confidence of 1.

Result:


Classification:

Label        :   natural science - geology
IPTC code    :   13004001
Confidence   :   1.0

For more getting started guides and code snippets to help you get up and running with our API, visit our getting started page on our website. If you haven’t already done so you can get free access to our API on our sign up page.

The Complete Code Snippet


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;

namespace AylienTextAPI
{
    class Program
    {
        static void Main(string[] args)
        {
            var url = "http://www.bbc.com/earth/story/20141110-earths-magnetic-field-flips-more";
            string[] endpoints = new string[] {"language", "sentiment", "classify", "hashtags"};

foreach(var endpoint in endpoints){
  switch(endpoint){
    case "language":
    {
      dynamic parameters = new System.Dynamic.ExpandoObject();
      parameters.text = "What Language is this sentence written in?";
      var language = CallApi("language", parameters);
      Console.WriteLine("nText     : {0}", language["text"] );
      Console.WriteLine("Language : {0} ({1})",
      language["lang"], language["confidence"]);
      break;
    }
    case "sentiment":{
      dynamic parameters = new System.Dynamic.ExpandoObject();
      parameters.text = "John is a very good football player!";
      var sentiment = CallApi("sentiment", parameters);
      Console.WriteLine("nText     : {0}", sentiment["text"] );
      Console.WriteLine("Sentiment: {0} ({1})",
      sentiment["polarity"], sentiment["polarity_confidence"]);
      break;
    }
    case "classify": {
      dynamic parameters = new System.Dynamic.ExpandoObject();
      parameters.url = url;
      var classify = CallApi("classify", parameters);
      Console.Write("nClassification: n");
      foreach(var item in classify["categories"])
      {
          Console.WriteLine("Label        :   {0}     ", item["label"].ToString());
          Console.WriteLine("IPTC code    :   {0}     ", item["code"].ToString());
          Console.WriteLine("Confidence   :   {0}     ", item["confidence"].ToString());
      }
      break;
    }
    case "hashtags":{
      dynamic parameters = new System.Dynamic.ExpandoObject();
      parameters.url = url;
      var hashtags = CallApi("hashtags", parameters);
      Console.Write("nHashtags: n");
      foreach(var item in hashtags["hashtags"])
      {
          Console.WriteLine(item.ToString());
      }
      break;
    }
  }
}
        }

        private static dynamic CallApi(String endpoint, dynamic parameters)
        {
            String APPLICATION_ID = YOUR_APPLICATION_ID;
            String APPLICATION_KEY = YOUR_APPLICATION_KEY;
            Uri address = new Uri("https://api.aylien.com/api/v1/" +
                endpoint);

            // Create the web request
            HttpWebRequest request = WebRequest.Create(address) as
                HttpWebRequest;

            // Set type to POST
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            // Create the data we want to send
            StringBuilder data = new StringBuilder();
            var i = 0;
            foreach (var item in parameters)
            {
                if (i == 0)
                    data.Append(item.Key + "=" +
                        HttpUtility.UrlEncode(item.Value));
                else
                    data.Append("&" + item.Key + "=" +
                        HttpUtility.UrlEncode(item.Value));

                i++;
            }

            // Create a byte array of the data we want to send
            byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());

            // Set the content length in the request headers
            request.ContentLength = byteData.Length;
            request.Accept = "application/json";
            request.Headers.Add("X-AYLIEN-TextAPI-Application-ID",
                APPLICATION_ID);
            request.Headers.Add("X-AYLIEN-TextAPI-Application-Key",
                APPLICATION_KEY);

            // Write data
            using (Stream postStream = request.GetRequestStream())
            {
                postStream.Write(byteData, 0, byteData.Length);
            }

            // Get response
            using (HttpWebResponse response = request.GetResponse()
                as HttpWebResponse)
            {
                // Get the response stream
                StreamReader reader =
                    new StreamReader(response.GetResponseStream());

                // Serialize to JSON dynamic object
                var serializer = new JavaScriptSerializer();
                return serializer.Deserialize(reader.ReadToEnd(),
                    typeof(object));
            }
        }
    }

    // http://stackoverflow.com/a/3806407/1455811
    public sealed class DynamicJsonConverter : JavaScriptConverter
    {
        public override object Deserialize(IDictionary
            dictionary,
            Type type, JavaScriptSerializer serializer)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");

            return type == typeof(object) ?
                new DynamicJsonObject(dictionary) : null;
        }

        public override IDictionary
            Serialize(object obj, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override IEnumerable SupportedTypes
        {
            get { return new ReadOnlyCollection
                (new List(new[] { typeof(object) })); }
        }

        #region Nested type: DynamicJsonObject

        private sealed class DynamicJsonObject : DynamicObject
        {
            private readonly IDictionary _dictionary;

            public DynamicJsonObject(IDictionary dictionary)
            {
                if (dictionary == null)
                    throw new ArgumentNullException("dictionary");
                _dictionary = dictionary;
            }

            public override string ToString()
            {
                var sb = new StringBuilder("{");
                ToString(sb);
                return sb.ToString();
            }

            private void ToString(StringBuilder sb)
            {
                var firstInDictionary = true;
                foreach (var pair in _dictionary)
                {
                    if (!firstInDictionary)
                        sb.Append(",");
                    firstInDictionary = false;
                    var value = pair.Value;
                    var name = pair.Key;
                    if (value is string)
                    {
                        sb.AppendFormat("{0}:"{1}"", name, value);
                    }
                    else if (value is IDictionary)
                    {
                        new DynamicJsonObject((IDictionary)
                            value).ToString(sb);
                    }
                    else if (value is ArrayList)
                    {
                        sb.Append(name + ":[");
                        var firstInArray = true;
                        foreach (var arrayValue in (ArrayList)value)
                        {
                            if (!firstInArray)
                                sb.Append(",");
                            firstInArray = false;
                            if (arrayValue is IDictionary)
                                new DynamicJsonObject(
                                    (IDictionary)
                                    arrayValue).ToString(sb);
                            else if (arrayValue is string)
                                sb.AppendFormat(""{0}"", arrayValue);
                            else
                                sb.AppendFormat("{0}", arrayValue);

                        }
                        sb.Append("]");
                    }
                    else
                    {
                        sb.AppendFormat("{0}:{1}", name, value);
                    }
                }
                sb.Append("}");
            }

            public override bool TryGetMember(GetMemberBinder binder,
                out object result)
            {
                if (!_dictionary.TryGetValue(binder.Name, out result))
                {
                    // return null to avoid exception.
                    // caller can check for null this way...
                    result = null;
                    return true;
                }

                result = WrapResultObject(result);
                return true;
            }

            public override bool TryGetIndex(GetIndexBinder binder,
                object[] indexes, out object result)
            {
                if (indexes.Length == 1 && indexes[0] != null)
                {
                    if (!_dictionary.TryGetValue(indexes[0].ToString(),
                        out result))
                    {
                        // return null to avoid exception.
                        // caller can check for null this way...
                        result = null;
                        return true;
                    }

                    result = WrapResultObject(result);
                    return true;
                }

                return base.TryGetIndex(binder, indexes, out result);
            }

            private static object WrapResultObject(object result)
            {
                var dictionary = result as IDictionary;
                if (dictionary != null)
                    return new DynamicJsonObject(dictionary);

                var arrayList = result as ArrayList;
                if (arrayList != null && arrayList.Count > 0)
                {
                    return arrayList[0] is IDictionary
                        ? new List(
                            arrayList.Cast>()
                            .Select(x => new DynamicJsonObject(x)))
                        : new List(arrayList.Cast());
                }

                return result;
            }
        }

        #endregion
    }
}



$(function(){
  $('.prettyprint:last').tooltip({title:'Click to expand!', trigger:'hover'});
  $('.prettyprint:last').on('click', function() {
    $(this).css({height: '100%', cursor: 'default'}).tooltip('destroy');
  });
});





Text Analysis API - Sign up




Author


Avatar

Mike Waldron

Head of Marketing & Sales @ AYLIEN A legal convert with a masters degree from Smurfit Business School, Mike runs our Sales and Marketing at AYLIEN. Mike gathered his Sales and Marketing experience with technology companies in Sydney and Dublin before getting the startup itch and joining the team at AYLIEN. Twitter: @MikeWallly