Movie Review (Sentiment Analysis) - Jupyter Notebook¶
This is the static (html) version of the notebook for the tutorial “Movie Review - Classic Workflow”.
(the orginal notebook file, “movie_review.ipynb”, can be found here, and an interactive online version here)
Before we begin, let’s import needed modules…
from pyss3 import SS3
from pyss3.util import Dataset
from pyss3.server import Server
from sklearn.metrics import accuracy_score
… and unzip the “movie_review.zip” dataset inside the datasets
folder.
!unzip -u datasets/movie_review.zip -d datasets/
Ok, now we are ready to begin. Let’s create a new SS3 instance
clf = SS3()
What are the default hyperparameter values? let’s see
s, l, p, _ = clf.get_hyperparameters()
print("Smoothness(s):", s)
print("Significance(l):", l)
print("Sanction(p):", p)
Smoothness(s): 0.45
Significance(l): 0.5
Sanction(p): 1
Ok, now let’s load the training and the test set using the
load_from_files
function from pyss3.util
as follow:
x_train, y_train = Dataset.load_from_files("datasets/movie_review/train")
x_test, y_test = Dataset.load_from_files("datasets/movie_review/test")
Let’s train our model…
clf.fit(x_train, y_train)
Training: 100%|██████████| 2/2 [00:13<00:00, 6.51s/it]
Note that we don’t have to create any document-term matrix! we are using
just the plain x_train
documents :D cool uh? (SS3 creates a language
model for each category and therefore it doesn’t need to create any
document-term matrices)
Now that the model has been trained, let’s test it using the documents
in x_test
y_pred = clf.predict(x_test)
Classification: 100%|██████████| 1000/1000 [00:04<00:00, 200.12it/s]
Let’s see how good our model performed
print("Accuracy:", accuracy_score(y_pred, y_test))
Accuracy: 0.852
Not bad using the default hyperparameter values, let’s now manually analyze what our model has actually learned by using the interactive “live test”.
Server.serve(clf, x_test, y_test)
Makes sense to you? (remember you can select “words” as the Description Level if you want to know based on what words is making classification decisions)
Live test doesn’t look bad, however, we will create a “more intelligent”
version of this model, a version that can recognize variable-length word
n-grams “on the fly”. Thus, when calling the fit
we will pass an
extra argument n_grams=3
to indicate we want SS3 to learn to
recognize important words, bigrams, and 3-grams [*]. Additionally, we will name our model “movie_review_3grams” so that we can save it and load it later from the PySS3 Command Line
to perform
the hyperparameter optimization to find better hyperparameter values.
[*] If you’re curious and want to know how this is actually done by SS3, read the paper “t-SS3: a text classifier with dynamic n-grams for early risk detection over text streams” (preprint available here).
clf = SS3(name="movie_review_3grams")
clf.fit(x_train, y_train, n_grams=3) # <-- note the n_grams=3 argument here
Training: 100%|██████████| 2/2 [00:19<00:00, 10.00s/it]
As mentioned above, we will save this trained model for later use.
clf.save_model()
[ saving model (ss3_models/movie_review_3grams.ss3m)... ]
Now let’s see if the performance has improved…
y_pred = clf.predict(x_test)
Classification: 100%|██████████| 1000/1000 [00:05<00:00, 195.64it/s]
print("Accuracy:", accuracy_score(y_pred, y_test))
Accuracy: 0.855
Yeah, the accuracy slightly improved but more importantly, we should now see that the model has learned “more intelligent patterns” involving sequences of words when using the interactive “live test” (like “was supposed to”, “has nothing to”, “low budget”, “your money”, etc. for the “negative” class). Let’s see…
Server.serve(clf, x_test, y_test)
Before moving forward, at this point you should read the Hyperparameter Optimization section of this tutorial.
As described in the “Hyperparameter Optimization” section, after performing hyperparameter
optimization using the PySS3 Command Line
, we found out that, for
example, the following hyperparameter values will slightly improve our
classification performance
clf.set_hyperparameters(s=.44, l=.48, p=1.1)
Let’s see if it’s true…
y_pred = clf.predict(x_test)
Classification: 100%|██████████| 1000/1000 [00:06<00:00, 148.17it/s]
print("Accuracy:", accuracy_score(y_pred, y_test))
Accuracy: 0.861
Great! accuracy improved. Fortunately, this time we got lucky and the default hyperparameters were also quite good.