├── 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 | ""
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 [](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 | " Category | \n",
218 | " Message | \n",
219 | "
\n",
220 | " \n",
221 | " \n",
222 | " \n",
223 | " 0 | \n",
224 | " ham | \n",
225 | " Go until jurong point, crazy.. Available only ... | \n",
226 | "
\n",
227 | " \n",
228 | " 1 | \n",
229 | " ham | \n",
230 | " Ok lar... Joking wif u oni... | \n",
231 | "
\n",
232 | " \n",
233 | " 2 | \n",
234 | " spam | \n",
235 | " Free entry in 2 a wkly comp to win FA Cup fina... | \n",
236 | "
\n",
237 | " \n",
238 | " 3 | \n",
239 | " ham | \n",
240 | " U dun say so early hor... U c already then say... | \n",
241 | "
\n",
242 | " \n",
243 | " 4 | \n",
244 | " ham | \n",
245 | " Nah I don't think he goes to usf, he lives aro... | \n",
246 | "
\n",
247 | " \n",
248 | "
\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 визуализация: \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 | " "
886 | ]
887 | },
888 | {
889 | "cell_type": "markdown",
890 | "metadata": {},
891 | "source": [
892 | "### Идея\n",
893 | "\n",
894 | "Сентимент предложения складывается из сентимента его составляющих, а тех -- в свою очередь, из их составляющих.\n",
895 | "\n",
896 | "\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 | "\n",
912 | "\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 | "
"
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 | "
"
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 | "
"
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 | "
"
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 | "
"
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 |
563 |
--------------------------------------------------------------------------------