MachineLearning with CoreML and Xamarin.iOS

In iOS 11, Apple introduced CoreML. CoreML makes it possible to do prediction on trained models locally on iOS devices. For image predictions I recommend you to read my earlier blog post, https://danielhindrikes.se/index.php/2018/07/05/using-machine-learning-for-image-classification-in-your-apps/. This blog post will focus on how to make prediction with text input.

If you don't have a model that you have trained yourself, you can try to search for a model on the internet. There are a couple of great collections of CoreML models out there.

The model that we will use in this post is from coreml.store and is a model for sentimental analysis of text.

The first thing we will do is to import the model to Visual Studio (for Mac). The model should be placed in the Resources folder oy the iOS-project. When we are importing a model, Visual Studio will generate code that we can use to use the model.

If we want, we can delete the code and write it ourselves. But I prefer to use the generated code. But with this model, we need to edit it a little bit because there is a naming conflict (Note that is always a risk that the code is regenerated and our changes will be overwritten, so we will keep changes in this file as small as possible). The conflict is in the GetPrediction method at the end of the file. I'm changing the name of the declared variable for SentimentPolarityInput to be sentimentPolarityInput instead of input.

public SentimentPolarityOutput GetPrediction (NSDictionary<NSObject, NSNumber> input, out NSError error)
{
     var sentimentPolarityInput = new SentimentPolarityInput (input);
 
     return GetPrediction (sentimentPolarityInput, out error);
}

Next step is to compile the model.

var assetPath = NSBundle.MainBundle.GetUrlForResource("SentimentPolarity", "mlmodel");
 
var compiledUrl = MLModel.CompileModel(assetPath, out var error);

With the URL for the compiled, we can create an instance of the class the was generated when we imported the model to Visual Studio.

var ml = SentimentPolarity.Create(assetPath, out var error);

Before we can do any prediction we need to prepare the data a little bit, that because of that the GetPrediction method needs an NSDictionary. In this case, it means a dictionary of all words in the text and how many times they occur in the text. If you downloading a model that someone else has created I recommend you to take a look if there is any sample code about how to use it. Sample projects are often written in Swift- or Objective-C but is often not a problem to figure out what they are doing with the model.

What we will do here is to split the text by whitespace, we will also ignore all words that are just two characters or shorter. This because those words will probarly not affect thre result.

 
var dictionary = new Dictionary<NSObject, NSNumber>();
 
var words = text.Split(' ');
 
foreach (var word in words)
{
     if (word.Length > 2)
     {
          var token = NSObject.FromObject(word);
 
          if (dictionary.ContainsKey(token))
          {
               dictionary[token] = NSNumber.FromDouble(dictionary[token].DoubleValue + 1.0);
          }
          else
          {
               dictionary.Add(token, 1.0);
          }
     }
}
 
var data = new NSDictionary<NSObject, NSNumber>(dictionary.Keys.ToArray(), dictionary.Values.ToArray());

Now when we have prepared the data we are ready to do predictions.

var result = ml.GetPrediction(new SentimentPolarityInput(data), out var predictionError);
var positiveScore = (NSNumber)result.ClassProbability["Pos"];
var negativeScore = (NSNumber)result.ClassProbability["Neg"];
 
if(postiveScore > negativeScore)
{
    Console.WriteLine("The text is positive");
}
else
{
    Console.WriteLine("The text is negative");
}

Now we now we knwo the basic about how to use CoreML in an Xamarin.iOS app and we can start to build smarter apps based on machine learning!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.