The Natural Language framework has excellent features to analyze text with. Bundled with the power of machine learning models, you can perform some powerful operations on text. Apple has spent a lot of time training several models with vast amounts of data to ensure that the natural language framework can detect names, places, and more.
However, sometimes you might want to add your own analysis tools. To facilitate this, Natural Language works well with CoreML and Apple's new CreateML framework. With CreateML, you can easily and quickly create your own machine learning models that you can use in your apps straight away.
You can use several different types of training for a Natural Language model. In this section, you will learn about two different models:
- A text classifier
- A word tagger
The text classifier will classify a particular piece of text with a label. This is similar to the sentiment analysis you have implemented in the TextAnalyzer sample app. An example of an entry in your training data would look as follows:
{ "text": "We took an exclusive ride in a flying car", "label": "Tech" }
This is a sample of a news article headline that belongs in a category labeled Tech. When you feed a large number of samples like this to your model, you could end up with a classifier that can apply labels to news articles based on their headlines. Of course, this assumes that the headlines are specific enough and contain enough information to train the classifier properly. In reality, you will find that short sentences like these will not make the best models. The sample Playground contains a JSON file with training data that attempts to separate news articles into two categories; politics and tech. Let's see how the model can be trained so you can then see for yourself how accurate the model is.
The following code trains and stores the custom CoreML model:
import CreateML import Foundation let trainingData = try! MLDataTable(contentsOf: Bundle.main.url(forResource: "texts", withExtension: "json")!) let model = try! MLTextClassifier(trainingData: trainingData, textColumn: "text", labelColumn: "label") try! model.write(to: URL(fileURLWithPath: "/path/to/folder/TextClassifier.mlmodel"))
Training the entire model requires only a couple of lines of code. All you need to do is obtain your training data, create the classifier, and save it somewhere on your machine. You can even do some quick testing to see whether your model works well, right inside of the playground. Note that the preceding code uses a try! statement. This is done to keep the code sample brief and simple. In your own apps, you should always strive for proper error handling to avoid surprising crashes.
The string that is passed to the URL(fileURLWithPath:) initializer, represents the location where your model will be stored. Make sure to specify the full path here, so, for instance, use /Users/donnywals/Desktop/TextClassifier.mlmodel, and not ~/Desktop/TextClassifier.mlmodel.
The following lines of code test two different headlines to see if the model correctly labels them:
let techHeadline = try! model.prediction(from: "Snap users drop for first time, but revenue climbs") let politicsHeadline = try! model.prediction(from: "Spike Lee says President Donald Trump is a 'bullhorn' for racism")
If you're happy with the results of your model, you can grab the trained model from the place where you saved it, and immediately add it to your Xcode project. From there, you can use the model like you would use any other model.
Let's see another example of a Natural Language model. In this case, the model should label every word in a text to classify it as a certain type of word. For instance, you could train the model to recognize certain brand names, product names, or other words that have special meanings to your app. An example of training data that you could use to train a model like this is the following:
{ "tokens": ["Apple", "announced", "iOS 12", "and", "Xcode 10", "at", "WWDC 2018"], "labels": ["COMPANY", "NONE", "OPERATING_SYSTEM", "NONE", "SOFTWARE", "NONE", "EVENT"] }
By collecting many samples that include the words that you want to label, your model will be able to not only match tags based on the word itself, but even on the surrounding words. Essentially, the model would be aware of the context in which each word is used to then determine the correct tag. Once you have collected enough sample data, you can train the model in a similar way as the classifier:
let labelTrainingData = try! MLDataTable(contentsOf: Bundle.main.url(forResource: "labels", withExtension: "json")!) let model = try! MLWordTagger(trainingData: labelTrainingData, tokenColumn: "tokens", labelColumn: "labels") try! model.write(to: URL(fileURLWithPath: "path/to/folder/TextTagger.mlmodel"))
The amount of code to train the model hasn't changed. The only difference is that the previous model was based on the MLTextClassifier class, and the current model is based on the MLWordTagger. Again, you can immediately use the trained model to make some predictions that you can then use to validate whether the model was trained properly. Providing good data and testing often are the keys to building a great CoreML model.
In addition to text analysis models, CreateML can also help you to train your own image recognition models. Let's see how this works next.