text_lab3
.pdfОтчет по лабораторной работе № 3
по дисциплине «Основы анализа текстовых данных»
на тему: «Классификация текстовых данных»
Цель работы:
Получить практические навыки решения задачи классификации текстовых данных в среде Jupiter Notebook (Эта лабораторная выполнялась в среде Google Colab). Научиться проводить предварительную обработку текстовых данных, настраивать параметры методов классификации и обучать модели, оценивать точность полученных моделей.
1. Загрузим выборки по варианту из лабораторной работы № 2.
Импортируем необходимые библиотеки:
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB from sklearn.tree import DecisionTreeClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report from sklearn.model_selection import GridSearchCV
Загрузим обучающую и тестовую выборки:
categories = ['misc.forsale', 'sci.med', 'talk.religion.misc'] remove = ('headers', 'footers', 'quotes')
twenty_train = fetch_20newsgroups(subset='train', shuffle=True, random_state=42, categories = categories, remove = remove )
twenty_test = fetch_20newsgroups(subset='test', shuffle=True, random_state=42, categories = categories, remove = remove )
Получим обучающую и тестовую выборки со стеммингом: import nltk
from nltk.stem import PorterStemmer from nltk.tokenize import word_tokenize from tqdm import tqdm
ps = PorterStemmer()
def stemming(text: str) -> str: words = []
for word in word_tokenize(text): words.append(ps.stem(word.lower()))
return ' '.join(words)
def stemming_dataset(dataset: list) -> list: resulting_list = []
for example in tqdm(dataset): resulting_list.append(stemming(example))
return resulting_list
stem_train = fetch_20newsgroups(subset='train', shuffle=True, random_state=42, categories = categories, remove = remove )
stem_test = fetch_20newsgroups(subset='test', shuffle=True, random_state=42, cat egories = categories, remove = remove )
nltk.download('punkt')
stem_train['data_stem'] = stemming_dataset(stem_train['data']) stem_test['data_stem'] = stemming_dataset(stem_test['data'])
del stem_train['data'] del stem_test['data']
2. Используя GridSearchCV, произведем предварительную обработку данных и настройку методов классификации, выведем оптимальные значения параметров и результаты классификации модели с данными параметрами.
1) Обработка данных без стемминга мультиномиальным наивным байесовским методом
(MNB):
parameters = {'vect__max_features': (100,500,1000,5000,10000), 'vect__stop_words': ('english', None), 'tfidf__use_idf': (True, False),
'clf__alpha': (0.1,1,2)}
text_clf = Pipeline([('vect', CountVectorizer(max_features= 10000,stop_words = 'english')),
('tfidf', TfidfTransformer(use_idf = True)), ('clf', MultinomialNB ()),])
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=3) gs_clf = gs_clf.fit(twenty_train.data, twenty_train.target)
Наилучшие параметры:
gs_clf.best_params_ {'clf__alpha': 0.1, 'tfidf__use_idf': True, 'vect__max_features': 10000, 'vect__stop_words': 'english'}
prediction = gs_clf.best_estimator_.predict(twenty_test.data) print(classification_report(twenty_test.target, prediction))
|
precision |
recall |
f1-score |
support |
0 |
0.95 |
0.95 |
0.95 |
390 |
1 |
0.87 |
0.93 |
0.90 |
396 |
2 |
0.89 |
0.80 |
0.84 |
251 |
accuracy |
|
|
0.90 |
1037 |
2
macro |
avg |
0.90 |
0.89 |
0.90 |
1037 |
weighted |
avg |
0.91 |
0.90 |
0.90 |
1037 |
2) Обработка данных со стеммингом методом MNB:
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=3) gs_clf = gs_clf.fit(stem_train.data_stem, stem_train.target)
Наилучшие параметры:
gs_clf.best_params_ {'clf__alpha': 0.1, 'tfidf__use_idf': True, 'vect__max_features': 10000, 'vect__stop_words': 'english'}
prediction = gs_clf.best_estimator_.predict(stem_test.data_stem) print(classification_report(stem_test.target, prediction))
|
precision |
recall |
f1-score |
support |
0 |
0.96 |
0.94 |
0.95 |
390 |
1 |
0.88 |
0.93 |
0.90 |
396 |
2 |
0.90 |
0.83 |
0.86 |
251 |
accuracy |
0.91 |
0.90 |
0.91 |
1037 |
macro avg |
0.91 |
1037 |
||
weighted avg |
0.91 |
0.91 |
0.91 |
1037 |
3) Обработка данных без стемминга методом «Дерево решений» (DT):
text_clf = Pipeline([('vect', CountVectorizer(max_features= 10000,stop_words = 'english')),
('tfidf', TfidfTransformer(use_idf = True)),
('clf', DecisionTreeClassifier (criterion='gini',max_depth=1)),])
parameters = {'vect__max_features': (100,500,1000,5000,10000), 'vect__stop_words': ('english', None), 'tfidf__use_idf': (True, False), 'clf__max_depth': (1,2,3,4,5,20,40,60,80,100), 'clf__criterion': ('gini','entropy')}
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=3) gs_clf = gs_clf.fit(twenty_train.data, twenty_train.target)
Наилучшие параметры:
gs_clf.best_params_ {'clf__criterion': 'gini', 'clf__max_depth': 60, 'tfidf__use_idf': False, 'vect__max_features': 500, 'vect__stop_words': 'english'}
3
prediction = gs_clf.best_estimator_.predict(twenty_test.data) print(classification_report(twenty_test.target, prediction))
|
precision |
recall |
f1-score |
support |
0 |
0.83 |
0.82 |
0.82 |
390 |
1 |
0.65 |
0.75 |
0.70 |
396 |
2 |
0.71 |
0.55 |
0.62 |
251 |
accuracy |
0.73 |
0.71 |
0.73 |
1037 |
macro avg |
0.71 |
1037 |
||
weighted avg |
0.73 |
0.73 |
0.73 |
1037 |
4) Обработка данных со стеммингом методом DT:
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=3) gs_clf = gs_clf.fit(stem_train.data_stem, stem_train.target)
Наилучшие параметры:
gs_clf.best_params_ {'clf__criterion': 'entropy', 'clf__max_depth': 40, 'tfidf__use_idf': False, 'vect__max_features': 10000, 'vect__stop_words': 'english'}
prediction = gs_clf.best_estimator_.predict(stem_test.data_stem) print(classification_report(stem_test.target, prediction))
|
precision |
recall |
f1-score |
support |
0 |
0.89 |
0.80 |
0.84 |
390 |
1 |
0.84 |
0.62 |
0.71 |
396 |
2 |
0.53 |
0.84 |
0.65 |
251 |
accuracy |
0.76 |
0.75 |
0.74 |
1037 |
macro avg |
0.74 |
1037 |
||
weighted avg |
0.79 |
0.74 |
0.75 |
1037 |
5) Обработка данных без стемминга методом К-ближайших соседей (KNN):
text_clf = Pipeline([('vect', CountVectorizer(max_features= 10000,stop_words = 'english')),
('tfidf', TfidfTransformer(use_idf = True)), ('clf', KNeighborsClassifier (n_neighbors=1)),])
parameters = {'vect__max_features': (100,500,1000,5000,10000), 'vect__stop_words': ('english', None), 'tfidf__use_idf': (True, False),
4
'clf__n_neighbors': (1,3,5,7), 'clf__metric': ('euclidean','manhattan')}
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=3) gs_clf = gs_clf.fit(twenty_train.data, twenty_train.target)
Наилучшие параметры:
gs_clf.best_params_ {'clf__metric': 'euclidean', 'clf__n_neighbors': 7, 'tfidf__use_idf': True, 'vect__max_features': 100, 'vect__stop_words': 'english'}
prediction = gs_clf.best_estimator_.predict(twenty_test.data) print(classification_report(twenty_test.target, prediction))
|
precision |
recall |
f1-score |
support |
0 |
0.78 |
0.77 |
0.77 |
390 |
1 |
0.63 |
0.68 |
0.65 |
396 |
2 |
0.62 |
0.56 |
0.59 |
251 |
accuracy |
0.68 |
0.67 |
0.68 |
1037 |
macro avg |
0.67 |
1037 |
||
weighted avg |
0.68 |
0.68 |
0.68 |
1037 |
6) Обработка данных со стеммингом методом KNN:
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=3) gs_clf = gs_clf.fit(stem_train.data_stem, stem_train.target)
Наилучшие параметры:
gs_clf.best_params_ {'clf__metric': 'euclidean', 'clf__n_neighbors': 1, 'tfidf__use_idf': True, 'vect__max_features': 100, 'vect__stop_words': 'english'}
prediction = gs_clf.best_estimator_.predict(stem_test.data_stem) print(classification_report(stem_test.target, prediction))
|
precision |
recall |
f1-score |
support |
0 |
0.81 |
0.80 |
0.80 |
390 |
1 |
0.71 |
0.71 |
0.71 |
396 |
2 |
0.62 |
0.63 |
0.63 |
251 |
accuracy |
0.71 |
0.71 |
0.72 |
1037 |
macro avg |
0.71 |
1037 |
||
weighted avg |
0.72 |
0.72 |
0.72 |
1037 |
5
3. Сравнительная таблица с результатами классификации различными методами с разными настройками:
|
|
|
Precision |
Recall |
F1-score |
|||
Классификатор |
Стемминг |
Accuracy |
|
|
|
|
|
|
macro |
weighted |
macro |
weighted |
macro |
weighted |
|||
|
|
|
avg |
avg |
avg |
avg |
avg |
avg |
|
|
|
|
|
|
|
|
|
MNB |
- |
0,90 |
0,90 |
0,91 |
0,89 |
0,90 |
0,90 |
0,90 |
|
|
|
|
|
|
|
|
|
|
+ |
0,91 |
0,91 |
0,91 |
0,90 |
0,91 |
0,91 |
0,91 |
|
|
|
|
|
|
|
|
|
DT |
- |
0,73 |
0,73 |
0,73 |
0,71 |
0,73 |
0,71 |
0,73 |
|
|
|
|
|
|
|
|
|
|
+ |
0,74 |
0,76 |
0,75 |
0,74 |
0,79 |
0,74 |
0,75 |
|
|
|
|
|
|
|
|
|
KNN |
- |
0,68 |
0,68 |
0,68 |
0,67 |
0,68 |
0,67 |
0,68 |
|
|
|
|
|
|
|
|
|
|
+ |
0,72 |
0,71 |
0,72 |
0,71 |
0,72 |
0,71 |
0,72 |
|
|
|
|
|
|
|
|
|
Таким образом, из таблицы видно, что значения метрик наилучшие (наиболее приближенные к единице) при использовании для выборок со стеммингом мультиномиального наивного байесовского метода с параметром сглаживания α = 0,1, с отсечением стоп-слов, взвешиванием TF-IDF, числом информативных терминов 10000.
6