├── HW ├── hw1.ipynb ├── hw2.ipynb ├── hw3.ipynb └── hw4.ipynb ├── README.md ├── lectures ├── 10_sumamrization_simplification.pdf ├── 11_text-normalisation.pdf ├── 1_intro.pdf ├── 2_word-embeddings.pdf ├── 3_text-classification.pdf ├── 4_lm.pdf ├── 4_seq-model.pdf ├── 5_syntax_fcs_2019_final.pdf ├── 6_mt_attn_transformer.pdf ├── 6_seq2seq.pdf ├── 8_sesame_street.pdf ├── 9_QA.pdf └── multilingual_dependency_parsing.pdf └── seminars ├── sem12_active_learning ├── active_learning.png ├── sem12-active-learning.ipynb └── spam_text_classification_data.csv ├── sem13 └── text_generation_seqGAN.pdf ├── sem1_preprocessing.ipynb ├── sem2_embeddings.ipynb ├── sem3_classification.ipynb ├── sem4_language_models ├── images │ ├── .DS_Store │ ├── LSTM.png │ ├── LSTM_rnn.png │ ├── bilstm_crf_model.png │ ├── dino.jpg │ ├── dino.png │ ├── dinos3.png │ ├── rnn.png │ ├── rnn_cell_backprop.png │ ├── rnn_step_forward.png │ ├── understanding_lstms.jpg │ └── word_representation_model.png └── sem4_language_models.ipynb ├── sem5_syntax ├── constituency_parsing.png ├── recursiveNN.jpg ├── recursiveNN_formula.jpg ├── rus_tree.png ├── sem5_syntax.ipynb └── sentiment_recursiveNN.png ├── sem6_seq2seq └── 6_seq2seq.ipynb ├── sem7_transformers ├── images │ ├── attention.png │ ├── attention_matrix.png │ ├── bert_input_representation.png │ ├── bert_model.png │ ├── multi-head-attention.png │ └── transformer.png └── sem7_transformer.ipynb ├── sem_10 └── sem_10_fastai.ipynb ├── sem_11 ├── bertsum.png ├── sem_11_summarization.ipynb └── summ-attentions.svg └── sem_9 └── Baseline_AIJ.ipynb /HW/hw1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Домашнее задание 1\n", 8 | "## Harry Potter and the Action Prediction Challenge from Natural Language\n", 9 | "\n", 10 | "*deadline*: 2 октября 2019, 23:59\n", 11 | "\n", 12 | "В этом домашнем задании вы будете работать с корпусом Harry Potter and the Action Prediction Challenge. Корпус собран из фанфиков о Гарри Поттере и состоит из двух частей: 1) сырые тексты, 2) фрагменты текстов, описывающих ситуацию, в которой произнесено заклинание.\n", 13 | "\n", 14 | "Корпус описан в статье: https://arxiv.org/pdf/1905.11037.pdf\n", 15 | "\n", 16 | "David Vilares and Carlos Gómez-Rodríguez. Harry Potter and the Action Prediction Challenge from Natural Language. 2019 Annual Conference of the North American Chapter of the Association for Computational Linguistics. To appear.\n", 17 | "\n", 18 | "Код для сбора корпуса находится в репозитории: https://github.com/aghie/hpac . Корпус можно скачать по инструкции из этого репозитория, но для экономии времени авторы задания уже скачали и подготовили данные к работе. \n", 19 | "\n", 20 | "Ссылки на собранный корпус: \n", 21 | "* Сырые тексты: https://www.dropbox.com/s/23xet9kvbqna1qs/hpac_raw.zip?dl=0\n", 22 | "* Токенизированные тексты в нижнем регистре: https://www.dropbox.com/s/gwfgmomdbetvdye/hpac_lower_tokenized.zip?dl=0\n", 23 | "* train-test-dev: https://www.dropbox.com/s/3vdz0mouvex8abd/hpac_splits.zip?dl=0\n", 24 | "\n", 25 | "Части 1, 2 задания должны быть выполнены на полных текстах (сырых или предобработанных -- на ваше усмотрение), Часть 3 – на разбиение на тестовое, отладочное и обучающее множества. Тестовое множество должно быть использовано исключительно для тестирования моделей, обучающее и отладочное – для выбора модели и параметров. \n", 26 | "\n", 27 | "В статье и репозитории вы найдете идеи, которые помогут вам выполнить домашнее задание. Их стоит воспринимать как руководство к действию, и не стоит их копировать и переиспользовать. Обученные модели использовать не нужно, код для их обучения можно использовать как подсказку. \n", 28 | "\n", 29 | "## ПРАВИЛА\n", 30 | "1. Домашнее задание выполняется в группе до 3-х человек.\n", 31 | "2. Домашнее задание сдается через anytask, инвайты будут дополнительно высланы.\n", 32 | "3. Домашнее задание оформляется в виде отчета либо в .pdf файле, либо ipython-тетрадке. \n", 33 | "4. Отчет должен содержать: нумерацию заданий и пунктов, которые вы выполнили, код решения, и понятное пошаговое описание того, что вы сделали. Отчет должен быть написан в академическом стиле, без излишнего использования сленга и с соблюдением норм русского языка.\n", 34 | "5. Не стоит копировать фрагменты лекций, статей и Википедии в ваш отчет.\n", 35 | "6. Отчеты, состоящие исключительно из кода, не будут проверены и будут автоматически оценены нулевой оценкой.\n", 36 | "7. Плагиат и любое недобросоветсное цитирование приводит к обнуление оценки. \n", 37 | "\n", 38 | "\n", 39 | "## Часть 1. [2 балла] Эксплоративный анализ \n", 40 | "1. Найдите топ-1000 слов по частоте без учета стоп-слов.\n", 41 | "2. Найдите топ-10 по частоте: имен, пар имя + фамилия, пар вида ''профессор'' + имя / фамилия. \n", 42 | "\n", 43 | "[бонус] Постройте тематическую модель по корпусу HPAC.\n", 44 | "\n", 45 | "[бонус] Найдите еще что-то интересное в корпусе (что-то специфичное для фанфиков или фентези-тематики)\n", 46 | "\n", 47 | "## Часть 2. [2 балла] Модели представления слов \n", 48 | "Обучите модель представления слов (word2vec, GloVe, fastText или любую другую) на материале корпуса HPAC.\n", 49 | "1. Продемонстрируйте, как работает поиск синонимов, ассоциаций, лишних слов в обученной модели. \n", 50 | "2. Визуализируйте топ-1000 слов по частоте без учета стоп-слов (п. 1.1) с помощью TSNE или UMAP (https://umap-learn.readthedocs.io).\n", 51 | "\n", 52 | "## Часть 3. [5 баллов] Классификация текстов\n", 53 | "Задача классификации формулируется так: данный фрагмент фанфика описывают какую-то ситуацию, которая предшествует произнесению заклинания. Требуется по тексту предсказать, какое именно заклинание будет произнесено. Таким образом, заклинание - это фактически метка класса. Основная мера качества – macro $F_1$.\n", 54 | "Обучите несколько классификаторов и сравните их между собой. Оцените качество классификаторов на частых и редких классах. Какие классы чаще всего оказываются перепутаны? Связаны ли ошибки со смыслом заклинаний?\n", 55 | "\n", 56 | "Используйте фрагменты из множества train для обучения, из множества dev для отладки, из множества test – для тестирования и получения итоговых результатов. \n", 57 | "\n", 58 | "1. [1 балл] Используйте fastText в качестве baseline-классификатора.\n", 59 | "2. [2 балла] Используйте сверточные сети в качестве более продвинутого классификатора. Поэкспериментируйте с количеством и размерностью фильтров, используйте разные размеры окон, попробуйте использовать $k$-max pooling. \n", 60 | "3. [2 балла] Попробуйте расширить обучающее множество за счет аугментации данных. Если вам понадобится словарь синонимов, можно использовать WordNet (ниже вы найдете примеры).\n", 61 | "\n", 62 | "[бонус] Используйте результат max pooling'а как эмбеддинг входного текста. Визуализируйте эмбеддинги 500-1000 предложений из обучающего множества и изучите свойства получившегося пространства.\n", 63 | "\n", 64 | "[бонус] Используйте ваш любимый классификатор и любые (честные) способы повышения качества классификации и получите macro $F_1$ больше 0.5.\n", 65 | "\n", 66 | "## Часть 4. [1 балл] Итоги\n", 67 | "Напишите краткое резюме проделанной работы. Читали ли вы сами Гарри Поттера или фанфики о нем и помогло ли вам знание предметной области в выполнении домашнего задания?" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "### Данные\n", 75 | "Сырые тексты " 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": { 82 | "jupyter": { 83 | "outputs_hidden": true 84 | } 85 | }, 86 | "outputs": [], 87 | "source": [ 88 | "!unzip hpac_source" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "!ls hpac_source | wc -l" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": null, 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "!unzip hpac_splits" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "train, test, dev файлы" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": null, 119 | "metadata": {}, 120 | "outputs": [], 121 | "source": [ 122 | "import pandas as pd\n", 123 | "df = pd.read_csv('hpac_splits/hpac_training_128.tsv', sep = '\\t', header = None)" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [ 132 | "df.head()" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "df.iloc[0][1], df.iloc[0][2]" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "### Как использовать WordNet из nltk?" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "# скачиваем WordNet\n", 158 | "import nltk\n", 159 | "nltk.download('wordnet')" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [ 168 | "# слово -> множество синсетов (синонимов разных смыслов исходного слова)\n", 169 | "from nltk.corpus import wordnet as wn\n", 170 | "wn.synsets('magic')" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "# посмотрим, что внутри одного синсета\n", 180 | "wn.synsets('magic')[1].lemmas()[0]" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": {}, 187 | "outputs": [], 188 | "source": [ 189 | "# возьмем лемму одного из слов из синсета\n", 190 | "wn.synsets('magic')[1].lemmas()[-1].name()" 191 | ] 192 | } 193 | ], 194 | "metadata": { 195 | "kernelspec": { 196 | "display_name": "Python 3", 197 | "language": "python", 198 | "name": "python3" 199 | }, 200 | "language_info": { 201 | "codemirror_mode": { 202 | "name": "ipython", 203 | "version": 3 204 | }, 205 | "file_extension": ".py", 206 | "mimetype": "text/x-python", 207 | "name": "python", 208 | "nbconvert_exporter": "python", 209 | "pygments_lexer": "ipython3", 210 | "version": "3.6.0" 211 | } 212 | }, 213 | "nbformat": 4, 214 | "nbformat_minor": 4 215 | } 216 | -------------------------------------------------------------------------------- /HW/hw2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Домашнее задание 2\n", 8 | "## Named Entety Recognition and Event Extraction from Literary Fiction\n", 9 | "\n", 10 | "deadline: 30 октября 2019, 23:59\n", 11 | "\n", 12 | "В этом домашнем задании вы будете работать с корпусом LitBank. Корпус собран из популярных художественных произведений на английском языке и сожержит разметку по именованным сущностям и событиям. Объем корпуса таков: 100 текстов по примерно 2000 слов каждый. \n", 13 | "\n", 14 | "Корпус описан в статьях:\n", 15 | "* David Bamman, Sejal Popat, Sheng Shen, An Annotated Dataset of Literary Entities http://people.ischool.berkeley.edu/~dbamman/pubs/pdf/naacl2019_literary_entities.pdf\n", 16 | "* Matthew Sims, Jong Ho Park, David Bamman, Literary Event Detection, http://people.ischool.berkeley.edu/~dbamman/pubs/pdf/acl2019_literary_events.pdf\n", 17 | "\n", 18 | "Корпус доступен в репозитории проекта: https://github.com/dbamman/litbank\n", 19 | "\n", 20 | "Статья и код, использованный для извлечения именованных сущностей: \n", 21 | "* Meizhi Ju, Makoto Miwa and Sophia Ananiadou, A Neural Layered Model for Nested Named Entity Recognition, https://github.com/meizhiju/layered-bilstm-crf\n", 22 | "\n", 23 | "Структура корпуса устроена так. \n", 24 | "Первый уровень: \n", 25 | "* entities -- разметка по сущностям\n", 26 | "* events -- разметка по сущностям\n", 27 | "\n", 28 | "\n", 29 | "В корпусе используются 6 типов именованных сущностей: PER, LOC, ORG, FAC, GPE, VEH (имена, локации, организации, помещения, топонимы, средства перемещния), допускаются вложенные сущности. \n", 30 | "\n", 31 | "События выражается одним словом - *триггером*, которое может быть глагом, прилагательным и существительным. В корпусе описаны события, которые действительно происходят и не имеют гипотетического характера. \n", 32 | "Пример: she *walked* rapidly and resolutely, здесь *walked* -- триггер события. Типы событий не заданы. \n", 33 | "\n", 34 | "\n", 35 | "\n", 36 | "Второй уровень:\n", 37 | "* brat -- рабочие файлы инструмента разметки brat, ann-файлы содержат разметку, txt-файлы – сырые тексты \n", 38 | "* tsv -- tsv-файлы содержат разметку в IOB формате,\n", 39 | "\n", 40 | "\n", 41 | "В статье и репозитории вы найдете идеи, которые помогут вам выполнить домашнее задание. Их стоит воспринимать как руководство к действию, и не стоит их копировать и переиспользовать. Обученные модели использовать не нужно, код для их обучения можно использовать как подсказку. \n", 42 | "\n", 43 | "## ПРАВИЛА\n", 44 | "1. Домашнее задание выполняется в группе до 3-х человек.\n", 45 | "2. Домашнее задание сдается через anytask, инвайты будут дополнительно высланы.\n", 46 | "3. Домашнее задание оформляется в виде отчета либо в .pdf файле, либо ipython-тетрадке. \n", 47 | "4. Отчет должен содержать: нумерацию заданий и пунктов, которые вы выполнили, код решения, и понятное пошаговое описание того, что вы сделали. Отчет должен быть написан в академическом стиле, без излишнего использования сленга и с соблюдением норм русского языка.\n", 48 | "5. Не стоит копировать фрагменты лекций, статей и Википедии в ваш отчет.\n", 49 | "6. Отчеты, состоящие исключительно из кода, не будут проверены и будут автоматически оценены нулевой оценкой.\n", 50 | "7. Плагиат и любое недобросоветсное цитирование приводит к обнуление оценки. \n", 51 | "\n", 52 | "\n", 53 | "## Часть 1. [2 балла] Эксплоративный анализ \n", 54 | "1. Найдите топ 10 (по частоте) именованных сущностей каждого из 6 типов.\n", 55 | "2. Найдите топ 10 (по частоте) частотных триггеров событий. \n", 56 | "3. Кластеризуйте все уникальные триггеры событий, используя эмбеддинги слов и любой алгоритм кластеризации (например, агломеративный иерархический алгоритм кластеризации) и попробуйте проинтерпретировать кластеры: есть ли очевидные типы событий? \n", 57 | "\n", 58 | "[бонус] Визуализируйте полученные кластеры с помощью TSNE или UMAP\n", 59 | "\n", 60 | "[бонус] Постройте тематическую модель по корпусу и сравните кластеры тригеров и выделенные темы: есть ли схожие паттерны в тематической модели и в стурктуре кластеров?\n", 61 | "\n", 62 | "В следующих частях домашнего задания вам понадобится train-test-dev разбиение. Авторы статей предлагают следующую структуру разбиения: обучающее множество – 80 книг, валидационное – 10 книг, тестовое – 10 книг. Предложения из одного источника не должны попадать в разные сегменты разбиения. \n", 63 | "\n", 64 | "\n", 65 | "## Часть 2. [3 балла] Извлечение именованных сущностей\n", 66 | "1. Обучите стандартную модель для извлечения именованных сущностей, CNN-BiLSTM-CRF, для извлечения именованных *низкоуровневых именованных сущностей*, т.е. для самых коротких из вложенных сущностей. \n", 67 | "Модель устроена так: сверточная сеть на символах + эмбеддинги слов + двунаправленная LSTM сеть (модель последовательности) + CRF (глобальная нормализация).\n", 68 | "2. Замените часть модели на символах и словах (CNN + эмбеддинги словах) на ELMo и / или BERT. Должна получиться модель ELMo / BERT + BiLSTM + CRF. \n", 69 | "3. Замените модель последовательности (BiLSTM) на другой слой, например, на Transformer. Должна получиться модель CNN + Transformer + CRF. \n", 70 | "\n", 71 | "[бонус] Дообучите BERT для извлечения именованных сущностей.\n", 72 | "\n", 73 | "[бонус] Используйте модель для извлечения вложенных именованных сущностей [Ju et al., 2018]\n", 74 | "\n", 75 | "[бонус] Модифицируйте модель для извлечения вложенных именованных сущностей [Ju et al., 2018]: вместо эмбеддингов слов используйте ELMo и/или BERT. \n", 76 | "\n", 77 | "## Часть 3. [2 балла] Извлечение событий \n", 78 | "\n", 79 | "1. Используйте BiLSTM на эмбеддингах слов для извлечения триггеров событий. \n", 80 | "\n", 81 | "2. Замените часть модели на словах на ELMo и/или BERT. Должна получиться модель ELMo / BERT + BiLSTM.\n", 82 | "\n", 83 | "[бонус] Предобучите BiLSTM как языковую модель. Дообучите ее для извлечения триггеров. \n", 84 | "\n", 85 | "[бонус] Дообучите BERT для извлечения триггеров событий. \n", 86 | "\n", 87 | "## Часть 4. [2 балла] Одновременное извлечение именованных сущностей и событий \n", 88 | "1. Обучите модель для совместного извлечения именованных сущностей и триггеров событий. У модели должен быть общий энкодер (например, CNN + BiLSMT, ELMo + BiLSTM, BERT + BiLSTM) и два декодера: один отвечает за извлечение именнованных сущностей, другой отвечает за извлечение триггеров событий.\n", 89 | "\n", 90 | "[бонус] Добавьте в модель механизм внимания, так, как это покажется вам разумным.\n", 91 | "\n", 92 | "[бонус] Визуализируйте карты механизма внимания. \n", 93 | "\n", 94 | "## Часть 5. [1 балл] Итоги\n", 95 | "Напишите краткое резюме проделанной работы. Сравните результаты всех разработанных моделей. Что помогло вам в выполнении работы, чего не хватало?" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [] 104 | } 105 | ], 106 | "metadata": { 107 | "kernelspec": { 108 | "display_name": "Python 3", 109 | "language": "python", 110 | "name": "python3" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": { 114 | "name": "ipython", 115 | "version": 3 116 | }, 117 | "file_extension": ".py", 118 | "mimetype": "text/x-python", 119 | "name": "python", 120 | "nbconvert_exporter": "python", 121 | "pygments_lexer": "ipython3", 122 | "version": "3.6.0" 123 | } 124 | }, 125 | "nbformat": 4, 126 | "nbformat_minor": 2 127 | } 128 | -------------------------------------------------------------------------------- /HW/hw3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Домашнее задание 3\n", 8 | "## Yes/No Questions\n", 9 | "\n", 10 | "deadline: 3 декабря 2019, 23:59\n", 11 | "\n", 12 | "В этом домашнем задании вы будете работать с корпусом BoolQ. Корпус состоит из вопросов, предполагающих бинарный ответ (да / нет), абзацев из Википедии, содержащих ответ на вопрос, заголовка статьи, из которой извлечен абзац и непосредственно ответа (true / false).\n", 13 | "\n", 14 | "Корпус описан в статье:\n", 15 | "\n", 16 | "Christopher Clark, Kenton Lee, Ming-Wei Chang, Tom Kwiatkowski, Michael Collins, Kristina Toutanova\n", 17 | "BoolQ: Exploring the Surprising Difficulty of Natural Yes/No Questions\n", 18 | "\n", 19 | "https://arxiv.org/abs/1905.10044\n", 20 | "\n", 21 | "\n", 22 | "Корпус (train-dev split) доступен в репозитории проекта: https://github.com/google-research-datasets/boolean-questions\n", 23 | "\n", 24 | "Используйте для обучения train часть корпуса, для валидации и тестирования – dev часть. \n", 25 | "\n", 26 | "Каждый бонус пункт оцениватся в 1 балл. " 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "### Пример вопроса: \n", 34 | "question: is batman and robin a sequel to batman forever\n", 35 | "\n", 36 | "title: Batman & Robin (film)\n", 37 | "\n", 38 | "answer: true\n", 39 | "\n", 40 | "passage: With the box office success of Batman Forever in June 1995, Warner Bros. immediately commissioned a sequel. They hired director Joel Schumacher and writer Akiva Goldsman to reprise their duties the following August, and decided it was best to fast track production for a June 1997 target release date, which is a break from the usual 3-year gap between films. Schumacher wanted to homage both the broad camp style of the 1960s television series and the work of Dick Sprang. The storyline of Batman & Robin was conceived by Schumacher and Goldsman during pre-production on A Time to Kill. Portions of Mr. Freeze's back-story were based on the Batman: The Animated Series episode ''Heart of Ice'', written by Paul Dini." 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## ПРАВИЛА\n", 48 | "1. Домашнее задание выполняется в группе до 3-х человек.\n", 49 | "2. Домашнее задание сдается через anytask, инвайты будут дополнительно высланы.\n", 50 | "3. Домашнее задание оформляется в виде отчета либо в .pdf файле, либо ipython-тетрадке. \n", 51 | "4. Отчет должен содержать: нумерацию заданий и пунктов, которые вы выполнили, код решения, и понятное пошаговое описание того, что вы сделали. Отчет должен быть написан в академическом стиле, без излишнего использования сленга и с соблюдением норм русского языка.\n", 52 | "5. Не стоит копировать фрагменты лекций, статей и Википедии в ваш отчет.\n", 53 | "6. Отчеты, состоящие исключительно из кода, не будут проверены и будут автоматически оценены нулевой оценкой.\n", 54 | "7. Плагиат и любое недобросоветсное цитирование приводит к обнуление оценки. " 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "## Часть 1. [1 балл] Эксплоративный анализ\n", 62 | "1. Посчитайте долю yes и no классов в корпусе\n", 63 | "2. Оцените среднюю длину вопроса\n", 64 | "3. Оцените среднюю длину параграфа\n", 65 | "4. Предположите, по каким эвристикам были собраны вопросы (или найдите ответ в статье). Продемонстриуйте, как эти эвристики повлияли на структуру корпуса. " 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "## Часть 2. [1 балл] Baseline\n", 73 | "1. Оцените accuracy точность совсем простого базового решения: присвоить каждой паре вопрос-ответ в dev части самый частый класс из train части\n", 74 | "2. Оцените accuracy чуть более сложного базового решения: fasttext на текстах, состоящих из склееных вопросов и абзацев (' '.join([question, passage]))\n", 75 | "\n", 76 | "Почему fasttext плохо справляется с этой задачей?" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "## Часть 3. [1 балл] Используем эмбеддинги предложений\n", 84 | "1. Постройте BERT эмбеддинги вопроса и абзаца. Обучите логистическую регрессию на конкатенированных эмбеддингах вопроса и абзаца и оцените accuracy этого решения. \n", 85 | "\n", 86 | "[bonus] Используйте другие модели эмбеддингов, доступные, например, в библиотеке 🤗 Transformers. Какая модель эмбеддингов даст лучшие результаты?\n", 87 | "\n", 88 | "[bonus] Предложите метод аугментации данных и продемонстрируйте его эффективность. " 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "## Часть 3. [3 балла] DrQA-подобная архитектура\n", 96 | "\n", 97 | "Основана на статье: Reading Wikipedia to Answer Open-Domain Questions\n", 98 | "\n", 99 | "Danqi Chen, Adam Fisch, Jason Weston, Antoine Bordes\n", 100 | "\n", 101 | "https://arxiv.org/abs/1704.00051\n", 102 | "\n", 103 | "Архитектура DrQA предложена для задачи SQuAD, но легко может быть адаптирована к текущему заданию. Модель состоит из следующих блоков:\n", 104 | "1. Кодировщик абзаца [paragraph encoding] – LSTM, получаящая на вход вектора слов, состоящие из: \n", 105 | "* эмбеддинга слова (w2v или fasttext)\n", 106 | "* дополнительных признаков-индикаторов, кодирующих в виде one-hot векторов часть речи слова, является ли оно именованной сущностью или нет, встречается ли слово в вопросе или нет \n", 107 | "* выровненного эмбеддинга вопроса, получаемого с использованием soft attention между эмбеддингами слов из абзаца и эмбеддингом вопроса.\n", 108 | "\n", 109 | "$f_{align}(p_i) = \\sum_j􏰂 a_{i,j} E(q_j)$, где $E(q_j)$ – эмбеддинг слова из вопроса. Формула для $a_{i,j}$ приведена в статье. \n", 110 | "\n", 111 | "2. Кодировщик вопроса [question encoding] – LSTM, получаящая на вход эмбеддинги слов из вопроса. Выход кодировщика: $q = 􏰂\\sum_j􏰂 b_j q_j$. Формула для $b_{j}$ приведена в статье. \n", 112 | "\n", 113 | "3. Слой предсказания. \n", 114 | "\n", 115 | "Предложите, как можно было модифицировать последний слой предсказания в архитектуре DrQA, с учетом того, что итоговое предсказание – это метка yes / no, предсказание которой проще, чем предсказание спана ответа для SQuAD.\n", 116 | "\n", 117 | "Оцените качество этой модели для решения задачи. \n", 118 | "\n", 119 | "[bonus] Замените входные эмбеддинги и все дополнительные признаки, используемые кодировщиками, на BERT эмбеддинги. Улучшит ли это качество результатов?" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "## Часть 4. [3 балла] BiDAF-подобная архитектура\n", 127 | "\n", 128 | "Основана на статье: Bidirectional Attention Flow for Machine Comprehension\n", 129 | "\n", 130 | "Minjoon Seo, Aniruddha Kembhavi, Ali Farhadi, Hannaneh Hajishirzi\n", 131 | "\n", 132 | "https://arxiv.org/abs/1611.01603\n", 133 | "\n", 134 | "Архитектура BiDAF предложена для задачи SQuAD, но легко может быть адаптирована к текущему заданию. Модель состоит из следующих блоков:\n", 135 | "1. Кодировщик получает на вход два представления слова: эмбеддинг слова и полученное из CNN посимвольное представление слова. Кодировщики для вопроса и для параграфа одинаковы. \n", 136 | "2. Слой внимания (детальное описание приведено в статье, см. пункт Attention Flow Layer)\n", 137 | "3. Промежуточный слой, который получает на вход контекстуализированные эмбеддинги слов из параграфа, состоящие из трех частей (выход кодировщика параграфа, Query2Context (один вектор) и Context2Query (матрица) выравнивания\n", 138 | "\n", 139 | "4. Слой предсказания. \n", 140 | "\n", 141 | "Предложите, как можно было модифицировать последний слой предсказания в архитектуре BiDAF, с учетом того, что итоговое предсказание – это метка yes / no, предсказание которой проще, чем предсказание спана ответа для SQuAD.\n", 142 | "\n", 143 | "Оцените качество этой модели для решения задачи. \n", 144 | "\n", 145 | "[bonus] Замените входные эмбеддинги и все дополнительные признаки, используемые кодировщиками, на BERT эмбеддинги. Улучшит ли это качество результатов?" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "Сравнение DrQA и BiDAF:\n", 153 | " \n", 154 | "![](https://www.researchgate.net/profile/Felix_Wu6/publication/321069852/figure/fig1/AS:560800147881984@1510716582560/Schematic-layouts-of-the-BiDAF-left-and-DrQA-right-architectures-We-propose-to.png)" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "## Часть 5. [1 балл] Итоги\n", 162 | "Напишите краткое резюме проделанной работы. Сравните результаты всех разработанных моделей. Что помогло вам в выполнении работы, чего не хватало?" 163 | ] 164 | } 165 | ], 166 | "metadata": { 167 | "kernelspec": { 168 | "display_name": "Python 3", 169 | "language": "python", 170 | "name": "python3" 171 | }, 172 | "language_info": { 173 | "codemirror_mode": { 174 | "name": "ipython", 175 | "version": 3 176 | }, 177 | "file_extension": ".py", 178 | "mimetype": "text/x-python", 179 | "name": "python", 180 | "nbconvert_exporter": "python", 181 | "pygments_lexer": "ipython3", 182 | "version": "3.6.8" 183 | } 184 | }, 185 | "nbformat": 4, 186 | "nbformat_minor": 2 187 | } 188 | -------------------------------------------------------------------------------- /HW/hw4.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Домашнее задание 4\n", 8 | "## Text Normalization \n", 9 | "\n", 10 | "deadline: 15 декабря 2019, 23:59\n", 11 | "\n", 12 | "В этом домашнем задании вы будете работать с корпусом соревнования по нормализации текстов на русском языке. \n", 13 | "\n", 14 | "Ссылка на соревнование:\n", 15 | "https://www.kaggle.com/c/text-normalization-challenge-russian-language\n", 16 | "\n", 17 | "Корпус (train-test split) доступен там же, на kaggle. Кроме того, kaggle проверяет результаты на тестовом множестве. Пример сабмита в файле: ru_sample_submission_2. \n", 18 | "\n", 19 | "Задача заключается в том, привести исходный текст (колонку before) в нормализованную форму (колонка after). Дополнительно известны классы токенов (колонка class), общее число классов – 15. В тестовом множестве классы токенов отсутствуют. \n", 20 | "\n", 21 | "Корпус состоит из предложений на русском языке и их нормализованных аналогов. Примеры продемонстрированы на kaggle." 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## ПРАВИЛА\n", 29 | "1. Домашнее задание выполняется в группе до 3-х человек.\n", 30 | "2. Домашнее задание сдается через anytask, инвайты будут дополнительно высланы.\n", 31 | "3. Домашнее задание оформляется в виде отчета либо в .pdf файле, либо ipython-тетрадке. \n", 32 | "4. Отчет должен содержать: нумерацию заданий и пунктов, которые вы выполнили, код решения, и понятное пошаговое описание того, что вы сделали. Отчет должен быть написан в академическом стиле, без излишнего использования сленга и с соблюдением норм русского языка.\n", 33 | "5. Не стоит копировать фрагменты лекций, статей и Википедии в ваш отчет.\n", 34 | "6. Отчеты, состоящие исключительно из кода, не будут проверены и будут автоматически оценены нулевой оценкой.\n", 35 | "7. Плагиат и любое недобросоветсное цитирование приводит к обнуление оценки. " 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## Часть 1. [1 балл] Эксплоративный анализ\n", 43 | "\n", 44 | "1. Найдите примеры каждого класса и опишите, по какой логике проведена нормализация токенов разных классов. \n", 45 | "2. В каких случаях токены класса PLAIN подвергаются нормализации? \n", 46 | "3. Напишите правила для нормализации токенов класса ORDINAL. " 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "## Часть 2. [6 баллов] seq2seq архитектуры\n", 54 | "Имплементируйте несколько seq2seq архитектур. Энкодер получает на вход последовательность токенов before, декодер учится превращать их в токены after.\n", 55 | "Энкодер и декодер работают на уровне символов, эмбеддинги символов инициализируются случайно (по аналогии с работами, в которых предложены нейросетевые модели исправления опечаток).\n", 56 | "\n", 57 | "Эту часть задания рекомендуется выполнять с использованием allennlp (должно быть проще и удобнее).\n", 58 | "\n", 59 | "1. [3 балла] LSTM encoder + LSTM decoder + три механизма внимания: скалярное произведение, аддитивное внимание и мультипликативное внимание (см. лекцию 6, слайд \"подсчет весов attention\")\n", 60 | "2. [3 балла] Transformer\n", 61 | "\n", 62 | "Используя автопровереку kaggle, оцените, как влияют параметры архитектуры на качество задачи.\n", 63 | "\n", 64 | "[бонус] convolutional encoder + convolutional decoder\n", 65 | "\n", 66 | "[бонус] pyramid LSTM (размер l+1 слоя в два раз меньше размера l, i-тый вход l+1 слоя – конкатенация выходов 2i и 2i+1)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "## Часть 3. [2 балла] Дополнительные признаки\n", 74 | "Предложите и покажите, как можно было бы повысить качество нейросетевых моделей. Примерные варианты:\n", 75 | "1. ансамблирование нейронных сетей\n", 76 | "2. добавление морфологоческих признаков \n", 77 | "3. использование эмбеддингов слов \n" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "## Часть 4. [1 балл] Итоги\n", 85 | "Напишите краткое резюме проделанной работы. Проведите анализ ошибок: когда модель ошибается? Можно ли скзаать, почему модель ошибается? Сравните результаты всех разработанных моделей. Что помогло вам в выполнении работы, чего не хватало?" 86 | ] 87 | } 88 | ], 89 | "metadata": { 90 | "kernelspec": { 91 | "display_name": "Python 3", 92 | "language": "python", 93 | "name": "python3" 94 | }, 95 | "language_info": { 96 | "codemirror_mode": { 97 | "name": "ipython", 98 | "version": 3 99 | }, 100 | "file_extension": ".py", 101 | "mimetype": "text/x-python", 102 | "name": "python", 103 | "nbconvert_exporter": "python", 104 | "pygments_lexer": "ipython3", 105 | "version": "3.7.4" 106 | } 107 | }, 108 | "nbformat": 4, 109 | "nbformat_minor": 4 110 | } 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NLP-course-AMI 2 | NLP course @ CS Faculty, HSE 3 | 4 | Week 1 5 | * Lecture: Intro to NLP 6 | * Practical: Text preprocessing 7 | 8 | Week 2 9 | * Lecture: Word embeddings 10 | * Practical: word2vec, fasttext, basic text classification 11 | * Quiz: https://forms.gle/DiS9rBskgxXxD6Hy6 12 | 13 | 14 | Week 3 15 | * Lecture & Practical: CNN for text classification 16 | * Quiz: https://forms.gle/mowmk9LgLG1yyLrh7 17 | * Homework 1 18 | 19 | Week 4: 20 | * Lecture & Practical: Language modelling 21 | 22 | Week 5: 23 | * Lecture & Practical: Syntax parsing 24 | * Quiz: https://forms.gle/WePgRurr4w9HLgW59 25 | 26 | Week 6 27 | * Lecture: Machine translation 28 | * Seminar: Seq2seq [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/PragmaticsLab/NLP-course-FinTech/blob/master/seminars/sem6_seq2seq/6_seq2seq.ipynb) 29 | 30 | Week 7: 31 | * Lecture: Transfer learning in NLP, part 1 32 | * Project p.1 33 | 34 | Week 8: 35 | * Lecture: Transfer learning in NLP, part 2 36 | * Quiz: https://forms.gle/tfv6Ki6CW4pNui4u8 37 | 38 | Week 9 39 | * Lecture: Question answering 40 | * Homework 3 41 | 42 | Week 10 43 | * Lecture: Summarization and simplification 44 | * Quiz: https://forms.gle/JyCybZkzSM5eSQAu5 45 | 46 | Week 11 47 | * Lecture: Summarization and simplification, p. 2 + presentations 48 | 49 | Week 12: 50 | * Lecture: Text normalisation + presentations 51 | * Homework 4 52 | * Project p.2 53 | 54 | Week 13: 55 | * Lecture: 56 | 57 | Week 14: 58 | * New Year games 59 | -------------------------------------------------------------------------------- /lectures/10_sumamrization_simplification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/10_sumamrization_simplification.pdf -------------------------------------------------------------------------------- /lectures/11_text-normalisation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/11_text-normalisation.pdf -------------------------------------------------------------------------------- /lectures/1_intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/1_intro.pdf -------------------------------------------------------------------------------- /lectures/2_word-embeddings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/2_word-embeddings.pdf -------------------------------------------------------------------------------- /lectures/3_text-classification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/3_text-classification.pdf -------------------------------------------------------------------------------- /lectures/4_lm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/4_lm.pdf -------------------------------------------------------------------------------- /lectures/4_seq-model.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/4_seq-model.pdf -------------------------------------------------------------------------------- /lectures/5_syntax_fcs_2019_final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/5_syntax_fcs_2019_final.pdf -------------------------------------------------------------------------------- /lectures/6_mt_attn_transformer.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/6_mt_attn_transformer.pdf -------------------------------------------------------------------------------- /lectures/6_seq2seq.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/6_seq2seq.pdf -------------------------------------------------------------------------------- /lectures/8_sesame_street.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/8_sesame_street.pdf -------------------------------------------------------------------------------- /lectures/9_QA.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/9_QA.pdf -------------------------------------------------------------------------------- /lectures/multilingual_dependency_parsing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/lectures/multilingual_dependency_parsing.pdf -------------------------------------------------------------------------------- /seminars/sem12_active_learning/active_learning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem12_active_learning/active_learning.png -------------------------------------------------------------------------------- /seminars/sem12_active_learning/sem12-active-learning.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Active Learning" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Активное обучение $-$ класс алгоритмов обучения моделей машинного обучения. Алгоритмы активного обучения отличаются тем, могут интерактивно запрашивать пользователя (или некоторый другой источник информации) для разметки новых примеров данных." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Active Learning Strategies" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "#### Pool-Based Sampling" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "В этом сценарии экземпляры извлекаются из всего пула данных и им присваивается информативная оценка, которая показывает, насколько хорошо текущий алгоритм «понимает» данные. \n", 43 | "\n", 44 | "Затем система выбираются и размечаются наиболее информативные примеры." 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "#### Uncertainty sampling" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "\n", 59 | "В рамках этого алгоритма размечаются те примеры, на которых текущая модель наименее уверена.\n", 60 | "\n", 61 | "В качестве функций \"уверенности\" можно использовать вероятности классов или расстояния до разделяющей гиперплоскости." 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "#### Membership Query Synthesis" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "Здесь алгритм обучения модели генерирует свои собственные примеры из некоторого настраиваемого распределения. \n", 76 | "Эти сгенерированные примеры отправляются на разметку и модель дообучается с учетом разметки этих примеров." 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "#### Query by Committee" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "Идея: построить ансамбль моделей $a_1,...,a_T$. \n", 91 | "\n", 92 | "Выбирать новые объекты $x_i$ с наибольшей несогласованностью решений ансамбля моделей.\n", 93 | "\n" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "Принцип максимума энтропии: выбираем $x_i$, на котором $a_t(x_i)$ максимально различны." 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Принцип максимума средней $KL$-дивергенции:выбираем $x_i$ , на котором $P_t(y|x_i)$ максимально различны:\n", 108 | "\n", 109 | "$С(y|u) = \\frac{1}{T}\\sum_{t=1}^T P_t(y|u)$ - консенсус комитета " 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "## SVM для Active Learning" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "Некоторые активные алгоритмы обучения построены на алгоритме SVM и используют структуру SVM для определения того, какие точки данных нужно размечать. \n", 124 | "\n", 125 | "SVM используется для определения уверенности модели в предсказании на каждом из примеров выборки. \n", 126 | "В качестве меры уверенности служит расстояние от объекта до построенной не текущей итерации разделяющей гиперплоскости." 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "## Active Learning for texts classification" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "Рассмотрим алгоритм pool-based active learning на примере задачи классификации твитов по тональности." 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "\n", 148 | "1. Разделить данные на X_pool (выборка, которую можно размечать) и X_test.\n", 149 | "2. Выбрать $k$ примеров из X_pool для начального X_train и разметить их. Остальные данные в X_pool $-$ валидационное множество. \n", 150 | "3. Обучить модель на X_train.\n", 151 | "5. Сделать predict обученной моделью на X_pool, вычислить вероятности для каждого $x_i$.\n", 152 | "6. Вычислить качество работы модели на X_test.\n", 153 | "7. Выбрать $k$ наиболее информативных объектов из X_pool, основываясь на уверенности модели в каждом из объектов (например, вероятности классов).\n", 154 | "8. Переменести эти $k$ выбранных объектов в X_train.\n", 155 | "9. Если качество работы модели на X_test достаточное, то останавливаемся, иначе возвращаемся к шагу 3." 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 1, 161 | "metadata": {}, 162 | "outputs": [], 163 | "source": [ 164 | "from sklearn.metrics import f1_score" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 2, 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "import pandas as pd\n", 174 | "import numpy as np\n", 175 | "from sklearn.metrics import *\n", 176 | "from sklearn.model_selection import train_test_split\n", 177 | "from sklearn.pipeline import Pipeline\n", 178 | "from nltk import ngrams\n", 179 | "\n", 180 | "from sklearn.linear_model import LogisticRegression \n", 181 | "from sklearn.feature_extraction.text import CountVectorizer" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 4, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "(5572, 2)\n" 194 | ] 195 | }, 196 | { 197 | "data": { 198 | "text/html": [ 199 | "
\n", 200 | "\n", 213 | "\n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | "
CategoryMessage
0hamGo until jurong point, crazy.. Available only ...
1hamOk lar... Joking wif u oni...
2spamFree entry in 2 a wkly comp to win FA Cup fina...
3hamU dun say so early hor... U c already then say...
4hamNah I don't think he goes to usf, he lives aro...
\n", 249 | "
" 250 | ], 251 | "text/plain": [ 252 | " Category Message\n", 253 | "0 ham Go until jurong point, crazy.. Available only ...\n", 254 | "1 ham Ok lar... Joking wif u oni...\n", 255 | "2 spam Free entry in 2 a wkly comp to win FA Cup fina...\n", 256 | "3 ham U dun say so early hor... U c already then say...\n", 257 | "4 ham Nah I don't think he goes to usf, he lives aro..." 258 | ] 259 | }, 260 | "execution_count": 4, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "df = pd.read_csv('spam_text_classification_data.csv')\n", 267 | "print(df.shape)\n", 268 | "df.head()" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 5, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "df['label'] = [0 if category == 'ham' else 1 for category in df['Category']]" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 20, 283 | "metadata": {}, 284 | "outputs": [], 285 | "source": [ 286 | "X,X_test,y,y_test = train_test_split(np.array(df['Message']), np.array(df['label']))" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 21, 292 | "metadata": {}, 293 | "outputs": [], 294 | "source": [ 295 | "def get_confidence(class_probs):\n", 296 | " return abs(0.5-class_probs[0])" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 22, 302 | "metadata": {}, 303 | "outputs": [ 304 | { 305 | "name": "stdout", 306 | "output_type": "stream", 307 | "text": [ 308 | "50 train samples\n", 309 | " precision recall f1-score support\n", 310 | "\n", 311 | " 0 1.00 0.89 0.94 1338\n", 312 | " 1 0.25 0.91 0.39 55\n", 313 | "\n", 314 | " micro avg 0.89 0.89 0.89 1393\n", 315 | " macro avg 0.62 0.90 0.66 1393\n", 316 | "weighted avg 0.97 0.89 0.92 1393\n", 317 | "\n", 318 | "60 train samples\n", 319 | " precision recall f1-score support\n", 320 | "\n", 321 | " 0 0.99 0.91 0.95 1292\n", 322 | " 1 0.42 0.84 0.56 101\n", 323 | "\n", 324 | " micro avg 0.91 0.91 0.91 1393\n", 325 | " macro avg 0.70 0.88 0.75 1393\n", 326 | "weighted avg 0.95 0.91 0.92 1393\n", 327 | "\n", 328 | "70 train samples\n", 329 | " precision recall f1-score support\n", 330 | "\n", 331 | " 0 0.98 0.94 0.96 1250\n", 332 | " 1 0.61 0.85 0.71 143\n", 333 | "\n", 334 | " micro avg 0.93 0.93 0.93 1393\n", 335 | " macro avg 0.79 0.89 0.83 1393\n", 336 | "weighted avg 0.94 0.93 0.93 1393\n", 337 | "\n", 338 | "80 train samples\n", 339 | " precision recall f1-score support\n", 340 | "\n", 341 | " 0 0.99 0.95 0.97 1237\n", 342 | " 1 0.71 0.91 0.80 156\n", 343 | "\n", 344 | " micro avg 0.95 0.95 0.95 1393\n", 345 | " macro avg 0.85 0.93 0.88 1393\n", 346 | "weighted avg 0.96 0.95 0.95 1393\n", 347 | "\n", 348 | "90 train samples\n", 349 | " precision recall f1-score support\n", 350 | "\n", 351 | " 0 0.98 0.97 0.98 1214\n", 352 | " 1 0.80 0.90 0.85 179\n", 353 | "\n", 354 | " micro avg 0.96 0.96 0.96 1393\n", 355 | " macro avg 0.89 0.93 0.91 1393\n", 356 | "weighted avg 0.96 0.96 0.96 1393\n", 357 | "\n", 358 | "100 train samples\n", 359 | " precision recall f1-score support\n", 360 | "\n", 361 | " 0 0.99 0.96 0.98 1222\n", 362 | " 1 0.79 0.92 0.85 171\n", 363 | "\n", 364 | " micro avg 0.96 0.96 0.96 1393\n", 365 | " macro avg 0.89 0.94 0.91 1393\n", 366 | "weighted avg 0.96 0.96 0.96 1393\n", 367 | "\n", 368 | "110 train samples\n", 369 | " precision recall f1-score support\n", 370 | "\n", 371 | " 0 0.99 0.97 0.98 1229\n", 372 | " 1 0.79 0.96 0.87 164\n", 373 | "\n", 374 | " micro avg 0.96 0.96 0.96 1393\n", 375 | " macro avg 0.89 0.96 0.92 1393\n", 376 | "weighted avg 0.97 0.96 0.97 1393\n", 377 | "\n", 378 | "120 train samples\n", 379 | " precision recall f1-score support\n", 380 | "\n", 381 | " 0 1.00 0.96 0.98 1233\n", 382 | " 1 0.77 0.97 0.86 160\n", 383 | "\n", 384 | " micro avg 0.96 0.96 0.96 1393\n", 385 | " macro avg 0.88 0.97 0.92 1393\n", 386 | "weighted avg 0.97 0.96 0.97 1393\n", 387 | "\n", 388 | "130 train samples\n", 389 | " precision recall f1-score support\n", 390 | "\n", 391 | " 0 0.99 0.97 0.98 1213\n", 392 | " 1 0.82 0.92 0.87 180\n", 393 | "\n", 394 | " micro avg 0.96 0.96 0.96 1393\n", 395 | " macro avg 0.90 0.94 0.92 1393\n", 396 | "weighted avg 0.97 0.96 0.96 1393\n", 397 | "\n", 398 | "140 train samples\n", 399 | " precision recall f1-score support\n", 400 | "\n", 401 | " 0 1.00 0.97 0.98 1221\n", 402 | " 1 0.84 0.98 0.90 172\n", 403 | "\n", 404 | " micro avg 0.97 0.97 0.97 1393\n", 405 | " macro avg 0.92 0.97 0.94 1393\n", 406 | "weighted avg 0.98 0.97 0.97 1393\n", 407 | "\n", 408 | "150 train samples\n", 409 | " precision recall f1-score support\n", 410 | "\n", 411 | " 0 1.00 0.97 0.98 1226\n", 412 | " 1 0.82 0.99 0.90 167\n", 413 | "\n", 414 | " micro avg 0.97 0.97 0.97 1393\n", 415 | " macro avg 0.91 0.98 0.94 1393\n", 416 | "weighted avg 0.98 0.97 0.97 1393\n", 417 | "\n", 418 | "160 train samples\n", 419 | " precision recall f1-score support\n", 420 | "\n", 421 | " 0 1.00 0.97 0.99 1226\n", 422 | " 1 0.83 0.99 0.90 167\n", 423 | "\n", 424 | " micro avg 0.97 0.97 0.97 1393\n", 425 | " macro avg 0.91 0.98 0.94 1393\n", 426 | "weighted avg 0.98 0.97 0.98 1393\n", 427 | "\n", 428 | "170 train samples\n", 429 | " precision recall f1-score support\n", 430 | "\n", 431 | " 0 1.00 0.97 0.99 1223\n", 432 | " 1 0.85 1.00 0.92 170\n", 433 | "\n", 434 | " micro avg 0.98 0.98 0.98 1393\n", 435 | " macro avg 0.92 0.99 0.95 1393\n", 436 | "weighted avg 0.98 0.98 0.98 1393\n", 437 | "\n", 438 | "180 train samples\n", 439 | " precision recall f1-score support\n", 440 | "\n", 441 | " 0 1.00 0.98 0.99 1221\n", 442 | " 1 0.86 1.00 0.92 172\n", 443 | "\n", 444 | " micro avg 0.98 0.98 0.98 1393\n", 445 | " macro avg 0.93 0.99 0.96 1393\n", 446 | "weighted avg 0.98 0.98 0.98 1393\n", 447 | "\n", 448 | "190 train samples\n", 449 | " precision recall f1-score support\n", 450 | "\n", 451 | " 0 1.00 0.98 0.99 1216\n", 452 | " 1 0.87 0.99 0.93 177\n", 453 | "\n", 454 | " micro avg 0.98 0.98 0.98 1393\n", 455 | " macro avg 0.93 0.98 0.96 1393\n", 456 | "weighted avg 0.98 0.98 0.98 1393\n", 457 | "\n", 458 | "200 train samples\n", 459 | " precision recall f1-score support\n", 460 | "\n", 461 | " 0 1.00 0.98 0.99 1216\n", 462 | " 1 0.87 0.99 0.93 177\n", 463 | "\n", 464 | " micro avg 0.98 0.98 0.98 1393\n", 465 | " macro avg 0.93 0.98 0.96 1393\n", 466 | "weighted avg 0.98 0.98 0.98 1393\n", 467 | "\n", 468 | "210 train samples\n", 469 | " precision recall f1-score support\n", 470 | "\n", 471 | " 0 1.00 0.98 0.99 1215\n", 472 | " 1 0.87 0.98 0.92 178\n", 473 | "\n", 474 | " micro avg 0.98 0.98 0.98 1393\n", 475 | " macro avg 0.93 0.98 0.96 1393\n", 476 | "weighted avg 0.98 0.98 0.98 1393\n", 477 | "\n", 478 | "220 train samples\n", 479 | " precision recall f1-score support\n", 480 | "\n", 481 | " 0 1.00 0.98 0.99 1217\n", 482 | " 1 0.88 1.00 0.93 176\n", 483 | "\n", 484 | " micro avg 0.98 0.98 0.98 1393\n", 485 | " macro avg 0.94 0.99 0.96 1393\n", 486 | "weighted avg 0.98 0.98 0.98 1393\n", 487 | "\n", 488 | "230 train samples\n", 489 | " precision recall f1-score support\n", 490 | "\n", 491 | " 0 1.00 0.98 0.99 1215\n", 492 | " 1 0.89 1.00 0.94 178\n", 493 | "\n", 494 | " micro avg 0.98 0.98 0.98 1393\n", 495 | " macro avg 0.94 0.99 0.96 1393\n", 496 | "weighted avg 0.99 0.98 0.98 1393\n", 497 | "\n", 498 | "240 train samples\n", 499 | " precision recall f1-score support\n", 500 | "\n", 501 | " 0 1.00 0.98 0.99 1214\n", 502 | " 1 0.88 0.99 0.93 179\n", 503 | "\n", 504 | " micro avg 0.98 0.98 0.98 1393\n", 505 | " macro avg 0.94 0.98 0.96 1393\n", 506 | "weighted avg 0.98 0.98 0.98 1393\n", 507 | "\n", 508 | "250 train samples\n", 509 | " precision recall f1-score support\n", 510 | "\n", 511 | " 0 1.00 0.98 0.99 1209\n", 512 | " 1 0.89 0.97 0.93 184\n", 513 | "\n", 514 | " micro avg 0.98 0.98 0.98 1393\n", 515 | " macro avg 0.94 0.98 0.96 1393\n", 516 | "weighted avg 0.98 0.98 0.98 1393\n", 517 | "\n", 518 | "260 train samples\n", 519 | " precision recall f1-score support\n", 520 | "\n", 521 | " 0 1.00 0.98 0.99 1214\n", 522 | " 1 0.88 0.99 0.93 179\n", 523 | "\n", 524 | " micro avg 0.98 0.98 0.98 1393\n", 525 | " macro avg 0.94 0.98 0.96 1393\n", 526 | "weighted avg 0.98 0.98 0.98 1393\n", 527 | "\n", 528 | "270 train samples\n", 529 | " precision recall f1-score support\n", 530 | "\n", 531 | " 0 1.00 0.98 0.99 1214\n", 532 | " 1 0.88 0.99 0.93 179\n", 533 | "\n", 534 | " micro avg 0.98 0.98 0.98 1393\n", 535 | " macro avg 0.94 0.98 0.96 1393\n", 536 | "weighted avg 0.98 0.98 0.98 1393\n", 537 | "\n", 538 | "280 train samples\n", 539 | " precision recall f1-score support\n", 540 | "\n", 541 | " 0 1.00 0.98 0.99 1212\n", 542 | " 1 0.89 0.98 0.93 181\n", 543 | "\n", 544 | " micro avg 0.98 0.98 0.98 1393\n", 545 | " macro avg 0.94 0.98 0.96 1393\n", 546 | "weighted avg 0.98 0.98 0.98 1393\n", 547 | "\n", 548 | "290 train samples\n", 549 | " precision recall f1-score support\n", 550 | "\n", 551 | " 0 1.00 0.98 0.99 1215\n", 552 | " 1 0.88 0.99 0.93 178\n", 553 | "\n", 554 | " micro avg 0.98 0.98 0.98 1393\n", 555 | " macro avg 0.94 0.98 0.96 1393\n", 556 | "weighted avg 0.98 0.98 0.98 1393\n", 557 | "\n" 558 | ] 559 | }, 560 | { 561 | "name": "stdout", 562 | "output_type": "stream", 563 | "text": [ 564 | "300 train samples\n", 565 | " precision recall f1-score support\n", 566 | "\n", 567 | " 0 1.00 0.98 0.99 1215\n", 568 | " 1 0.88 0.99 0.93 178\n", 569 | "\n", 570 | " micro avg 0.98 0.98 0.98 1393\n", 571 | " macro avg 0.94 0.99 0.96 1393\n", 572 | "weighted avg 0.98 0.98 0.98 1393\n", 573 | "\n", 574 | "310 train samples\n", 575 | " precision recall f1-score support\n", 576 | "\n", 577 | " 0 1.00 0.98 0.99 1214\n", 578 | " 1 0.89 0.99 0.94 179\n", 579 | "\n", 580 | " micro avg 0.98 0.98 0.98 1393\n", 581 | " macro avg 0.94 0.99 0.96 1393\n", 582 | "weighted avg 0.98 0.98 0.98 1393\n", 583 | "\n", 584 | "320 train samples\n", 585 | " precision recall f1-score support\n", 586 | "\n", 587 | " 0 1.00 0.98 0.99 1213\n", 588 | " 1 0.89 0.99 0.93 180\n", 589 | "\n", 590 | " micro avg 0.98 0.98 0.98 1393\n", 591 | " macro avg 0.94 0.98 0.96 1393\n", 592 | "weighted avg 0.98 0.98 0.98 1393\n", 593 | "\n", 594 | "330 train samples\n", 595 | " precision recall f1-score support\n", 596 | "\n", 597 | " 0 1.00 0.98 0.99 1213\n", 598 | " 1 0.89 0.99 0.94 180\n", 599 | "\n", 600 | " micro avg 0.98 0.98 0.98 1393\n", 601 | " macro avg 0.94 0.99 0.97 1393\n", 602 | "weighted avg 0.99 0.98 0.98 1393\n", 603 | "\n", 604 | "340 train samples\n", 605 | " precision recall f1-score support\n", 606 | "\n", 607 | " 0 1.00 0.98 0.99 1212\n", 608 | " 1 0.89 0.99 0.94 181\n", 609 | "\n", 610 | " micro avg 0.98 0.98 0.98 1393\n", 611 | " macro avg 0.94 0.99 0.96 1393\n", 612 | "weighted avg 0.98 0.98 0.98 1393\n", 613 | "\n", 614 | "350 train samples\n", 615 | " precision recall f1-score support\n", 616 | "\n", 617 | " 0 1.00 0.98 0.99 1211\n", 618 | " 1 0.90 0.99 0.95 182\n", 619 | "\n", 620 | " micro avg 0.98 0.98 0.98 1393\n", 621 | " macro avg 0.95 0.99 0.97 1393\n", 622 | "weighted avg 0.99 0.98 0.99 1393\n", 623 | "\n", 624 | "360 train samples\n", 625 | " precision recall f1-score support\n", 626 | "\n", 627 | " 0 1.00 0.98 0.99 1212\n", 628 | " 1 0.90 0.99 0.94 181\n", 629 | "\n", 630 | " micro avg 0.98 0.98 0.98 1393\n", 631 | " macro avg 0.95 0.99 0.97 1393\n", 632 | "weighted avg 0.99 0.98 0.98 1393\n", 633 | "\n", 634 | "370 train samples\n", 635 | " precision recall f1-score support\n", 636 | "\n", 637 | " 0 1.00 0.99 0.99 1209\n", 638 | " 1 0.91 0.99 0.95 184\n", 639 | "\n", 640 | " micro avg 0.99 0.99 0.99 1393\n", 641 | " macro avg 0.95 0.99 0.97 1393\n", 642 | "weighted avg 0.99 0.99 0.99 1393\n", 643 | "\n" 644 | ] 645 | } 646 | ], 647 | "source": [ 648 | "train_size = 50\n", 649 | "\n", 650 | "dataset_size = X.shape[0]\n", 651 | "target_score = 0.95\n", 652 | "score = 0\n", 653 | "step = 10\n", 654 | "\n", 655 | "X_train = X[:train_size]\n", 656 | "y_train = y[:train_size]\n", 657 | "X_pool = X[train_size:]\n", 658 | "y_pool = y[train_size:]\n", 659 | "\n", 660 | "scores = [0]\n", 661 | "train_szs = [0]\n", 662 | "\n", 663 | "while score < target_score and train_size <= dataset_size:\n", 664 | " vec = CountVectorizer(ngram_range=(1, 1))\n", 665 | " bow = vec.fit_transform(X_train)\n", 666 | " clf = LogisticRegression()\n", 667 | " clf = clf.fit(bow,y_train)\n", 668 | " pred = clf.predict(vec.transform(X_test))\n", 669 | " \n", 670 | " print(\"{0} train samples\".format(train_size))\n", 671 | " print(classification_report(pred, y_test))\n", 672 | " score = f1_score(pred, y_test)\n", 673 | " scores.append(score)\n", 674 | " train_szs.append(train_size)\n", 675 | " \n", 676 | " pred_probs = clf.predict_proba(vec.transform(X_pool))\n", 677 | " confidences = [get_confidence(probs) for probs in pred_probs]\n", 678 | " \n", 679 | " X_train = np.concatenate([X_train, X_pool[np.argsort(confidences)[:step]]])\n", 680 | " y_train = np.concatenate([y_train, y_pool[np.argsort(confidences)[:step]]])\n", 681 | " X_pool = X_pool[sorted(np.argsort(confidences)[step:])]\n", 682 | " y_pool = y_pool[sorted(np.argsort(confidences)[step:])]\n", 683 | " train_size += step" 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "execution_count": 23, 689 | "metadata": {}, 690 | "outputs": [ 691 | { 692 | "name": "stdout", 693 | "output_type": "stream", 694 | "text": [ 695 | "4179 train samples\n", 696 | " precision recall f1-score support\n", 697 | "\n", 698 | " 0 1.00 0.98 0.99 1215\n", 699 | " 1 0.88 0.99 0.93 178\n", 700 | "\n", 701 | " micro avg 0.98 0.98 0.98 1393\n", 702 | " macro avg 0.94 0.99 0.96 1393\n", 703 | "weighted avg 0.98 0.98 0.98 1393\n", 704 | "\n" 705 | ] 706 | } 707 | ], 708 | "source": [ 709 | "vec = CountVectorizer(ngram_range=(1, 1))\n", 710 | "bow = vec.fit_transform(X)\n", 711 | "clf = clf.fit(bow,y)\n", 712 | "pred = clf.predict(vec.transform(X_test))\n", 713 | "\n", 714 | "print(\"{0} train samples\".format(dataset_size))\n", 715 | "print(classification_report(pred, y_test))" 716 | ] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "execution_count": 24, 721 | "metadata": {}, 722 | "outputs": [], 723 | "source": [ 724 | "from matplotlib import pyplot as plt\n", 725 | "\n", 726 | "%matplotlib inline" 727 | ] 728 | }, 729 | { 730 | "cell_type": "code", 731 | "execution_count": 25, 732 | "metadata": {}, 733 | "outputs": [ 734 | { 735 | "data": { 736 | "text/plain": [ 737 | "[]" 738 | ] 739 | }, 740 | "execution_count": 25, 741 | "metadata": {}, 742 | "output_type": "execute_result" 743 | }, 744 | { 745 | "data": { 746 | "image/png": "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\n", 747 | "text/plain": [ 748 | "
" 749 | ] 750 | }, 751 | "metadata": { 752 | "needs_background": "light" 753 | }, 754 | "output_type": "display_data" 755 | } 756 | ], 757 | "source": [ 758 | "plt.plot(train_szs,scores)\n", 759 | "plt.plot(train_szs, [0.95 for sz in train_szs])" 760 | ] 761 | }, 762 | { 763 | "cell_type": "markdown", 764 | "metadata": {}, 765 | "source": [ 766 | "Можно видеть, что для достижения лучшего качества на этом датасете дсотаточно обучиться на 300 правильно выбранных примерах." 767 | ] 768 | }, 769 | { 770 | "cell_type": "code", 771 | "execution_count": null, 772 | "metadata": {}, 773 | "outputs": [], 774 | "source": [] 775 | } 776 | ], 777 | "metadata": { 778 | "kernelspec": { 779 | "display_name": "Python 3", 780 | "language": "python", 781 | "name": "python3" 782 | }, 783 | "language_info": { 784 | "codemirror_mode": { 785 | "name": "ipython", 786 | "version": 3 787 | }, 788 | "file_extension": ".py", 789 | "mimetype": "text/x-python", 790 | "name": "python", 791 | "nbconvert_exporter": "python", 792 | "pygments_lexer": "ipython3", 793 | "version": "3.7.1" 794 | } 795 | }, 796 | "nbformat": 4, 797 | "nbformat_minor": 2 798 | } 799 | -------------------------------------------------------------------------------- /seminars/sem13/text_generation_seqGAN.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem13/text_generation_seqGAN.pdf -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/.DS_Store -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/LSTM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/LSTM.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/LSTM_rnn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/LSTM_rnn.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/bilstm_crf_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/bilstm_crf_model.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/dino.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/dino.jpg -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/dino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/dino.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/dinos3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/dinos3.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/rnn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/rnn.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/rnn_cell_backprop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/rnn_cell_backprop.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/rnn_step_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/rnn_step_forward.png -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/understanding_lstms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/understanding_lstms.jpg -------------------------------------------------------------------------------- /seminars/sem4_language_models/images/word_representation_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem4_language_models/images/word_representation_model.png -------------------------------------------------------------------------------- /seminars/sem5_syntax/constituency_parsing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem5_syntax/constituency_parsing.png -------------------------------------------------------------------------------- /seminars/sem5_syntax/recursiveNN.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem5_syntax/recursiveNN.jpg -------------------------------------------------------------------------------- /seminars/sem5_syntax/recursiveNN_formula.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem5_syntax/recursiveNN_formula.jpg -------------------------------------------------------------------------------- /seminars/sem5_syntax/rus_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem5_syntax/rus_tree.png -------------------------------------------------------------------------------- /seminars/sem5_syntax/sem5_syntax.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Depencency parsing\n", 8 | "(парсинг зависимостей)\n", 9 | "\n", 10 | "### Что это?\n", 11 | "\n", 12 | "* наша цель -- представить предложение естественного языка в виде дерева\n", 13 | "* слова предложения -- вершины; *зависимости (dependencies)* между ними -- рёбра\n", 14 | "* зависимости могут быть разными: например, субъект глагола, объект глагола, прилагательное-модификатор, и так далее\n", 15 | "\n", 16 | "### Формат\n", 17 | "\n", 18 | "Существует несколько форматов записи деревьев зависимостей, но самый популярный и общеиспользуемый -- [CoNLL-U](http://universaldependencies.org/format.html).
\n", 19 | "Как это выглядит (пример из [русского Universal Dependency трибанка](https://github.com/UniversalDependencies/UD_Russian-SynTagRus)):" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "my_example = \"\"\"\n", 29 | "# sent_id = 2003Armeniya.xml_138\n", 30 | "# text = Перспективы развития сферы высоких технологий.\n", 31 | "1\tПерспективы\tперспектива\tNOUN\t_\tAnimacy=Inan|Case=Nom|Gender=Fem|Number=Plur\t0\tROOT\t0:root\t_\n", 32 | "2\tразвития\tразвитие\tNOUN\t_\tAnimacy=Inan|Case=Gen|Gender=Neut|Number=Sing\t1\tnmod\t1:nmod\t_\n", 33 | "3\tсферы\tсфера\tNOUN\t_\tAnimacy=Inan|Case=Gen|Gender=Fem|Number=Sing\t2\tnmod\t2:nmod\t_\n", 34 | "4\tвысоких\tвысокий\tADJ\t_\tCase=Gen|Degree=Pos|Number=Plur\t5\tamod\t5:amod\t_\n", 35 | "5\tтехнологий\tтехнология\tNOUN\t_\tAnimacy=Inan|Case=Gen|Gender=Fem|Number=Plur\t3\tnmod\t3:nmod\tSpaceAfter=No\n", 36 | "6\t.\t.\tPUNCT\t_\t_\t1\tpunct\t1:punct\t_\n", 37 | "\"\"\"" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "Комментарии + таблица c 9 колонками (разделители табы):\n", 45 | "* ID\n", 46 | "* FORM: токен\n", 47 | "* LEMMA: начальная форма\n", 48 | "* UPOS: универсальная часть речи\n", 49 | "* XPOS: лингво-специфичная часть речи\n", 50 | "* FEATS: морфологическая информация: падеж, род, число etc\n", 51 | "* HEAD: id ролителя\n", 52 | "* DEPREL: тип зависимости, то есть отношение к токену-родителю\n", 53 | "* DEPS: альтернативный подграф (не будем углубляться :))\n", 54 | "* MISC: всё остальное\n", 55 | "\n", 56 | "Отсутствующие данные представляются с помощью `_`. Больше подробностей про формат -- в [официальной документаци](http://universaldependencies.org/format.html).
\n", 57 | "User-friendly визуализация: ![2003Armeniya.xml_138](rus_tree.png)\n", 58 | "\n", 59 | "Отрытый инструмент для визуализации, ручной разметки и конвертации в другие форматы: UD Annotatrix. [Online-интерфейс](https://universal-dependencies.linghub.net/annotatrix), [репозиторий](https://github.com/jonorthwash/ud-annotatrix).\n", 60 | "\n", 61 | "Трибанк -- много таких предложений. Обычно они разделяются двумя переносами строки.\n", 62 | "### Как считывать данные в питоне\n", 63 | "\n", 64 | "Используем библиотеку [conllu](https://github.com/EmilStenstrom/conllu)." 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 2, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "Collecting conllu\n", 77 | " Downloading https://files.pythonhosted.org/packages/9e/34/ddfbf22e7477a75ca609d60a831452439383e4ab61bed2b5a1b83d1eef5b/conllu-2.0-py2.py3-none-any.whl\n", 78 | "Installing collected packages: conllu\n", 79 | "Successfully installed conllu-2.0\n", 80 | "\u001b[33mYou are using pip version 8.1.1, however version 19.2.3 is available.\n", 81 | "You should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n" 82 | ] 83 | } 84 | ], 85 | "source": [ 86 | "!pip3 install conllu" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 6, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "from conllu import parse" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 3, 101 | "metadata": {}, 102 | "outputs": [ 103 | { 104 | "name": "stdout", 105 | "output_type": "stream", 106 | "text": [ 107 | "Help on function parse in module conllu:\n", 108 | "\n", 109 | "parse(data, fields=None, field_parsers=None)\n", 110 | "\n" 111 | ] 112 | } 113 | ], 114 | "source": [ 115 | "help(parse)" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "data": { 125 | "text/plain": [ 126 | "OrderedDict([('id', 1),\n", 127 | " ('form', 'Перспективы'),\n", 128 | " ('lemma', 'перспектива'),\n", 129 | " ('upostag', 'NOUN'),\n", 130 | " ('xpostag', None),\n", 131 | " ('feats',\n", 132 | " OrderedDict([('Animacy', 'Inan'),\n", 133 | " ('Case', 'Nom'),\n", 134 | " ('Gender', 'Fem'),\n", 135 | " ('Number', 'Plur')])),\n", 136 | " ('head', 0),\n", 137 | " ('deprel', 'ROOT'),\n", 138 | " ('deps', '0:root'),\n", 139 | " ('misc', None)])" 140 | ] 141 | }, 142 | "execution_count": 4, 143 | "metadata": {}, 144 | "output_type": "execute_result" 145 | } 146 | ], 147 | "source": [ 148 | "sentences = parse(my_example)\n", 149 | "sentence = sentences[0]\n", 150 | "sentence[0]" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 5, 156 | "metadata": {}, 157 | "outputs": [ 158 | { 159 | "data": { 160 | "text/plain": [ 161 | "OrderedDict([('id', 6),\n", 162 | " ('form', '.'),\n", 163 | " ('lemma', '.'),\n", 164 | " ('upostag', 'PUNCT'),\n", 165 | " ('xpostag', None),\n", 166 | " ('feats', None),\n", 167 | " ('head', 1),\n", 168 | " ('deprel', 'punct'),\n", 169 | " ('deps', [('punct', 1)]),\n", 170 | " ('misc', None)])" 171 | ] 172 | }, 173 | "execution_count": 5, 174 | "metadata": {}, 175 | "output_type": "execute_result" 176 | } 177 | ], 178 | "source": [ 179 | "sentence[-1]" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "## Визуализация\n", 187 | "\n", 188 | "В nltk есть DependencyGraph, который умеет рисовать деревья (и ещё многое другое). Для того, чтобы визуализация работала корректно, ему нужна зависимость: graphviz." 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "!apt-get install graphviz\n", 198 | "!pip install graphviz" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 4, 204 | "metadata": {}, 205 | "outputs": [], 206 | "source": [ 207 | "from nltk import DependencyGraph" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "В отличие от `conllu`, `DependencyGraph` не справляется с комментариями, поэтому придётся их убрать. Кроме того ему обязательно нужен `deprel` *ROOT* в верхнем регистре, иначе он не находит корень." 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 5, 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "ename": "NameError", 224 | "evalue": "name 'my_example' is not defined", 225 | "output_type": "error", 226 | "traceback": [ 227 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 228 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 229 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0msents\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0msent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mmy_example\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\n\\n'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# убираем коменты\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0msent\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'\\n'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mline\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\n'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstartswith\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'#'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;31m# заменяем deprel для root\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 230 | "\u001b[0;31mNameError\u001b[0m: name 'my_example' is not defined" 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "sents = []\n", 236 | "for sent in my_example.split('\\n\\n'):\n", 237 | " # убираем коменты\n", 238 | " sent = '\\n'.join([line for line in sent.split('\\n') if not line.startswith('#')])\n", 239 | " # заменяем deprel для root\n", 240 | " sent = sent.replace('\\troot\\t', '\\tROOT\\t')\n", 241 | " sents.append(sent)" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": null, 247 | "metadata": {}, 248 | "outputs": [], 249 | "source": [ 250 | "graph = DependencyGraph(tree_str=sents[0])\n", 251 | "graph" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": null, 257 | "metadata": {}, 258 | "outputs": [], 259 | "source": [ 260 | "tree = graph.tree()\n", 261 | "print(tree.pretty_print())" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "## UDPipe\n", 269 | "\n", 270 | "Есть разные инструменты для парсинга зависимостей. Сегодня мы посмотрим на [UDPipe](http://ufal.mff.cuni.cz/udpipe). UDPipe умеет парсить текст с помощью готовых моделей (которые можно скачать [здесь](https://github.com/jwijffels/udpipe.models.ud.2.0/tree/master/inst/udpipe-ud-2.0-170801)) и обучать модели на своих трибанках.\n", 271 | "\n", 272 | "Собственно, в UDPipe есть три вида моделей:\n", 273 | "* токенизатор (разделить текст на предложения, предложения на токены, сделать заготовку для CoNLL-U)\n", 274 | "* тэггер (лемматизировать, разметить части речи)\n", 275 | "* сам парсер (проставить каждому токену `head` и `deprel`)\n", 276 | "\n", 277 | "Мы сегодня не будем обучать новых моделей (это слишком долго), а используем готовую модель для русского." 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "### The Python binding\n", 285 | "\n", 286 | "У udpipe есть питоновская обвязка. Она довольно [плохо задокументирована](https://pypi.org/project/ufal.udpipe/), но зато можно использовать прямо в питоне :)" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 1, 292 | "metadata": {}, 293 | "outputs": [ 294 | { 295 | "name": "stdout", 296 | "output_type": "stream", 297 | "text": [ 298 | "Requirement already satisfied: ufal.udpipe in /usr/local/lib/python3.5/dist-packages (1.2.0.1)\n", 299 | "\u001b[33mYou are using pip version 18.0, however version 18.1 is available.\n", 300 | "You should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n" 301 | ] 302 | } 303 | ], 304 | "source": [ 305 | "!pip install ufal.udpipe" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 11, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "from ufal.udpipe import Model, Pipeline" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 12, 320 | "metadata": {}, 321 | "outputs": [ 322 | { 323 | "name": "stdout", 324 | "output_type": "stream", 325 | "text": [ 326 | "--2019-09-29 23:23:05-- https://github.com/jwijffels/udpipe.models.ud.2.0/raw/master/inst/udpipe-ud-2.0-170801/russian-ud-2.0-170801.udpipe\n", 327 | "Resolving github.com (github.com)... 140.82.118.3\n", 328 | "Connecting to github.com (github.com)|140.82.118.3|:443... connected.\n", 329 | "HTTP request sent, awaiting response... 302 Found\n", 330 | "Location: https://raw.githubusercontent.com/jwijffels/udpipe.models.ud.2.0/master/inst/udpipe-ud-2.0-170801/russian-ud-2.0-170801.udpipe [following]\n", 331 | "--2019-09-29 23:23:06-- https://raw.githubusercontent.com/jwijffels/udpipe.models.ud.2.0/master/inst/udpipe-ud-2.0-170801/russian-ud-2.0-170801.udpipe\n", 332 | "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.244.133\n", 333 | "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.244.133|:443... connected.\n", 334 | "HTTP request sent, awaiting response... 200 OK\n", 335 | "Length: 13265262 (13M) [application/octet-stream]\n", 336 | "Saving to: ‘russian-ud-2.0-170801.udpipe’\n", 337 | "\n", 338 | "russian-ud-2.0-1708 100%[===================>] 12,65M 12,7MB/s in 1,0s \n", 339 | "\n", 340 | "2019-09-29 23:23:08 (12,7 MB/s) - ‘russian-ud-2.0-170801.udpipe’ saved [13265262/13265262]\n", 341 | "\n" 342 | ] 343 | } 344 | ], 345 | "source": [ 346 | "!wget https://github.com/jwijffels/udpipe.models.ud.2.0/raw/master/inst/udpipe-ud-2.0-170801/russian-ud-2.0-170801.udpipe" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 13, 352 | "metadata": {}, 353 | "outputs": [], 354 | "source": [ 355 | "model = Model.load(\"russian-ud-2.0-170801.udpipe\") # path to the model" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 14, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "data": { 365 | "text/plain": [ 366 | "" 367 | ] 368 | }, 369 | "execution_count": 14, 370 | "metadata": {}, 371 | "output_type": "execute_result" 372 | } 373 | ], 374 | "source": [ 375 | "# если успех, должно быть так (model != None)\n", 376 | "model" 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": 15, 382 | "metadata": {}, 383 | "outputs": [ 384 | { 385 | "name": "stdout", 386 | "output_type": "stream", 387 | "text": [ 388 | "# newdoc\n", 389 | "# newpar\n", 390 | "# sent_id = 1\n", 391 | "# text = Если бы мне платили каждый раз.\n", 392 | "1\tЕсли\tЕСЛИ\tSCONJ\tIN\t_\t4\tmark\t_\t_\n", 393 | "2\tбы\tБЫ\tPART\tRP\t_\t4\tdiscourse\t_\t_\n", 394 | "3\tмне\tЯ\tPRON\tPRP\tCase=Dat|Number=Sing|Person=1\t4\tiobj\t_\t_\n", 395 | "4\tплатили\tПЛАТИТЬ\tVERB\tVBC\tAspect=Imp|Mood=Ind|Number=Plur|Tense=Past|VerbForm=Fin\t0\troot\t_\t_\n", 396 | "5\tкаждый\tКАЖДЫЙ\tDET\tDT\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t6\tamod\t_\t_\n", 397 | "6\tраз\tРАЗ\tNOUN\tNN\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t4\tadvmod\t_\tSpaceAfter=No\n", 398 | "7\t.\t.\tPUNCT\t.\t_\t4\tpunct\t_\t_\n", 399 | "\n", 400 | "# sent_id = 2\n", 401 | "# text = Каждый раз, когда я думаю о тебе.\n", 402 | "1\tКаждый\tКАЖДЫЙ\tDET\tDT\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t2\tamod\t_\t_\n", 403 | "2\tраз\tРАЗ\tNOUN\tNN\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t6\tadvmod\t_\tSpaceAfter=No\n", 404 | "3\t,\t,\tPUNCT\t,\t_\t6\tpunct\t_\t_\n", 405 | "4\tкогда\tКОГДА\tADV\tWRB\t_\t6\tadvmod\t_\t_\n", 406 | "5\tя\tЯ\tPRON\tPRP\tCase=Nom|Number=Sing|Person=1\t6\tnsubj\t_\t_\n", 407 | "6\tдумаю\tдУМАТЬ\tVERB\tVBC\tAspect=Imp|Mood=Ind|Number=Sing|Person=1|Tense=Pres|VerbForm=Fin\t0\troot\t_\t_\n", 408 | "7\tо\tО\tADP\tIN\t_\t8\tcase\t_\t_\n", 409 | "8\tтебе\tТЫ\tPRON\tPRP\tCase=Dat|Number=Sing|Person=2\t6\tobl\t_\tSpaceAfter=No\n", 410 | "9\t.\t.\tPUNCT\t.\t_\t6\tpunct\t_\tSpacesAfter=\\n\n", 411 | "\n", 412 | "\n" 413 | ] 414 | } 415 | ], 416 | "source": [ 417 | "pipeline = Pipeline(model, 'generic_tokenizer', '', '', '')\n", 418 | "example = \"Если бы мне платили каждый раз. Каждый раз, когда я думаю о тебе.\"\n", 419 | "parsed = pipeline.process(example)\n", 420 | "print(parsed)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "Как видим, UDPipe и токенизировал, и лематизировал текст, сделал POS-tagging и, собственно, синтаксический парсинг." 428 | ] 429 | }, 430 | { 431 | "cell_type": "markdown", 432 | "metadata": {}, 433 | "source": [ 434 | "### Command line interface\n", 435 | "\n", 436 | "Но с обвязкой бывают проблемы, и вообще довольно удобно пользоваться прекомпилированной утилитой `udpipe` из шелла." 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": 22, 442 | "metadata": {}, 443 | "outputs": [ 444 | { 445 | "name": "stdout", 446 | "output_type": "stream", 447 | "text": [ 448 | "--2019-09-29 23:31:16-- https://github.com/ufal/udpipe/releases/download/v1.2.0/udpipe-1.2.0-bin.zip\n", 449 | "Resolving github.com (github.com)... 140.82.118.3\n", 450 | "Connecting to github.com (github.com)|140.82.118.3|:443... connected.\n", 451 | "HTTP request sent, awaiting response... 302 Found\n", 452 | "Location: https://github-production-release-asset-2e65be.s3.amazonaws.com/50672597/a24cacd8-77c6-11e7-8f6e-e9de8ca37f48?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20190929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190929T203116Z&X-Amz-Expires=300&X-Amz-Signature=844d153d7dc66e51f2aa43d0ee199e4a5d8f6b7e2755e3f50fc136597f8111c9&X-Amz-SignedHeaders=host&actor_id=0&response-content-disposition=attachment%3B%20filename%3Dudpipe-1.2.0-bin.zip&response-content-type=application%2Foctet-stream [following]\n", 453 | "--2019-09-29 23:31:17-- https://github-production-release-asset-2e65be.s3.amazonaws.com/50672597/a24cacd8-77c6-11e7-8f6e-e9de8ca37f48?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20190929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190929T203116Z&X-Amz-Expires=300&X-Amz-Signature=844d153d7dc66e51f2aa43d0ee199e4a5d8f6b7e2755e3f50fc136597f8111c9&X-Amz-SignedHeaders=host&actor_id=0&response-content-disposition=attachment%3B%20filename%3Dudpipe-1.2.0-bin.zip&response-content-type=application%2Foctet-stream\n", 454 | "Resolving github-production-release-asset-2e65be.s3.amazonaws.com (github-production-release-asset-2e65be.s3.amazonaws.com)... 52.216.170.107\n", 455 | "Connecting to github-production-release-asset-2e65be.s3.amazonaws.com (github-production-release-asset-2e65be.s3.amazonaws.com)|52.216.170.107|:443... connected.\n", 456 | "HTTP request sent, awaiting response... 200 OK\n", 457 | "Length: 12644197 (12M) [application/octet-stream]\n", 458 | "Saving to: ‘udpipe-1.2.0-bin.zip’\n", 459 | "\n", 460 | "udpipe-1.2.0-bin.zi 100%[===================>] 12,06M 3,49MB/s in 3,7s \n", 461 | "\n", 462 | "2019-09-29 23:31:21 (3,22 MB/s) - ‘udpipe-1.2.0-bin.zip’ saved [12644197/12644197]\n", 463 | "\n" 464 | ] 465 | } 466 | ], 467 | "source": [ 468 | "!wget https://github.com/ufal/udpipe/releases/download/v1.2.0/udpipe-1.2.0-bin.zip" 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": 26, 474 | "metadata": {}, 475 | "outputs": [], 476 | "source": [ 477 | "# !unzip udpipe-1.2.0-bin.zip" 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 2, 483 | "metadata": {}, 484 | "outputs": [ 485 | { 486 | "name": "stdout", 487 | "output_type": "stream", 488 | "text": [ 489 | "AUTHORS bin-linux64 bin-win64 LICENSE\t MANUAL.pdf src_lib_only\r\n", 490 | "bindings bin-osx\t CHANGES MANUAL\t README\r\n", 491 | "bin-linux32 bin-win32\t INSTALL MANUAL.html src\r\n" 492 | ] 493 | } 494 | ], 495 | "source": [ 496 | "!ls udpipe-1.2.0-bin/" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": {}, 502 | "source": [ 503 | "Внутри бинарники для всех популярных ОС, выбираем свою. У меня путь к бинарнику такой: `udpipe-1.2.0-bin/bin-linux64`.\n", 504 | "\n", 505 | "Синтаксис:" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 30, 511 | "metadata": {}, 512 | "outputs": [ 513 | { 514 | "name": "stdout", 515 | "output_type": "stream", 516 | "text": [ 517 | "Usage: udpipe-1.2.0-bin/bin-linux64/udpipe [running_opts] model_file [input_files]\r\n", 518 | " udpipe-1.2.0-bin/bin-linux64/udpipe --train [training_opts] model_file [input_files]\r\n", 519 | " udpipe-1.2.0-bin/bin-linux64/udpipe --detokenize [detokenize_opts] raw_text_file [input_files]\r\n", 520 | "Running opts: --accuracy (measure accuracy only)\r\n", 521 | " --input=[conllu|generic_tokenizer|horizontal|vertical]\r\n", 522 | " --immediate (process sentences immediately during loading)\r\n", 523 | " --outfile=output file template\r\n", 524 | " --output=[conllu|epe|matxin|horizontal|plaintext|vertical]\r\n", 525 | " --tokenize (perform tokenization)\r\n", 526 | " --tokenizer=tokenizer options, implies --tokenize\r\n", 527 | " --tag (perform tagging)\r\n", 528 | " --tagger=tagger options, implies --tag\r\n", 529 | " --parse (perform parsing)\r\n", 530 | " --parser=parser options, implies --parse\r\n", 531 | "Training opts: --method=[morphodita_parsito] which method to use\r\n", 532 | " --heldout=heldout data file name\r\n", 533 | " --tokenizer=tokenizer options\r\n", 534 | " --tagger=tagger options\r\n", 535 | " --parser=parser options\r\n", 536 | "Detokenize opts: --outfile=output file template\r\n", 537 | "Generic opts: --version\r\n", 538 | " --help\r\n" 539 | ] 540 | } 541 | ], 542 | "source": [ 543 | "! udpipe-1.2.0-bin/bin-linux64/udpipe --help" 544 | ] 545 | }, 546 | { 547 | "cell_type": "markdown", 548 | "metadata": {}, 549 | "source": [ 550 | "Типичная команда для парсинга будет выглядеть так:" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": 33, 556 | "metadata": {}, 557 | "outputs": [ 558 | { 559 | "name": "stdout", 560 | "output_type": "stream", 561 | "text": [ 562 | "Loading UDPipe model: done.\n", 563 | "# newdoc id = example.txt\n", 564 | "# newpar\n", 565 | "# sent_id = 1\n", 566 | "# text = Если бы мне платили каждый раз.\n", 567 | "1\tЕсли\tЕСЛИ\tSCONJ\tIN\t_\t4\tmark\t_\t_\n", 568 | "2\tбы\tБЫ\tPART\tRP\t_\t4\tdiscourse\t_\t_\n", 569 | "3\tмне\tЯ\tPRON\tPRP\tCase=Dat|Number=Sing|Person=1\t4\tiobj\t_\t_\n", 570 | "4\tплатили\tПЛАТИТЬ\tVERB\tVBC\tAspect=Imp|Mood=Ind|Number=Plur|Tense=Past|VerbForm=Fin\t0\troot\t_\t_\n", 571 | "5\tкаждый\tКАЖДЫЙ\tDET\tDT\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t6\tamod\t_\t_\n", 572 | "6\tраз\tРАЗ\tNOUN\tNN\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t4\tadvmod\t_\tSpaceAfter=No\n", 573 | "7\t.\t.\tPUNCT\t.\t_\t4\tpunct\t_\t_\n", 574 | "\n", 575 | "# sent_id = 2\n", 576 | "# text = Каждый раз, когда я думаю о тебе.\n", 577 | "1\tКаждый\tКАЖДЫЙ\tDET\tDT\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t2\tamod\t_\t_\n", 578 | "2\tраз\tРАЗ\tNOUN\tNN\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t6\tadvmod\t_\tSpaceAfter=No\n", 579 | "3\t,\t,\tPUNCT\t,\t_\t6\tpunct\t_\t_\n", 580 | "4\tкогда\tКОГДА\tADV\tWRB\t_\t6\tadvmod\t_\t_\n", 581 | "5\tя\tЯ\tPRON\tPRP\tCase=Nom|Number=Sing|Person=1\t6\tnsubj\t_\t_\n", 582 | "6\tдумаю\tдУМАТЬ\tVERB\tVBC\tAspect=Imp|Mood=Ind|Number=Sing|Person=1|Tense=Pres|VerbForm=Fin\t0\troot\t_\t_\n", 583 | "7\tо\tО\tADP\tIN\t_\t8\tcase\t_\t_\n", 584 | "8\tтебе\tТЫ\tPRON\tPRP\tCase=Dat|Number=Sing|Person=2\t6\tobl\t_\tSpaceAfter=No\n", 585 | "9\t.\t.\tPUNCT\t.\t_\t6\tpunct\t_\tSpacesAfter=\\n\n", 586 | "\n" 587 | ] 588 | } 589 | ], 590 | "source": [ 591 | "with open('example.txt', 'w') as f:\n", 592 | " f.write(example)\n", 593 | "\n", 594 | "! udpipe-1.2.0-bin/bin-linux64/udpipe --tokenize --tag --parse\\\n", 595 | " russian-ud-2.0-170801.udpipe example.txt > parsed_example.conllu\n", 596 | "! cat parsed_example.conllu" 597 | ] 598 | }, 599 | { 600 | "cell_type": "markdown", 601 | "metadata": {}, 602 | "source": [ 603 | "Если нас интересует только тэггинг:" 604 | ] 605 | }, 606 | { 607 | "cell_type": "code", 608 | "execution_count": 18, 609 | "metadata": {}, 610 | "outputs": [ 611 | { 612 | "name": "stdout", 613 | "output_type": "stream", 614 | "text": [ 615 | "Loading UDPipe model: done.\n", 616 | "# newdoc id = example.txt\n", 617 | "# newpar\n", 618 | "# sent_id = 1\n", 619 | "# text = Если бы мне платили каждый раз.\n", 620 | "1\tЕсли\tЕСЛИ\tSCONJ\tIN\t_\t_\t_\t_\t_\n", 621 | "2\tбы\tБЫ\tPART\tRP\t_\t_\t_\t_\t_\n", 622 | "3\tмне\tЯ\tPRON\tPRP\tCase=Dat|Number=Sing|Person=1\t_\t_\t_\t_\n", 623 | "4\tплатили\tПЛАТИТЬ\tVERB\tVBC\tAspect=Imp|Mood=Ind|Number=Plur|Tense=Past|VerbForm=Fin\t_\t_\t_\t_\n", 624 | "5\tкаждый\tКАЖДЫЙ\tDET\tDT\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t_\t_\t_\t_\n", 625 | "6\tраз\tРАЗ\tNOUN\tNN\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t_\t_\t_\tSpaceAfter=No\n", 626 | "7\t.\t.\tPUNCT\t.\t_\t_\t_\t_\t_\n", 627 | "\n", 628 | "# sent_id = 2\n", 629 | "# text = Каждый раз, когда я думаю о тебе.\n", 630 | "1\tКаждый\tКАЖДЫЙ\tDET\tDT\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t_\t_\t_\t_\n", 631 | "2\tраз\tРАЗ\tNOUN\tNN\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t_\t_\t_\tSpaceAfter=No\n", 632 | "3\t,\t,\tPUNCT\t,\t_\t_\t_\t_\t_\n", 633 | "4\tкогда\tКОГДА\tADV\tWRB\t_\t_\t_\t_\t_\n", 634 | "5\tя\tЯ\tPRON\tPRP\tCase=Nom|Number=Sing|Person=1\t_\t_\t_\t_\n", 635 | "6\tдумаю\tдУМАТЬ\tVERB\tVBC\tAspect=Imp|Mood=Ind|Number=Sing|Person=1|Tense=Pres|VerbForm=Fin\t_\t_\t_\t_\n", 636 | "7\tо\tО\tADP\tIN\t_\t_\t_\t_\t_\n", 637 | "8\tтебе\tТЫ\tPRON\tPRP\tCase=Dat|Number=Sing|Person=2\t_\t_\t_\tSpaceAfter=No\n", 638 | "9\t.\t.\tPUNCT\t.\t_\t_\t_\t_\tSpacesAfter=\\n\n", 639 | "\n" 640 | ] 641 | } 642 | ], 643 | "source": [ 644 | "with open('example.txt', 'w') as f:\n", 645 | " f.write(example)\n", 646 | "\n", 647 | "! udpipe-1.2.0-bin/bin-linux64/udpipe --tokenize --tag\\\n", 648 | " russian-ud-2.0-170801.udpipe example.txt > tagged_example.conllu\n", 649 | "! cat tagged_example.conllu" 650 | ] 651 | }, 652 | { 653 | "cell_type": "markdown", 654 | "metadata": {}, 655 | "source": [ 656 | "(Ну а потом снова считываем проанализированные предложения питоном).\n", 657 | "\n", 658 | "Вот два способа работать с UDPipe. Choose your fighter! " 659 | ] 660 | }, 661 | { 662 | "cell_type": "markdown", 663 | "metadata": {}, 664 | "source": [ 665 | "#### Задание\n", 666 | "\n", 667 | "Напишите функцию, которая проверяет, не состоит ли предложение из большого числа однородных предложений." 668 | ] 669 | }, 670 | { 671 | "cell_type": "code", 672 | "execution_count": null, 673 | "metadata": {}, 674 | "outputs": [], 675 | "source": [] 676 | }, 677 | { 678 | "cell_type": "markdown", 679 | "metadata": {}, 680 | "source": [ 681 | "## SVO-triples\n", 682 | "\n", 683 | "С помощью синтекстического парсинга можно извлекать из предложений тройки субъект-объект-глагол, которые можно использовать для извлечения информации из текста. " 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "execution_count": 7, 689 | "metadata": {}, 690 | "outputs": [], 691 | "source": [ 692 | "sent = \"\"\"1\tСобянин\t_\tNOUN\t_\tAnimacy=Anim|Case=Nom|Gender=Masc|Number=Sing|fPOS=NOUN++\t2\tnsubj\t_\t_\n", 693 | "2\tоткрыл\t_\tVERB\t_\tAspect=Perf|Gender=Masc|Mood=Ind|Number=Sing|Tense=Past|VerbForm=Fin|Voice=Act|fPOS=VERB++\t0\tROOT\t_\t_\n", 694 | "3\tновый\t_\tADJ\t_\tAnimacy=Inan|Case=Acc|Degree=Pos|Gender=Masc|Number=Sing|fPOS=ADJ++\t4\tamod\t_\t_\n", 695 | "4\tпарк\t_\tNOUN\t_\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing|fPOS=NOUN++\t2\tdobj\t_\t_\n", 696 | "5\tи\t_\tCONJ\t_\tfPOS=CONJ++\t4\tcc\t_\t_\n", 697 | "6\tдетскую\t_\tADJ\t_\tCase=Acc|Degree=Pos|Gender=Fem|Number=Sing|fPOS=ADJ++\t7\tamod\t_\t_\n", 698 | "7\tплощадку\t_\tNOUN\t_\tAnimacy=Inan|Case=Acc|Gender=Fem|Number=Sing|fPOS=NOUN++\t4\tconj\t_\t_\n", 699 | "8\t.\t_\tPUNCT\t.\tfPOS=PUNCT++.\t2\tpunct\t_\t_\"\"\"" 700 | ] 701 | }, 702 | { 703 | "cell_type": "markdown", 704 | "metadata": {}, 705 | "source": [ 706 | "Тройки слово-слово-связь:" 707 | ] 708 | }, 709 | { 710 | "cell_type": "code", 711 | "execution_count": 8, 712 | "metadata": {}, 713 | "outputs": [ 714 | { 715 | "data": { 716 | "text/plain": [ 717 | "[(('открыл', 'VERB'), 'nsubj', ('Собянин', 'NOUN')),\n", 718 | " (('открыл', 'VERB'), 'dobj', ('парк', 'NOUN')),\n", 719 | " (('парк', 'NOUN'), 'amod', ('новый', 'ADJ')),\n", 720 | " (('парк', 'NOUN'), 'cc', ('и', 'CONJ')),\n", 721 | " (('парк', 'NOUN'), 'conj', ('площадку', 'NOUN')),\n", 722 | " (('площадку', 'NOUN'), 'amod', ('детскую', 'ADJ')),\n", 723 | " (('открыл', 'VERB'), 'punct', ('.', 'PUNCT'))]" 724 | ] 725 | }, 726 | "execution_count": 8, 727 | "metadata": {}, 728 | "output_type": "execute_result" 729 | } 730 | ], 731 | "source": [ 732 | "graph = DependencyGraph(tree_str=sent)\n", 733 | "list(graph.triples())" 734 | ] 735 | }, 736 | { 737 | "cell_type": "markdown", 738 | "metadata": {}, 739 | "source": [ 740 | "Тройки субьект-объект-глагол:" 741 | ] 742 | }, 743 | { 744 | "cell_type": "code", 745 | "execution_count": 9, 746 | "metadata": {}, 747 | "outputs": [ 748 | { 749 | "name": "stdout", 750 | "output_type": "stream", 751 | "text": [ 752 | "{'открыл': {'obj': 'парк', 'subj': 'Собянин'}}\n" 753 | ] 754 | } 755 | ], 756 | "source": [ 757 | "def get_sov(sent):\n", 758 | " graph = DependencyGraph(tree_str=sent)\n", 759 | " sov = {}\n", 760 | " for triple in graph.triples():\n", 761 | " if triple:\n", 762 | " if triple[0][1] == 'VERB':\n", 763 | " sov[triple[0][0]] = {'subj':'','obj':''}\n", 764 | " for triple in graph.triples():\n", 765 | " if triple:\n", 766 | " if triple[1] == 'nsubj':\n", 767 | " if triple[0][1] == 'VERB':\n", 768 | " sov[triple[0][0]]['subj'] = triple[2][0]\n", 769 | " if triple[1] == 'dobj':\n", 770 | " if triple[0][1] == 'VERB':\n", 771 | " sov[triple[0][0]]['obj'] = triple[2][0]\n", 772 | " return sov\n", 773 | "\n", 774 | "sov = get_sov(sent)\n", 775 | "print(sov)" 776 | ] 777 | }, 778 | { 779 | "cell_type": "markdown", 780 | "metadata": {}, 781 | "source": [ 782 | "#### Задание\n", 783 | "\n", 784 | "Измените код выше так, чтобы учитывались:\n", 785 | " 1. Однородные члены предложения \n", 786 | " * (парк, площадка), (Германия, Щвейцария)\n", 787 | " 2. Сложные сказуемые \n", 788 | " * (начнет продавать), (запретил провозить)\n", 789 | " 3. Непрямые объекты\n", 790 | " * (едет, Польшу), (спел, скандале)" 791 | ] 792 | }, 793 | { 794 | "cell_type": "code", 795 | "execution_count": 26, 796 | "metadata": {}, 797 | "outputs": [], 798 | "source": [ 799 | "example = \"\"\"\n", 800 | "1\tДалее\tдалее\tADV\t_\tDegree=Pos\t3\tadvmod\t_\t_\n", 801 | "2\tона\tона\tPRON\t_\tCase=Nom|Gender=Fem|Number=Sing|Person=3\t3\tnsubj\t_\t_\n", 802 | "3\tперебралась\tперебраться\tVERB\t_\tAspect=Perf|Gender=Fem|Mood=Ind|Number=Sing|Tense=Past|VerbForm=Fin|Voice=Mid\t0\troot\t_\t_\n", 803 | "4\tв\tв\tADP\t_\t_\t5\tcase\t_\t_\n", 804 | "5\tБухарест\tБухарест\tPROPN\t_\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t3\tobl\t_\tSpaceAfter=No\n", 805 | "6\t,\t,\tPUNCT\t_\t_\t9\tpunct\t_\t_\n", 806 | "7\tа\tа\tCCONJ\t_\t_\t9\tcc\t_\t_\n", 807 | "8\tзатем\tзатем\tADV\t_\tDegree=Pos\t9\tadvmod\t_\t_\n", 808 | "9\tуехала\tуехать\tVERB\t_\tAspect=Perf|Gender=Fem|Mood=Ind|Number=Sing|Tense=Past|VerbForm=Fin|Voice=Act\t3\tconj\t_\t_\n", 809 | "10\tв\tв\tADP\t_\t_\t11\tcase\t_\t_\n", 810 | "11\tПариж\tПариж\tPROPN\t_\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing\t9\tobl\t_\tSpaceAfter=No\n", 811 | "12\t.\t.\tPUNCT\t_\t_\t3\tpunct\t_\t_\"\"\"" 812 | ] 813 | }, 814 | { 815 | "cell_type": "code", 816 | "execution_count": 29, 817 | "metadata": {}, 818 | "outputs": [], 819 | "source": [ 820 | "def get_sov(sent):\n", 821 | " graph = DependencyGraph(tree_str=sent)\n", 822 | " sov = {}\n", 823 | " for triple in graph.triples():\n", 824 | " print(triple)\n", 825 | " if triple:\n", 826 | " if triple[0][1] == 'VERB':\n", 827 | " sov[triple[0][0]] = {'subj':'','obj':''}\n", 828 | " for triple in graph.triples():\n", 829 | " if triple:\n", 830 | " if triple[1] == 'nsubj':\n", 831 | " if triple[0][1] == 'VERB':\n", 832 | " sov[triple[0][0]]['subj'] = triple[2][0]\n", 833 | " if triple[1] == 'dobj' or triple[1] == 'obl':\n", 834 | " if triple[0][1] == 'VERB':\n", 835 | " sov[triple[0][0]]['obj'] = triple[2][0]\n", 836 | " return sov" 837 | ] 838 | }, 839 | { 840 | "cell_type": "code", 841 | "execution_count": 30, 842 | "metadata": {}, 843 | "outputs": [ 844 | { 845 | "ename": "TypeError", 846 | "evalue": "'NoneType' object is not subscriptable", 847 | "output_type": "error", 848 | "traceback": [ 849 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 850 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 851 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtriples\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_sov\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexample\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 852 | "\u001b[0;32m\u001b[0m in \u001b[0;36mget_sov\u001b[0;34m(sent)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mgraph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mDependencyGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree_str\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0msov\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mtriple\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtriples\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtriple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtriple\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 853 | "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/nltk/parse/dependencygraph.py\u001b[0m in \u001b[0;36mtriples\u001b[0;34m(self, node)\u001b[0m\n\u001b[1;32m 424\u001b[0m \u001b[0mnode\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 425\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 426\u001b[0;31m \u001b[0mhead\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'word'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'ctag'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 427\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_iterable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'deps'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 428\u001b[0m \u001b[0mdep\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_by_address\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 854 | "\u001b[0;31mTypeError\u001b[0m: 'NoneType' object is not subscriptable" 855 | ] 856 | } 857 | ], 858 | "source": [ 859 | "triples = get_sov(example)" 860 | ] 861 | }, 862 | { 863 | "cell_type": "code", 864 | "execution_count": null, 865 | "metadata": {}, 866 | "outputs": [], 867 | "source": [] 868 | }, 869 | { 870 | "cell_type": "markdown", 871 | "metadata": {}, 872 | "source": [ 873 | "# Sentiment Analysis with Recursive Neural Network\n", 874 | "\n", 875 | "* [источник туториала](https://medium.com/@keisukeumezawa/chainer-tutorial-sentiment-analysis-with-recursive-neural-network-180ddde892a2)\n", 876 | "* [статья](https://nlp.stanford.edu/~socherr/EMNLP2013_RNTN.pdf); архитектура описана в 4 секции\n", 877 | "* [демо с кликабельными картинками](http://nlp.stanford.edu:8080/sentiment/rntnDemo.html)" 878 | ] 879 | }, 880 | { 881 | "cell_type": "markdown", 882 | "metadata": {}, 883 | "source": [ 884 | "До сих пор мы смотрели на парсинг зависимостей, но для анализа тональности в этой части используется другой подход, *парсинг составляющих*, или *constituency parsing*. \n", 885 | "![Constituancy parsing](constituency_parsing.png) " 886 | ] 887 | }, 888 | { 889 | "cell_type": "markdown", 890 | "metadata": {}, 891 | "source": [ 892 | "### Идея\n", 893 | "\n", 894 | "Сентимент предложения складывается из сентимента его составляющих, а тех -- в свою очередь, из их составляющих.\n", 895 | "\n", 896 | "![sentiment recursive nn](sentiment_recursiveNN.png)\n", 897 | "\n", 898 | "(в датасете 5 классов тональности: --, -, 0, +, ++)" 899 | ] 900 | }, 901 | { 902 | "attachments": {}, 903 | "cell_type": "markdown", 904 | "metadata": {}, 905 | "source": [ 906 | "### Recursive Neural Network\n", 907 | "\n", 908 | "Это нейросети, которые работают с данными переменной длины, используя иерархические структуры (деревья).\n", 909 | "Скрытое состояние i-той вершины дерева вычисляются из скрытых состояний её левого и правого ребёнка:\n", 910 | "\n", 911 | "![recursive nn_formula](recursiveNN_formula.jpg)\n", 912 | "![recursive nn](recursiveNN.jpg)\n", 913 | "\n", 914 | "Векторные представления фраз (узлов дерева) подаются на вход слою-классификатору тональности и слою softmax (в обучающем датасете все составляющие размечены по тональности)." 915 | ] 916 | }, 917 | { 918 | "cell_type": "markdown", 919 | "metadata": {}, 920 | "source": [ 921 | "А теперь давайте посмотрим на код: [jupyter notebook](https://chainer-colab-notebook.readthedocs.io/en/latest/notebook/official_example/sentiment.html), [репозиторий](https://github.com/chainer/chainer/tree/master/examples/sentiment)." 922 | ] 923 | } 924 | ], 925 | "metadata": { 926 | "kernelspec": { 927 | "display_name": "Python 3", 928 | "language": "python", 929 | "name": "python3" 930 | }, 931 | "language_info": { 932 | "codemirror_mode": { 933 | "name": "ipython", 934 | "version": 3 935 | }, 936 | "file_extension": ".py", 937 | "mimetype": "text/x-python", 938 | "name": "python", 939 | "nbconvert_exporter": "python", 940 | "pygments_lexer": "ipython3", 941 | "version": "3.5.2" 942 | } 943 | }, 944 | "nbformat": 4, 945 | "nbformat_minor": 2 946 | } 947 | -------------------------------------------------------------------------------- /seminars/sem5_syntax/sentiment_recursiveNN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem5_syntax/sentiment_recursiveNN.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/images/attention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem7_transformers/images/attention.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/images/attention_matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem7_transformers/images/attention_matrix.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/images/bert_input_representation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem7_transformers/images/bert_input_representation.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/images/bert_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem7_transformers/images/bert_model.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/images/multi-head-attention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem7_transformers/images/multi-head-attention.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/images/transformer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem7_transformers/images/transformer.png -------------------------------------------------------------------------------- /seminars/sem7_transformers/sem7_transformer.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Attention" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "* Кодирование производится с помощью BiLSTM (не принципиально)\n", 15 | "* Веса $a_i$ обычно в сумме равны $1$" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "\"Drawing\"" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "Визуализируя веса, можно понимать стратегию получения результата (от каких частей контекста зависела каждая из частей выхода).\n" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "Пример визуализации весов $attention$ в задаче машинного перевода" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "\"Drawing\"" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "При использовании BiLSTM каждый вектор $h_j$ хранит информацию о всей последовательности, но в наибольшей степени о $j$-м слове и его соседях.\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "Далее при текущем выходе $y_{t−1}$ (с вектором $s_{t−1}$) для вектора каждого входного слова $h_j$ считается $a_{tj}$ – вклад в генерацию следующего выходного вектора ($attention$):\n", 58 | "\n", 59 | "$$a_{tj} = \\frac {e^{e_{tj}}} {\\sum_k e^{e_{tk}}}$$\n", 60 | "\n", 61 | "где $e_{tj} = f (s_{t−1}, h_j )$ – модель выравнивания" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "\n", 69 | "􏰀Модель выравнивания предсказывает то, насколько хорошо соотносятся входное слово в позиции j и выходное в позиции t (обычно это простая модель, например, однослойная сеть)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "#### Multi-head attention" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "Вход: вектор запроса и несколько пар векторов ключей и значений (ключ и значение обычно совпадают)" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "\"Drawing\"" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "Для запроса и каждого ключа считается вес (линейный слой)\n", 98 | "Значения суммируются с этими весами в итоговый вектор" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "Идея: обучать несколько $attention$, в надежде, что они станут отвечать за разные признаки слов" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "Результаты пропустим через однослойную сеть, получим на выходе один вектор той же размерности, что и входные вектора." 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "metadata": {}, 118 | "source": [ 119 | "## Transformer" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "Состоит из encoder и decoder, в каждом используются $multi$-$head\\ attention$ и полносвязные (свёрточные) слои (нет RNN)" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "Для каждого слова в encoder формируется вектор на основе нескольких слоёв $multi$-$head\\ attention$, который передаётся в декодер." 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "\n", 141 | "􏰀На основании векторов энкодера, а также выходных векторов для уже обработанных слов получается вектор для текущего слова. В обоих случаях используется $multi$-$head\\ attention$." 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "\"Drawing\"" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": {}, 154 | "source": [ 155 | "$Positional\\ encoding$ – дополнительный вектор признаков для каждого слова, представляющий собой набор значений синусов и косинусов с разными периодами от позиции слова в предложении" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "В трансформере и в encoder, и в decoder можно использовать несколько последовательных слоёв $multi$-$head\\ attention$." 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": {}, 168 | "source": [ 169 | "Для большей выразительности и качества добавляют полносвязные слои, а также дропаут, нормализацию по слою и residual connections." 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "Важная особенность: обучение модели внутри предложения можно распараллелить, в отличие от RNN." 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "## BERT" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "$BERT\\ (Bidirectional\\ Encoder\\ Representations\\ from\\ Transformers)\\ -$ многослойный двунаправленный transformer-encoder." 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "#### Model architecture " 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "Модель BERT основана на архитектуре Transformer и является усовершенствованием модели GPT от OpenAI.\n", 205 | "Модель, в отличие от GPT является двунаправленной.\n", 206 | "\n", 207 | "Ссылка на оригинальную статью: https://arxiv.org/abs/1810.04805" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "\"Drawing\"" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "Основные параметры модели:\n", 222 | "* L – количество $transformer$-блоков \n", 223 | "* H – размер скрытого представления,\n", 224 | "* A – количество параллельных слоев в $multi$-$head$ $attention$" 225 | ] 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "metadata": {}, 230 | "source": [ 231 | "Существует две основные модели от Google:\n", 232 | "\n", 233 | "* $BERT_{BASE}$: \n", 234 | " * L = 12\n", 235 | " * H = 768\n", 236 | " * A = 12, \n", 237 | " * Total = 110M\n", 238 | "$$$$\n", 239 | "* $BERT_{LARGE}$: \n", 240 | " * L = 24\n", 241 | " * H = 1024\n", 242 | " * A = 16, \n", 243 | " * Total = 340M\n" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "Модель обучается на двух задачах: \n", 251 | "* Masked Language Modeling.\n", 252 | "* Next sentence prediction." 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": {}, 258 | "source": [ 259 | "#### Masked Language Modeling" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": {}, 265 | "source": [ 266 | "В отличие от обычного Language Modeling, где предсказывается каждое следующее слово на каждом шаге, в задаче Masked Language Modeling случайные токены заменяются на специальный токен [MASK] и предсказываются только эти \"замаскированные\" токены." 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "* 80% времени обучения: Заменим слово на [MASK].\n", 274 | " * my dog is hairy → my dog is [MASK]\n", 275 | "* 10% времени обучения: Заменим слово на другое случайное слово \n", 276 | " * my dog is hairy → my dog is apple\n", 277 | "* 10% времени обучения: оставим предложение без изменений. Цель этого - сделать модель смещенной в сторону слова, которое действительно встречалось в корпусе в данном предложении. \n", 278 | " * my dog is hairy → my dog is hairy. " 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": {}, 284 | "source": [ 285 | "#### Next sentence prediction " 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "metadata": {}, 291 | "source": [ 292 | "Next sentence prediction $-$ задача бинарной классификации. По паре предложений требуется определить, является ли второе предложение продолжением первого." 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "* Input =[CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]\n", 300 | " * Label = IsNext\n", 301 | "$$$$\n", 302 | "* Input =[CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]\n", 303 | " * Label = NotNext" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "#### BERT Embeddings" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "metadata": {}, 316 | "source": [ 317 | "Посмотрим на эмбеддинги, получаемые с помощью модели BERT. \n", 318 | "\n", 319 | "Будем использовать модель $BERT_{base}$ из реализации pytorch_pretrained_bert от HuggingFace. \n", 320 | "Ссылка на их гитхаб: https://github.com/huggingface/transformers" 321 | ] 322 | }, 323 | { 324 | "cell_type": "markdown", 325 | "metadata": {}, 326 | "source": [ 327 | "Примеры текстов взяты из туториала (https://mccormickml.com/2019/05/14/BERT-word-embeddings-tutorial/)" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": 3, 333 | "metadata": {}, 334 | "outputs": [ 335 | { 336 | "name": "stderr", 337 | "output_type": "stream", 338 | "text": [ 339 | "100%|██████████| 231508/231508 [00:00<00:00, 599772.53B/s]\n" 340 | ] 341 | } 342 | ], 343 | "source": [ 344 | "import torch\n", 345 | "from pytorch_pretrained_bert import BertTokenizer, BertModel, BertForMaskedLM\n", 346 | "\n", 347 | "# OPTIONAL: if you want to have more information on what's happening, activate the logger as follows\n", 348 | "import logging\n", 349 | "#logging.basicConfig(level=logging.INFO)\n", 350 | "\n", 351 | "import matplotlib.pyplot as plt\n", 352 | "# % matplotlib inline\n", 353 | "\n", 354 | "# Load pre-trained model tokenizer (vocabulary)\n", 355 | "tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 4, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "name": "stdout", 365 | "output_type": "stream", 366 | "text": [ 367 | "[CLS] After stealing money from the bank vault, the bank robber was seen fishing on the Mississippi river bank. [SEP]\n" 368 | ] 369 | } 370 | ], 371 | "source": [ 372 | "text = \"Here is the sentence I want embeddings for.\"\n", 373 | "text = \"After stealing money from the bank vault, the bank robber was seen fishing on the Mississippi river bank.\"\n", 374 | "marked_text = \"[CLS] \" + text + \" [SEP]\"\n", 375 | "\n", 376 | "print (marked_text)" 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": 5, 382 | "metadata": {}, 383 | "outputs": [ 384 | { 385 | "name": "stdout", 386 | "output_type": "stream", 387 | "text": [ 388 | "['[CLS]', 'after', 'stealing', 'money', 'from', 'the', 'bank', 'vault', ',', 'the', 'bank', 'robber', 'was', 'seen', 'fishing', 'on', 'the', 'mississippi', 'river', 'bank', '.', '[SEP]']\n" 389 | ] 390 | } 391 | ], 392 | "source": [ 393 | "tokenized_text = tokenizer.tokenize(marked_text)\n", 394 | "print (tokenized_text)" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": 6, 400 | "metadata": {}, 401 | "outputs": [ 402 | { 403 | "data": { 404 | "text/plain": [ 405 | "['knight',\n", 406 | " 'lap',\n", 407 | " 'survey',\n", 408 | " 'ma',\n", 409 | " '##ow',\n", 410 | " 'noise',\n", 411 | " 'billy',\n", 412 | " '##ium',\n", 413 | " 'shooting',\n", 414 | " 'guide',\n", 415 | " 'bedroom',\n", 416 | " 'priest',\n", 417 | " 'resistance',\n", 418 | " 'motor',\n", 419 | " 'homes',\n", 420 | " 'sounded',\n", 421 | " 'giant',\n", 422 | " '##mer',\n", 423 | " '150',\n", 424 | " 'scenes']" 425 | ] 426 | }, 427 | "execution_count": 6, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "list(tokenizer.vocab.keys())[5000:5020]\n" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": 7, 439 | "metadata": {}, 440 | "outputs": [ 441 | { 442 | "name": "stdout", 443 | "output_type": "stream", 444 | "text": [ 445 | "('[CLS]', 101)\n", 446 | "('after', 2044)\n", 447 | "('stealing', 11065)\n", 448 | "('money', 2769)\n", 449 | "('from', 2013)\n", 450 | "('the', 1996)\n", 451 | "('bank', 2924)\n", 452 | "('vault', 11632)\n", 453 | "(',', 1010)\n", 454 | "('the', 1996)\n", 455 | "('bank', 2924)\n", 456 | "('robber', 27307)\n", 457 | "('was', 2001)\n", 458 | "('seen', 2464)\n", 459 | "('fishing', 5645)\n", 460 | "('on', 2006)\n", 461 | "('the', 1996)\n", 462 | "('mississippi', 5900)\n", 463 | "('river', 2314)\n", 464 | "('bank', 2924)\n", 465 | "('.', 1012)\n", 466 | "('[SEP]', 102)\n" 467 | ] 468 | } 469 | ], 470 | "source": [ 471 | "indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text)\n", 472 | "\n", 473 | "for tup in zip(tokenized_text, indexed_tokens):\n", 474 | " print (tup)" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": 8, 480 | "metadata": {}, 481 | "outputs": [ 482 | { 483 | "name": "stdout", 484 | "output_type": "stream", 485 | "text": [ 486 | "[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n" 487 | ] 488 | } 489 | ], 490 | "source": [ 491 | "segments_ids = [1] * len(tokenized_text)\n", 492 | "print (segments_ids)" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 9, 498 | "metadata": {}, 499 | "outputs": [ 500 | { 501 | "name": "stderr", 502 | "output_type": "stream", 503 | "text": [ 504 | "100%|██████████| 407873900/407873900 [02:57<00:00, 2298162.71B/s]\n" 505 | ] 506 | }, 507 | { 508 | "data": { 509 | "text/plain": [ 510 | "BertModel(\n", 511 | " (embeddings): BertEmbeddings(\n", 512 | " (word_embeddings): Embedding(30522, 768)\n", 513 | " (position_embeddings): Embedding(512, 768)\n", 514 | " (token_type_embeddings): Embedding(2, 768)\n", 515 | " (LayerNorm): BertLayerNorm()\n", 516 | " (dropout): Dropout(p=0.1, inplace=False)\n", 517 | " )\n", 518 | " (encoder): BertEncoder(\n", 519 | " (layer): ModuleList(\n", 520 | " (0): BertLayer(\n", 521 | " (attention): BertAttention(\n", 522 | " (self): BertSelfAttention(\n", 523 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 524 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 525 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 526 | " (dropout): Dropout(p=0.1, inplace=False)\n", 527 | " )\n", 528 | " (output): BertSelfOutput(\n", 529 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 530 | " (LayerNorm): BertLayerNorm()\n", 531 | " (dropout): Dropout(p=0.1, inplace=False)\n", 532 | " )\n", 533 | " )\n", 534 | " (intermediate): BertIntermediate(\n", 535 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 536 | " )\n", 537 | " (output): BertOutput(\n", 538 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 539 | " (LayerNorm): BertLayerNorm()\n", 540 | " (dropout): Dropout(p=0.1, inplace=False)\n", 541 | " )\n", 542 | " )\n", 543 | " (1): BertLayer(\n", 544 | " (attention): BertAttention(\n", 545 | " (self): BertSelfAttention(\n", 546 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 547 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 548 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 549 | " (dropout): Dropout(p=0.1, inplace=False)\n", 550 | " )\n", 551 | " (output): BertSelfOutput(\n", 552 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 553 | " (LayerNorm): BertLayerNorm()\n", 554 | " (dropout): Dropout(p=0.1, inplace=False)\n", 555 | " )\n", 556 | " )\n", 557 | " (intermediate): BertIntermediate(\n", 558 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 559 | " )\n", 560 | " (output): BertOutput(\n", 561 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 562 | " (LayerNorm): BertLayerNorm()\n", 563 | " (dropout): Dropout(p=0.1, inplace=False)\n", 564 | " )\n", 565 | " )\n", 566 | " (2): BertLayer(\n", 567 | " (attention): BertAttention(\n", 568 | " (self): BertSelfAttention(\n", 569 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 570 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 571 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 572 | " (dropout): Dropout(p=0.1, inplace=False)\n", 573 | " )\n", 574 | " (output): BertSelfOutput(\n", 575 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 576 | " (LayerNorm): BertLayerNorm()\n", 577 | " (dropout): Dropout(p=0.1, inplace=False)\n", 578 | " )\n", 579 | " )\n", 580 | " (intermediate): BertIntermediate(\n", 581 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 582 | " )\n", 583 | " (output): BertOutput(\n", 584 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 585 | " (LayerNorm): BertLayerNorm()\n", 586 | " (dropout): Dropout(p=0.1, inplace=False)\n", 587 | " )\n", 588 | " )\n", 589 | " (3): BertLayer(\n", 590 | " (attention): BertAttention(\n", 591 | " (self): BertSelfAttention(\n", 592 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 593 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 594 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 595 | " (dropout): Dropout(p=0.1, inplace=False)\n", 596 | " )\n", 597 | " (output): BertSelfOutput(\n", 598 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 599 | " (LayerNorm): BertLayerNorm()\n", 600 | " (dropout): Dropout(p=0.1, inplace=False)\n", 601 | " )\n", 602 | " )\n", 603 | " (intermediate): BertIntermediate(\n", 604 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 605 | " )\n", 606 | " (output): BertOutput(\n", 607 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 608 | " (LayerNorm): BertLayerNorm()\n", 609 | " (dropout): Dropout(p=0.1, inplace=False)\n", 610 | " )\n", 611 | " )\n", 612 | " (4): BertLayer(\n", 613 | " (attention): BertAttention(\n", 614 | " (self): BertSelfAttention(\n", 615 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 616 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 617 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 618 | " (dropout): Dropout(p=0.1, inplace=False)\n", 619 | " )\n", 620 | " (output): BertSelfOutput(\n", 621 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 622 | " (LayerNorm): BertLayerNorm()\n", 623 | " (dropout): Dropout(p=0.1, inplace=False)\n", 624 | " )\n", 625 | " )\n", 626 | " (intermediate): BertIntermediate(\n", 627 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 628 | " )\n", 629 | " (output): BertOutput(\n", 630 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 631 | " (LayerNorm): BertLayerNorm()\n", 632 | " (dropout): Dropout(p=0.1, inplace=False)\n", 633 | " )\n", 634 | " )\n", 635 | " (5): BertLayer(\n", 636 | " (attention): BertAttention(\n", 637 | " (self): BertSelfAttention(\n", 638 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 639 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 640 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 641 | " (dropout): Dropout(p=0.1, inplace=False)\n", 642 | " )\n", 643 | " (output): BertSelfOutput(\n", 644 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 645 | " (LayerNorm): BertLayerNorm()\n", 646 | " (dropout): Dropout(p=0.1, inplace=False)\n", 647 | " )\n", 648 | " )\n", 649 | " (intermediate): BertIntermediate(\n", 650 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 651 | " )\n", 652 | " (output): BertOutput(\n", 653 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 654 | " (LayerNorm): BertLayerNorm()\n", 655 | " (dropout): Dropout(p=0.1, inplace=False)\n", 656 | " )\n", 657 | " )\n", 658 | " (6): BertLayer(\n", 659 | " (attention): BertAttention(\n", 660 | " (self): BertSelfAttention(\n", 661 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 662 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 663 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 664 | " (dropout): Dropout(p=0.1, inplace=False)\n", 665 | " )\n", 666 | " (output): BertSelfOutput(\n", 667 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 668 | " (LayerNorm): BertLayerNorm()\n", 669 | " (dropout): Dropout(p=0.1, inplace=False)\n", 670 | " )\n", 671 | " )\n", 672 | " (intermediate): BertIntermediate(\n", 673 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 674 | " )\n", 675 | " (output): BertOutput(\n", 676 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 677 | " (LayerNorm): BertLayerNorm()\n", 678 | " (dropout): Dropout(p=0.1, inplace=False)\n", 679 | " )\n", 680 | " )\n", 681 | " (7): BertLayer(\n", 682 | " (attention): BertAttention(\n", 683 | " (self): BertSelfAttention(\n", 684 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 685 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 686 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 687 | " (dropout): Dropout(p=0.1, inplace=False)\n", 688 | " )\n", 689 | " (output): BertSelfOutput(\n", 690 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 691 | " (LayerNorm): BertLayerNorm()\n", 692 | " (dropout): Dropout(p=0.1, inplace=False)\n", 693 | " )\n", 694 | " )\n", 695 | " (intermediate): BertIntermediate(\n", 696 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 697 | " )\n", 698 | " (output): BertOutput(\n", 699 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 700 | " (LayerNorm): BertLayerNorm()\n", 701 | " (dropout): Dropout(p=0.1, inplace=False)\n", 702 | " )\n", 703 | " )\n", 704 | " (8): BertLayer(\n", 705 | " (attention): BertAttention(\n", 706 | " (self): BertSelfAttention(\n", 707 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 708 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 709 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 710 | " (dropout): Dropout(p=0.1, inplace=False)\n", 711 | " )\n", 712 | " (output): BertSelfOutput(\n", 713 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 714 | " (LayerNorm): BertLayerNorm()\n", 715 | " (dropout): Dropout(p=0.1, inplace=False)\n", 716 | " )\n", 717 | " )\n", 718 | " (intermediate): BertIntermediate(\n", 719 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 720 | " )\n", 721 | " (output): BertOutput(\n", 722 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 723 | " (LayerNorm): BertLayerNorm()\n", 724 | " (dropout): Dropout(p=0.1, inplace=False)\n", 725 | " )\n", 726 | " )\n", 727 | " (9): BertLayer(\n", 728 | " (attention): BertAttention(\n", 729 | " (self): BertSelfAttention(\n", 730 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 731 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 732 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 733 | " (dropout): Dropout(p=0.1, inplace=False)\n", 734 | " )\n", 735 | " (output): BertSelfOutput(\n", 736 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 737 | " (LayerNorm): BertLayerNorm()\n", 738 | " (dropout): Dropout(p=0.1, inplace=False)\n", 739 | " )\n", 740 | " )\n", 741 | " (intermediate): BertIntermediate(\n", 742 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 743 | " )\n", 744 | " (output): BertOutput(\n", 745 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 746 | " (LayerNorm): BertLayerNorm()\n", 747 | " (dropout): Dropout(p=0.1, inplace=False)\n", 748 | " )\n", 749 | " )\n", 750 | " (10): BertLayer(\n", 751 | " (attention): BertAttention(\n", 752 | " (self): BertSelfAttention(\n", 753 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 754 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 755 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 756 | " (dropout): Dropout(p=0.1, inplace=False)\n", 757 | " )\n", 758 | " (output): BertSelfOutput(\n", 759 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 760 | " (LayerNorm): BertLayerNorm()\n", 761 | " (dropout): Dropout(p=0.1, inplace=False)\n", 762 | " )\n", 763 | " )\n", 764 | " (intermediate): BertIntermediate(\n", 765 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 766 | " )\n", 767 | " (output): BertOutput(\n", 768 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 769 | " (LayerNorm): BertLayerNorm()\n", 770 | " (dropout): Dropout(p=0.1, inplace=False)\n", 771 | " )\n", 772 | " )\n", 773 | " (11): BertLayer(\n", 774 | " (attention): BertAttention(\n", 775 | " (self): BertSelfAttention(\n", 776 | " (query): Linear(in_features=768, out_features=768, bias=True)\n", 777 | " (key): Linear(in_features=768, out_features=768, bias=True)\n", 778 | " (value): Linear(in_features=768, out_features=768, bias=True)\n", 779 | " (dropout): Dropout(p=0.1, inplace=False)\n", 780 | " )\n", 781 | " (output): BertSelfOutput(\n", 782 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 783 | " (LayerNorm): BertLayerNorm()\n", 784 | " (dropout): Dropout(p=0.1, inplace=False)\n", 785 | " )\n", 786 | " )\n", 787 | " (intermediate): BertIntermediate(\n", 788 | " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", 789 | " )\n", 790 | " (output): BertOutput(\n", 791 | " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", 792 | " (LayerNorm): BertLayerNorm()\n", 793 | " (dropout): Dropout(p=0.1, inplace=False)\n", 794 | " )\n", 795 | " )\n", 796 | " )\n", 797 | " )\n", 798 | " (pooler): BertPooler(\n", 799 | " (dense): Linear(in_features=768, out_features=768, bias=True)\n", 800 | " (activation): Tanh()\n", 801 | " )\n", 802 | ")" 803 | ] 804 | }, 805 | "execution_count": 9, 806 | "metadata": {}, 807 | "output_type": "execute_result" 808 | } 809 | ], 810 | "source": [ 811 | "# Convert inputs to PyTorch tensors\n", 812 | "tokens_tensor = torch.tensor([indexed_tokens])\n", 813 | "segments_tensors = torch.tensor([segments_ids])\n", 814 | "\n", 815 | "# Load pre-trained model (weights)\n", 816 | "model = BertModel.from_pretrained('bert-base-uncased')\n", 817 | "\n", 818 | "# Put the model in \"evaluation\" mode, meaning feed-forward operation.\n", 819 | "model.eval()" 820 | ] 821 | }, 822 | { 823 | "cell_type": "code", 824 | "execution_count": 10, 825 | "metadata": {}, 826 | "outputs": [], 827 | "source": [ 828 | "# Predict hidden states features for each layer\n", 829 | "with torch.no_grad():\n", 830 | " encoded_layers, _ = model(tokens_tensor, segments_tensors)" 831 | ] 832 | }, 833 | { 834 | "cell_type": "code", 835 | "execution_count": 11, 836 | "metadata": {}, 837 | "outputs": [ 838 | { 839 | "name": "stdout", 840 | "output_type": "stream", 841 | "text": [ 842 | "Number of layers: 12\n", 843 | "Number of batches: 1\n", 844 | "Number of tokens: 22\n", 845 | "Number of hidden units: 768\n" 846 | ] 847 | } 848 | ], 849 | "source": [ 850 | "print (\"Number of layers:\", len(encoded_layers))\n", 851 | "layer_i = 0\n", 852 | "\n", 853 | "print (\"Number of batches:\", len(encoded_layers[layer_i]))\n", 854 | "batch_i = 0\n", 855 | "\n", 856 | "print (\"Number of tokens:\", len(encoded_layers[layer_i][batch_i]))\n", 857 | "token_i = 0\n", 858 | "\n", 859 | "print (\"Number of hidden units:\", len(encoded_layers[layer_i][batch_i][token_i]))" 860 | ] 861 | }, 862 | { 863 | "cell_type": "code", 864 | "execution_count": 12, 865 | "metadata": {}, 866 | "outputs": [ 867 | { 868 | "data": { 869 | "image/png": "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\n", 870 | "text/plain": [ 871 | "
" 872 | ] 873 | }, 874 | "metadata": { 875 | "needs_background": "light" 876 | }, 877 | "output_type": "display_data" 878 | } 879 | ], 880 | "source": [ 881 | "# For the 5th token in our sentence, select its feature values from layer 5.\n", 882 | "token_i = 5\n", 883 | "layer_i = 5\n", 884 | "vec = encoded_layers[layer_i][batch_i][token_i]\n", 885 | "\n", 886 | "# Plot the values as a histogram to show their distribution.\n", 887 | "plt.figure(figsize=(10,10))\n", 888 | "plt.hist(vec, bins=200)\n", 889 | "plt.show()" 890 | ] 891 | }, 892 | { 893 | "cell_type": "code", 894 | "execution_count": 13, 895 | "metadata": {}, 896 | "outputs": [ 897 | { 898 | "name": "stdout", 899 | "output_type": "stream", 900 | "text": [ 901 | "Number of tokens in sequence: 22\n", 902 | "Number of layers per token: 12\n" 903 | ] 904 | } 905 | ], 906 | "source": [ 907 | "# Convert the hidden state embeddings into single token vectors\n", 908 | "\n", 909 | "# Holds the list of 12 layer embeddings for each token\n", 910 | "# Will have the shape: [# tokens, # layers, # features]\n", 911 | "token_embeddings = [] \n", 912 | "\n", 913 | "# For each token in the sentence...\n", 914 | "for token_i in range(len(tokenized_text)):\n", 915 | " \n", 916 | " # Holds 12 layers of hidden states for each token \n", 917 | " hidden_layers = [] \n", 918 | " \n", 919 | " # For each of the 12 layers...\n", 920 | " for layer_i in range(len(encoded_layers)):\n", 921 | " \n", 922 | " # Lookup the vector for `token_i` in `layer_i`\n", 923 | " vec = encoded_layers[layer_i][batch_i][token_i]\n", 924 | "\n", 925 | " hidden_layers.append(vec)\n", 926 | " \n", 927 | " token_embeddings.append(hidden_layers)\n", 928 | "\n", 929 | "# Sanity check the dimensions:\n", 930 | "print (\"Number of tokens in sequence:\", len(token_embeddings))\n", 931 | "print (\"Number of layers per token:\", len(token_embeddings[0]))" 932 | ] 933 | }, 934 | { 935 | "cell_type": "code", 936 | "execution_count": 14, 937 | "metadata": {}, 938 | "outputs": [], 939 | "source": [ 940 | "concatenated_last_4_layers = [torch.cat((layer[-1], layer[-2], layer[-3], layer[-4]), 0) for layer in token_embeddings] # [number_of_tokens, 3072]\n", 941 | "\n", 942 | "summed_last_4_layers = [torch.sum(torch.stack(layer)[-4:], 0) for layer in token_embeddings] # [number_of_tokens, 768]" 943 | ] 944 | }, 945 | { 946 | "cell_type": "code", 947 | "execution_count": 15, 948 | "metadata": {}, 949 | "outputs": [], 950 | "source": [ 951 | "sentence_embedding = torch.mean(encoded_layers[11], 1)" 952 | ] 953 | }, 954 | { 955 | "cell_type": "code", 956 | "execution_count": 16, 957 | "metadata": {}, 958 | "outputs": [ 959 | { 960 | "name": "stdout", 961 | "output_type": "stream", 962 | "text": [ 963 | "Our final sentence embedding vector of shape:\n" 964 | ] 965 | }, 966 | { 967 | "data": { 968 | "text/plain": [ 969 | "(None, 768)" 970 | ] 971 | }, 972 | "execution_count": 16, 973 | "metadata": {}, 974 | "output_type": "execute_result" 975 | } 976 | ], 977 | "source": [ 978 | "print (\"Our final sentence embedding vector of shape:\"), sentence_embedding[0].shape[0]" 979 | ] 980 | }, 981 | { 982 | "cell_type": "code", 983 | "execution_count": 17, 984 | "metadata": {}, 985 | "outputs": [ 986 | { 987 | "name": "stdout", 988 | "output_type": "stream", 989 | "text": [ 990 | "After stealing money from the bank vault, the bank robber was seen fishing on the Mississippi river bank.\n" 991 | ] 992 | } 993 | ], 994 | "source": [ 995 | "print (text)" 996 | ] 997 | }, 998 | { 999 | "cell_type": "code", 1000 | "execution_count": 18, 1001 | "metadata": {}, 1002 | "outputs": [ 1003 | { 1004 | "name": "stdout", 1005 | "output_type": "stream", 1006 | "text": [ 1007 | "0 [CLS]\n", 1008 | "1 after\n", 1009 | "2 stealing\n", 1010 | "3 money\n", 1011 | "4 from\n", 1012 | "5 the\n", 1013 | "6 bank\n", 1014 | "7 vault\n", 1015 | "8 ,\n", 1016 | "9 the\n", 1017 | "10 bank\n", 1018 | "11 robber\n", 1019 | "12 was\n", 1020 | "13 seen\n", 1021 | "14 fishing\n", 1022 | "15 on\n", 1023 | "16 the\n", 1024 | "17 mississippi\n", 1025 | "18 river\n", 1026 | "19 bank\n", 1027 | "20 .\n", 1028 | "21 [SEP]\n" 1029 | ] 1030 | } 1031 | ], 1032 | "source": [ 1033 | "for i,x in enumerate(tokenized_text):\n", 1034 | " print (i,x)" 1035 | ] 1036 | }, 1037 | { 1038 | "cell_type": "code", 1039 | "execution_count": 19, 1040 | "metadata": {}, 1041 | "outputs": [ 1042 | { 1043 | "name": "stdout", 1044 | "output_type": "stream", 1045 | "text": [ 1046 | "First fifteen values of 'bank' as in 'bank robber':\n" 1047 | ] 1048 | }, 1049 | { 1050 | "data": { 1051 | "text/plain": [ 1052 | "tensor([ 1.1868, -1.5298, -1.3770, 1.0648, 3.1446, 1.4003, -4.2407, 1.3946,\n", 1053 | " -0.1170, -1.8777, 0.1091, -0.3862, 0.6744, 2.1924, -4.5306])" 1054 | ] 1055 | }, 1056 | "execution_count": 19, 1057 | "metadata": {}, 1058 | "output_type": "execute_result" 1059 | } 1060 | ], 1061 | "source": [ 1062 | "print (\"First fifteen values of 'bank' as in 'bank robber':\")\n", 1063 | "summed_last_4_layers[10][:15]" 1064 | ] 1065 | }, 1066 | { 1067 | "cell_type": "code", 1068 | "execution_count": 20, 1069 | "metadata": {}, 1070 | "outputs": [ 1071 | { 1072 | "name": "stdout", 1073 | "output_type": "stream", 1074 | "text": [ 1075 | "First fifteen values of 'bank' as in 'bank vault':\n" 1076 | ] 1077 | }, 1078 | { 1079 | "data": { 1080 | "text/plain": [ 1081 | "tensor([ 2.1319, -2.1413, -1.6260, 0.8638, 3.3173, 0.1797, -4.4853, 3.1215,\n", 1082 | " -0.9740, -3.1780, 0.1046, -1.5481, 0.4758, 1.1703, -4.4859])" 1083 | ] 1084 | }, 1085 | "execution_count": 20, 1086 | "metadata": {}, 1087 | "output_type": "execute_result" 1088 | } 1089 | ], 1090 | "source": [ 1091 | "print (\"First fifteen values of 'bank' as in 'bank vault':\")\n", 1092 | "summed_last_4_layers[6][:15]" 1093 | ] 1094 | }, 1095 | { 1096 | "cell_type": "code", 1097 | "execution_count": 21, 1098 | "metadata": {}, 1099 | "outputs": [ 1100 | { 1101 | "name": "stdout", 1102 | "output_type": "stream", 1103 | "text": [ 1104 | "First fifteen values of 'bank' as in 'river bank':\n" 1105 | ] 1106 | }, 1107 | { 1108 | "data": { 1109 | "text/plain": [ 1110 | "tensor([ 1.1295, -1.4725, -0.7296, -0.0901, 2.4970, 0.5330, 0.9742, 5.1834,\n", 1111 | " -1.0692, -1.5941, 1.9261, 0.7119, -0.9809, 1.2127, -2.9812])" 1112 | ] 1113 | }, 1114 | "execution_count": 21, 1115 | "metadata": {}, 1116 | "output_type": "execute_result" 1117 | } 1118 | ], 1119 | "source": [ 1120 | "print (\"First fifteen values of 'bank' as in 'river bank':\")\n", 1121 | "summed_last_4_layers[19][:15]" 1122 | ] 1123 | }, 1124 | { 1125 | "cell_type": "code", 1126 | "execution_count": 22, 1127 | "metadata": {}, 1128 | "outputs": [], 1129 | "source": [ 1130 | "from sklearn.metrics.pairwise import cosine_similarity\n", 1131 | "\n", 1132 | "# Compare \"bank\" as in \"bank robber\" to \"bank\" as in \"river bank\"\n", 1133 | "different_bank = cosine_similarity(summed_last_4_layers[10].reshape(1,-1), summed_last_4_layers[19].reshape(1,-1))[0][0]\n", 1134 | "\n", 1135 | "# Compare \"bank\" as in \"bank robber\" to \"bank\" as in \"bank vault\" \n", 1136 | "same_bank = cosine_similarity(summed_last_4_layers[10].reshape(1,-1), summed_last_4_layers[6].reshape(1,-1))[0][0]" 1137 | ] 1138 | }, 1139 | { 1140 | "cell_type": "code", 1141 | "execution_count": 23, 1142 | "metadata": {}, 1143 | "outputs": [ 1144 | { 1145 | "name": "stdout", 1146 | "output_type": "stream", 1147 | "text": [ 1148 | "Similarity of 'bank' as in 'bank robber' to 'bank' as in 'bank vault': 0.9456751\n" 1149 | ] 1150 | } 1151 | ], 1152 | "source": [ 1153 | "print (\"Similarity of 'bank' as in 'bank robber' to 'bank' as in 'bank vault':\", same_bank)" 1154 | ] 1155 | }, 1156 | { 1157 | "cell_type": "code", 1158 | "execution_count": 24, 1159 | "metadata": {}, 1160 | "outputs": [ 1161 | { 1162 | "name": "stdout", 1163 | "output_type": "stream", 1164 | "text": [ 1165 | "Similarity of 'bank' as in 'bank robber' to 'bank' as in 'river bank': 0.6797334\n" 1166 | ] 1167 | } 1168 | ], 1169 | "source": [ 1170 | "print (\"Similarity of 'bank' as in 'bank robber' to 'bank' as in 'river bank':\", different_bank)" 1171 | ] 1172 | }, 1173 | { 1174 | "cell_type": "code", 1175 | "execution_count": null, 1176 | "metadata": {}, 1177 | "outputs": [], 1178 | "source": [] 1179 | } 1180 | ], 1181 | "metadata": { 1182 | "kernelspec": { 1183 | "display_name": "Python 3", 1184 | "language": "python", 1185 | "name": "python3" 1186 | }, 1187 | "language_info": { 1188 | "codemirror_mode": { 1189 | "name": "ipython", 1190 | "version": 3 1191 | }, 1192 | "file_extension": ".py", 1193 | "mimetype": "text/x-python", 1194 | "name": "python", 1195 | "nbconvert_exporter": "python", 1196 | "pygments_lexer": "ipython3", 1197 | "version": "3.7.1" 1198 | } 1199 | }, 1200 | "nbformat": 4, 1201 | "nbformat_minor": 2 1202 | } 1203 | -------------------------------------------------------------------------------- /seminars/sem_11/bertsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PragmaticsLab/NLP-course-AMI/0cb50728ceaa825f97d88f4e72efc954b817badc/seminars/sem_11/bertsum.png -------------------------------------------------------------------------------- /seminars/sem_11/summ-attentions.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 24 | 25 | 26 | 27 | 29 | 31 | 32 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 59 | 60 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 104 | 106 | 108 | 110 | 112 | 114 | 116 | 118 | 120 | 122 | 124 | 126 | 128 | 130 | 132 | 134 | 135 | 141 | 142 | 156 | 157 | 177 | 178 | 197 | 198 | 205 | 206 | 226 | 227 | 236 | 237 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 272 | 295 | 310 | 339 | 381 | 386 | 388 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 413 | 415 | 417 | 419 | 421 | 423 | 425 | 427 | 429 | 431 | 433 | 435 | 437 | 439 | 441 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 478 | 480 | 482 | 484 | 485 | 494 | 495 | 501 | 502 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 517 | 519 | 521 | 523 | 524 | 525 | 526 | 527 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 538 | 540 | 543 | 545 | 547 | 550 | 552 | 554 | 555 | 556 | 558 | 559 | 560 | 561 | 562 | 563 | --------------------------------------------------------------------------------