Лабораторная работа №1. Выделение ключевых слов
Full API
Дано
Текст сказки Ганса Христиана Андерсена “Дюймовочка” на русском языке (
assets/Дюймовочка.txt
).Список стоп-слов (
assets/stop_words.txt
).Словарь с Inverse Document Frequency значениями (
assets/IDF.json
).Словарь с корпусными частотами (
assets/corpus_frequencies.json
).
Что надо сделать
Шаг 0. Начать работу над лабораторной (вместе с преподавателем на практике)
Создайте форк репозитория.
Установите необходимые инструменты для работы.
Измените файлы
main.py
иstart.py
.Закоммитьте изменения и создайте Pull request.
Для этого реализуйте функции в модуле main.py
и импортируйте их в
start.py
. Весь процесс (от предобработки текста до выделения ключевых слов) должен быть
выполнен в функции main
в файле start.py
:
def main() -> None:
pass
Вызов функции в файле start.py
:
if __name__ == '__main__':
main()
В рамках данной лабораторной работы нельзя использовать модули collections, itertools, а также сторонние модули.
Обратите внимание, что желаемую оценку необходимо указать в файле
settings.json
в поле target_score
. Возможные значения: 0, 4, 6, 8, 10.
Чем большее значение выставлено, тем больше тестов будет запущено.
Шаг 1. Очистить и токенизировать текст
Реализуйте функцию lab_1_keywords_tfidf.main.clean_and_tokenize()
.
Функция принимает на вход текст в виде строки. Возвращаемым значением должен быть список строк без:
знаков препинания,
букв верхнего регистра,
лишних пробелов.
Например, строка 'Hey! How are you?'
должна быть токенизирована
следующим образом:
['hey', 'how', 'are', 'you']
.
Если на вход подаются некорректные значения, возвращается None
. Некорректным значением считается значение не того типа, который ожидается.
Интерфейс:
def clean_and_tokenize(text: str) -> list[str]:
pass
Шаг 2. Удалить стоп-слова
Important
Выполнение Шагов 1-2 соответствует 4 баллам.
Реализуйте функцию lab_1_keywords_tfidf.main.remove_stop_words()
.
Функция принимает на вход список токенов и список стоп-слов.
Возвращаемым значением должен быть список токенов без стоп-слов.
Если на вход подаются некорректные значения, возвращается None
.
Пустой список стоп-слов не считается некорректным значением.
Продемонстрируйте выделяемые токены из текста про Дюймовочку без стоп-слов в
файле start.py
. Текст сохранен в переменную target_text
.
Интерфейс:
def remove_stop_words(tokens: list[str], stop_words: list[str]) -> list[str]:
pass
Шаг 3. Получить частотный словарь по заданному тексту
Реализуйте функцию lab_1_keywords_tfidf.main.calculate_frequencies()
.
Функция принимает список токенов.
Возвращает словарь вида {токен: количество вхождений}
.
Так, из последовательности токенов
['hey', 'how', 'are', 'you']
должен получиться следующий словарь частот:
{'hey': 1,
'how': 1,
'are': 1,
'you': 1}
Интерфейс:
def calculate_frequencies(tokens: list[str]) -> dict[str, int]:
pass
Шаг 4. Получить список первых N по популярности слов
Important
Выполнение Шагов 1-4 соответствует 6 баллам.
Реализуйте функцию lab_1_keywords_tfidf.main.get_top_n()
.
Функция принимает частотный словарь и число N
.
Возвращает список первых N
слов по убыванию частоты.
Если N
больше числа слов в словаре, возвращаются все слова.
Обратите внимание, что значения ожидаемого на вход словаря могут быть как в целочисленном формате int, так и в формате с плавающей точкой float.
Интерфейс:
def get_top_n(frequencies: dict[str, int | float], top: int) -> list[str]:
pass
Шаг 5. Рассчитать значения Term Frequency для каждого из слов в тексте
Term Frequency - это отношение числа вхождений некоторого слова к общему числу слов документа. Таким образом оценивается важность слова в пределах отдельного документа.
Формула:
Где:
\(n_t\) — количество вхождений слова \(t\) в документ \(d\);
\(N_d\) — общее количество слов в документе \(d\).
Реализуйте функцию lab_1_keywords_tfidf.main.calculate_tf()
. Она должны будет рассчитывать Term Frequency для токенов. Функция принимает на вход частотный словарь.
Возвращаемым значением функции должен быть словарь, в котором ключами являются токены, а значениями - соответствующие
им значения TF.
Интерфейс:
def calculate_tf(frequencies: dict[str, int]) -> dict[str, float]:
pass
Шаг 6. Рассчитать значения TF-IDF для каждого из слов в тексте
TF-IDF — статистическая мера, используемая для оценки важности слова в контексте документа, являющегося частью коллекции документов или корпуса. Она состоит из двух множителей — Term Frequency (TF) и Inverse Document Frequency (IDF).
Формула:
Множитель Inverse Document Frequency — это инверсия частоты, с которой некоторое слово встречается в документах коллекции:
Здесь:
числитель (\(|D|\)) — общее количество документов в коллекции;
знаменатель (\(|\{d_i \in D : t \in d_i\}|\)) — количество таких документов, в которых встречается слово \(t\).
Таким образом, вес токена в документе прямо пропорционален количеству его вхождений в этот документ и обратно пропорционален количеству вхождений в остальные документы. Простыми словами: чем чаще слово встречается в нашем документе и чем реже оно встречается где-то ещё, тем оно важнее.
Note
Если слово не найдено в словаре IDF, используйте формулу выше, подставив 0 вместо \(|\{d_i \in D : t \in d_i\}|\) и 47 вместо \(|D|\) (именно столько текстов содержится в коллекции сказок Г. Х. Андерсена).
Реализуйте функцию lab_1_keywords_tfidf.main.calculate_tfidf()
.
Функция принимает на вход два словаря: словарь со значениями TF и словарь со значениями IDF.
Возвращает словарь формата {слово: значение TF-IDF}
.
Если на вход подаются некорректные значения, возвращается None
.
Интерфейс:
def calculate_tfidf(term_freq: dict[str, float], idf: dict[str, float]) -> dict[str, float]:
pass
Шаг 7. Продемонстрировать топ-10 ключевых слов согласно TF-IDF
Important
Выполнение Шагов 1-7 соответствует 8 баллам.
Выведите 10 наиболее важных слов согласно значению TF-IDF с помощью функции print
.
Напомним, чем выше значение TF-IDF, тем более важным считается слово.
В этом задании обязательно использовать функцию lab_1_keywords_tfidf.main.get_top_n()
.
Шаг 8. Рассчитать ожидаемую частотность слов
Предположим, что важность слова можно оценивать, сравнивая его частотность в документе с его частотностью в коллекции документов. Если токен ключевой для документа, его встречаемость в этом документе будет сильно отличаться от обычной частотности. Если слово не ключевое, частотность примерно совпадает с частотой в коллекции.
Формулировка гипотез:
\(H_0:\) частотность слова \(t\) в документе \(d\) статистически значимо превышает его частотность в коллекции \(D\)
\(H_1:\) частотность слова \(t\) в документе \(d\) не превышает его частотность в коллекции \(D\)
Для вычисления ожидаемой частотности необходимо найти следующие значения:
d |
D |
|
---|---|---|
t |
j |
k |
~t |
l |
m |
где:
\(j\) — количество вхождений слова \(t\) в документ \(d\)
\(k\) — количество вхождений слова \(t\) во все документы коллекции \(D\)
\(l\) — количество вхождений всех слов, кроме \(t\), в документ \(d\)
\(m\) — количество вхождений всех слов, кроме \(t\), в коллекцию документов \(D\)
Ожидаемая частотность слова \(t\) в документе \(d\) рассчитывается по формуле:
Реализуйте функцию lab_1_keywords_tfidf.main.calculate_expected_frequency()
.
Интерфейс:
def calculate_expected_frequency(doc_freqs: dict[str, int], corpus_freqs: dict[str, int]) -> dict[str, float]:
pass
Частотный словарь для коллекции сказок Г. Х. Андерсена загружен в переменной corpus_freqs
в файле start.py
.
Шаг 9. Рассчитать значения хи-квадрат
Для оценки того, насколько наблюдаемая частотность превышает ожидаемую, используется статистический критерий \(\chi^2\). Формула для каждого слова:
где:
observed
— наблюдаемое количество вхождений слова в документеexpected
— ожидаемая частотность слова (рассчитанная в Шаге 8)
Реализуйте функцию lab_1_keywords_tfidf.main.calculate_chi_values()
.
Интерфейс:
def calculate_chi_values(expected: dict[str, float], observed: dict[str, int]) -> dict[str, float]:
pass
Если на вход подаются некорректные значения, функция должна возвращать None
.
Шаг 10. Выделить статистически значимые слова
Статистически значимыми словами считаются те, для которых значение \(\chi^2\) превышает критическое значение. Выбор критического значения зависит от желаемого уровня значимости (вероятность ошибочно назвать неключевое слово ключевым):
CRITERION = {0.05: 3.842, 0.01: 6.635, 0.001: 10.828}
Реализуйте функцию lab_1_keywords_tfidf.main.extract_significant_words()
.
Функция принимает словарь значений \(\chi^2\) и уровень значимости alpha
.
Возвращает словарь, содержащий только статистически значимые слова.
Если на вход подаются некорректные значения, возвращается None
.
Интерфейс:
def extract_significant_words(chi_values: dict[str, float], alpha: float) -> dict[str, float]:
pass
Шаг 11. Вывести топ-10 ключевых слов согласно \(\chi^2\)
Important
Выполнение Шагов 1-11 соответствует 10 баллам.
Чем выше значение \(\chi^2\) для токена, тем более значимым считается слово.
Выведите 10 самых важных слов с точки зрения статистики.
Ранжирование токенов выполняется с помощью функции lab_1_keywords_tfidf.main.get_top_n()
.