Чтобы получить список слов, основы которых входят в список "положительных" наборов слов, достаточно использовать list comprehension:
text = 'Просто шикарный клуб! Ходили с другом на "Animal Джаz"! Остались очень довольны, атмосфера очень уютная, дружелюбная, есть второй этаж, бар'
text_no_punctuation = clear_punctuation(text)
positive_words_list = [x for x in text_no_punctuation.split(' ') if snowball_stemmer.stem(x) in params['positive']]
В этом тексте оказалось только одно "положительное" слово. Есть чем расширить наши списки для улучшения модели классификации:
positive_words_list
Результат:
['довольны']
Количество слов в таком списке считаем с помощью функции len:
positive_words_count = len([x for x in text_no_punctuation.split(' ') if snowball_stemmer.stem(x) in params['positive']])
positive_words_count
Результат:
1
Оформим эти вычисления в функцию. Если количество положительных отзывов больше, чем отрицательных - возвращаем 'positive'. Если меньше - 'negative'. В случае равенства (в том числе 0) - возвращаем 'undef'.
def classifier(text):
"""Классификация отзыва text на 'positive', 'negative' и 'undef' по совпадающим основам слов из params.yaml"""
text = clear_punctuation(text)
positive_words_count = len([x for x in text.split(' ') if snowball_stemmer.stem(x) in params['positive']])
negative_words_count = len([x for x in text.split(' ') if snowball_stemmer.stem(x) in params['negative']])
if positive_words_count > negative_words_count:
return 'positive'
elif positive_words_count < negative_words_count:
return 'negative'
return 'undef'
Проверяем как работает (на очевидных примерах):
text = 'Просто шикарный клуб! Ходили с другом на "Animal Джаz"! Остались очень довольны, атмосфера очень уютная, дружелюбная, есть второй этаж, бар'
classifier(text)
Результат:
'positive'
Еще проверка:
text = 'Ужасное место. Сотрудники клуба от них в восторге! А культурным людям тут не место.'
classifier(text)
Результат:
'negative'
Прогоним наш файл с отзывами через классификатор. В этом скрипте мы используем одни и те же файлы для чтения и записи. В таких случаях рекомендуется "закрывать" их с помощью метода close, чтобы при следующем открытии не возникало проблем и каждый раз не придумывать новые названия переменных:
f = open('texts_opinions.txt', mode = 'r', encoding = 'utf-8')
f_classified = open('texts_classified.txt', mode = 'w', encoding = 'utf-8')
for line in f:
line = line.strip()
f_classified.write('{}\n'.format(classifier(line)))
f.close()
f_classified.close()
В файле texts_classified.txt у вас должен получиться столбец из классификаций 'positive', 'negative' и 'undef'.
Проверка точности модели
Теперь давайте сравним оценки нашего классификатора с реальными оценками пользователей в файле texts_ratings.txt. Будем пользовать следующими правилами:
- Не учитываем отзывы, которые мы не смогли классифицировать (значение 'undef').
- Для определенных типов отзывов (positive и negative) считаем их общее количество в переменной total_defined_ratings.
- Если оценка отзыва в файлах совпала, то увеличиваем переменную right_classifications на 1.
- В конце алгоритма выводим долю верно угаданных отзывов.
f_classified = open('texts_classified.txt', mode = 'r', encoding = 'utf-8')
f_ratings = open('texts_ratings.txt', mode = 'r', encoding = 'utf-8')
classified_list = [line.strip() for line in f_classified]
ratings_list = [line.strip() for line in f_ratings]
right_classifications = 0
total_defined_ratings = 0
for i in range(len(classified_list)):
if classified_list[i]!= 'undef':
total_defined_ratings += 1
if classified_list[i] == ratings_list[i]:
right_classifications += 1
print('Доля верно классифицированных отзывов: {:.0%}'.format(right_classifications / total_defined_ratings))
f_classified.close()
f_ratings.close()
Результат:
Доля верно классифицированных отзывов: 77%
Итак, при первой самой простой модели мы получили точность классификации 77%. Конечно, это без учета того, что часть отзыва мы не классифицировали. Но долю неопределенных отзывов можно уменьшить, добавив в наш словарь больше "положительных" и "отрицательных" слов.
Попробуйте улучшить классификатор, добавив в params.yaml больше слов.
Упражнение
(1 возможный балл)
Как изменятся результаты, когда вы добавите в params.yaml новые слова?
Начало формы
Увеличится доля верно классифицированных отзывов Доля неопределенных отзывов undef уменьшится, либо останется прежней Уменьшится доля верно классифицированных отзывов
- Этот вопрос оставлен без ответа. Конец формы