Now, in the last lesson, we managed to parse all of the tweets that we got back from our results JSON 1
into an array of tweets, 2
that is an array of strings. 3
Now, we want to be able to run our predictions on that array and get back an array of sentiment labels. 4
So instead of using this particular method, which can only take a single piece of text, we need to use 5
something else. 6
So down here, let's tap into our sentimentClassifier again and let's hit ".pre" just to see all of 7
the different prediction methods, 8
and there's only five of them. The one that we've already used is this first one that's just making a 9
prediction on a single piece of text. The next one is something that takes a TweetSentimentClassifier 10
input data type to make a prediction, or you can take an array of TweetSentimentClassifier inputs and 11
get an array of outputs back. 12
And this is making a batch prediction using the structured interface of the CoreML Natural Language 13
processes. 14
Now, we can also specify some options and these options if you read the API docs include whether if you 15
want to pick to use the CPU or the GPU to make this prediction 16
depending on how resource-intensive this whole process is going to be. And you can also do that for batch 17
processing as well. 18
Now, in our case, we're interested in this method where we can batch process all of our tweets through 19
our sentimentClassifier, so that's the one that I'm gonna put in here. 20
Now, it would be nice to be able to simply put our tweets array in here and get our sentiments back as 21
an array. But unfortunately, you can see we get a error here that says, cannot convert value of type String 22
array, which is what tweets is, to the expected type which is a TweetSentimentClassifierInput array. 23
In order for this to work, we have to change this tweet array from being an array of Strings to an array 24
of TweetSentimentClassifierInput objects. 25
So that's very easy to change. But then, we have a problem down here because we're trying to convert a 26
string that's a single tweet to an array that can only take TweetSentimentClassifierInput objects. 27
So in that case, we have to convert our tweet. 28
So let's say let tweetForClassification = tweetSentimentClassifierInput, we initialize it with 29
tweet which is a string. And then we append, instead of the tweet which is the string, we append our 30
tweetForClassification which is now in the right data type. And now, we fixed that problem. But we, of 31
course, get another problem. Always remember that Churchill once said that "Success is going from failure 32
to failure without loss of enthusiasm." 33
So that's exactly what we need to do when we're programming. In most cases, you're going from bug to bug 34
and error to error, 35
but let's try to not lose our enthusiasm. In this case, the reason is because the sentimentClassifier 36
can throw, but it's not marked with a "try" and the error is not handled. 37
Now, previously, we simply marked it with a forced "try" to just force this prediction to go through, but 38
that was because we were testing our code and we weren't expecting to keep that. 39
In fact, I'm going to delete it now. 40
But in this case, this is gonna be our working code, so I don't want to force the "try," I just want to use 41
a normal "try," but that means I have to hold it inside a "do" and "catch" block. Inside my "do" block, 42
I, of course, have my "try." And inside my "catch" block, I'm simply going to print 43
my error. 44
All right. 45
So, now we have one more error and that's because using this sentimentClassifier which, remember, is something 46
that has global scope inside the class, inside a closure or a callback. 47
Remember, you can tell when we're inside a closure or a callback with that in keyword. 48
And this entire part is the closure, then we have to mark this with a self. 49
So let's just click fix. 50
Now, the final warning we're getting is that we've gotten this thing, but we haven't really done anything 51
with it. 52
So let's do something with it. Let's store it inside a constant. Let's call it predictions. And let's go 53
ahead and print predictions at index zero .label, so just as what we did previously. We're tapping into 54
that label property of the prediction which, remember, is that positive, negative, or neutral. 55
So let's hit run and see what we get. 56
All right. 57
So the first tweet had a label of neutral. If we wanted to see the label for all of the predictions inside 58
this array of prediction, 59
then we, again, need to use a loop. 60
Let's delete this print statement, and instead, 61
let's write 62
a for prediction in predictions. 63
Print prediction, singular, .label. 64
Now, if you find that too similar, you can also just call this "pred," for "pred" in predictions. 65
Just make sure that you understand that this is the singular one and this is the array. 66
So, now we have all of our positive, neutral, or negative predictions for all hundred tweets that we have 67
processed. 68
So pretty neat, right? 69
Now, wouldn't it be nice to be able to tally this up as almost like a score? 70
So, say, if one of the tweets was marked as negative, then we subtract one from the score, but if it was 71
marked as positive, then we add one to the score. And if it's neutral, it doesn't affect the score, 72
and we see depending on what it is that we search for, say, @Apple or @CocaCola, we see what is the overall 73
sentiment over a hundred tweets. And we can do that by keeping score. 74
So let's create a local variable called sentimentScore and let's start it off at zero. 75
Now, instead of printing all of these prediction labels, we're going to say, let sentiment = 76
pred.label. And if the sentiment is equal to positive, then sentimentScore is plus equal 1. 77
So sentimentScore gets increased by 1. 78
Now else if the sentiment is equal to negative, then the sentimentScore gets minus equal 1. 79
So we subtract 1 from the score. And we can ignore the "else" case which is basically neutral. 80
We're not going to affect the score in that case. After this, all of this loop has gone through, 81
let's now print our sentimentScore. 82
Let's run this based off tweets that contain or mention @Apple that are English for 100 of them. 83
Let's see what we get. We get minus 15. 84
So overall, the sentiment over 100 tweets is a bit negative. 85
Now, let's try something else. 86
Let's try something like @Facebook. 87
How do people feel about Facebook given all of the controversy? 88
Interesting, minus 3. 89
So people dislike it less than Apple even. 90
Now, let's try this with a hashtag instead 91
maybe, something that we know people always write positive things about when they have a particular hashtag. 92
One of them is #blessed, right? 93
People say, "Oh, I have the best life. #blessed." 94
Something like that. 95
Let's see what the score is for that, just to make sure that our scoring and our sentiment analyze it 96
everything is actually working properly. 97
All right, great. 98
So that's great. For the tweets that have the #blessed, 99
we're getting a score of 36. 100
That's really, really positive. 101
And you can actually have fun here and try and play around with all sorts of different things. 102
Say, what happens when you try @Trump or @Obama or hashtag a particular stock symbol. 103
See what happens. 104
What is the overall sentiment? Instead of having to read through all of the tweets, try to gather the 105
sentiment. 106
You can actually do this automatically now using all of this code that we have written. Now in the next 107
lesson, we're going to be making some UI updates so that our app isn't just sitting there and we're doing 108
everything inside the debug console. 109
So for all of that and more, I'll see you on the next lesson.