scikit-learn/doc/tutorial/text_analytics/solutions/exercise_02_sentiment.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

80 lines
3.1 KiB
Python
Raw Normal View History

"""Build a sentiment analysis / polarity model
Sentiment analysis can be casted as a binary text classification problem,
that is fitting a linear classifier on features extracted from the text
2020-01-28 09:52:17 +08:00
of the user messages so as to guess whether the opinion of the author is
positive or negative.
In this examples we will use a movie review dataset.
"""
2011-03-10 15:22:25 +08:00
# Author: Olivier Grisel <olivier.grisel@ensta.org>
# License: Simplified BSD
import sys
2014-01-10 21:56:10 +08:00
from sklearn.feature_extraction.text import TfidfVectorizer
2012-02-13 16:39:55 +08:00
from sklearn.svm import LinearSVC
2011-09-19 17:46:58 +08:00
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
2011-09-19 17:46:58 +08:00
from sklearn.datasets import load_files
from sklearn.model_selection import train_test_split
2011-09-19 17:46:58 +08:00
from sklearn import metrics
2011-03-10 15:22:25 +08:00
if __name__ == "__main__":
# NOTE: we put the following in a 'if __name__ == "__main__"' protected
# block to be able to use a multi-core grid search that also works under
2011-09-20 22:35:34 +08:00
# Windows, see: http://docs.python.org/library/multiprocessing.html#windows
# The multiprocessing module is used as the backend of joblib.Parallel
# that is used when n_jobs != 1 in GridSearchCV
2011-03-10 15:22:25 +08:00
# the training data folder must be passed as first argument
movie_reviews_data_folder = sys.argv[1]
2012-02-13 16:39:55 +08:00
dataset = load_files(movie_reviews_data_folder, shuffle=False)
2014-01-10 21:56:10 +08:00
print("n_samples: %d" % len(dataset.data))
2011-03-10 15:22:25 +08:00
# split the dataset in training and test set:
2012-02-13 16:39:55 +08:00
docs_train, docs_test, y_train, y_test = train_test_split(
2014-01-10 21:56:10 +08:00
dataset.data, dataset.target, test_size=0.25, random_state=None)
2011-03-10 15:22:25 +08:00
2014-01-10 21:56:10 +08:00
# TASK: Build a vectorizer / classifier pipeline that filters out tokens
# that are too rare or too frequent
pipeline = Pipeline([
2014-01-10 21:56:10 +08:00
('vect', TfidfVectorizer(min_df=3, max_df=0.95)),
('clf', LinearSVC(C=1000)),
])
2011-03-10 15:22:25 +08:00
# TASK: Build a grid search to find out whether unigrams or bigrams are
# more useful.
# Fit the pipeline on the training set using grid search for the parameters
2014-01-10 21:56:10 +08:00
parameters = {
'vect__ngram_range': [(1, 1), (1, 2)],
}
grid_search = GridSearchCV(pipeline, parameters, n_jobs=-1)
2014-01-10 21:56:10 +08:00
grid_search.fit(docs_train, y_train)
# TASK: print the mean and std for each candidate along with the parameter
# settings for all the candidates explored by grid search.
n_candidates = len(grid_search.cv_results_['params'])
for i in range(n_candidates):
print(i, 'params - %s; mean - %0.2f; std - %0.2f'
% (grid_search.cv_results_['params'][i],
grid_search.cv_results_['mean_test_score'][i],
grid_search.cv_results_['std_test_score'][i]))
2011-03-10 15:22:25 +08:00
2014-01-10 21:56:10 +08:00
# TASK: Predict the outcome on the testing set and store it in a variable
# named y_predicted
y_predicted = grid_search.predict(docs_test)
2011-03-10 15:22:25 +08:00
# Print the classification report
2014-01-10 21:56:10 +08:00
print(metrics.classification_report(y_test, y_predicted,
target_names=dataset.target_names))
2011-03-10 15:22:25 +08:00
2014-01-10 21:56:10 +08:00
# Print and plot the confusion matrix
cm = metrics.confusion_matrix(y_test, y_predicted)
2014-01-10 21:56:10 +08:00
print(cm)
2011-03-10 15:22:25 +08:00
2014-01-10 21:56:10 +08:00
# import matplotlib.pyplot as plt
# plt.matshow(cm)
# plt.show()