diff --git a/notebooks/first_module_intro/02_homework.ipynb b/notebooks/first_module_intro/02_homework.ipynb new file mode 100644 index 0000000..7e30eab --- /dev/null +++ b/notebooks/first_module_intro/02_homework.ipynb @@ -0,0 +1,178 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "43fc8290", + "metadata": {}, + "source": [ + "## Задание 1." + ] + }, + { + "cell_type": "markdown", + "id": "b06a5ace", + "metadata": {}, + "source": [ + "Посчитайте частоты для 5-грамм в корпусе lenta.txt. двумя способами: \n", + "1) lenta.txt -> sent_tokenize (russian) -> word_tokenize -> ngrammer \n", + "2) lenta.txt -> word_tokene(preserve_line=True) - ngrammer \n", + " \n", + "Проанализируйте топ-20 самых частотных нграмм и проверьте есть ли различия? " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "957f5656", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "b5781f34", + "metadata": {}, + "source": [ + "## Задание 2." + ] + }, + { + "cell_type": "markdown", + "id": "4292716e", + "metadata": {}, + "source": [ + "Найдите какую-то инетересную (по вашему мнению) закономерность на https://books.google.com/ngrams/ для русского языка (с 1990 по 2019)\n", + "\n", + "Вставьте сюда скриншот" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e3bf76d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "8a0a89ec", + "metadata": {}, + "source": [ + "## Заданиe 3" + ] + }, + { + "cell_type": "markdown", + "id": "b40c35e9", + "metadata": {}, + "source": [ + "Когда мы разбирали PMI мы использовали такую функцию:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "221f1bc0", + "metadata": {}, + "outputs": [], + "source": [ + "def scorer_simple(word_count_a, word_count_b, bigram_count, *args):\n", + " try:\n", + " score = bigram_count/((word_count_a+word_count_b))\n", + " except ZeroDivisionError:\n", + " return 0\n", + " return score" + ] + }, + { + "cell_type": "markdown", + "id": "53fd2def", + "metadata": {}, + "source": [ + "Но если вы посмотрите на определение в википедии, то увидите, что формула немного другая ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/094243d23c19d2d032f6bb26c4dc4f47d98d32f8)" + ] + }, + { + "cell_type": "markdown", + "id": "b1905862", + "metadata": {}, + "source": [ + "Перепишите функцию, чтобы она точно соответствовала этому определению. Расчитайте PMI для всех биграммов также как мы делали в семинаре с помощью функции score_bigrams используя изначальный scorer и обновленный. Посмотрите есть ли разница в топ-10 биграммов. Подумайте почему результаты совпадают/отличаются?\n", + "\n", + "*Подсказка: для вероятностей можно поделить на количество слов в корпусе" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1431f618", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "0a6e1c99", + "metadata": {}, + "source": [ + "## Задание 4*\n", + "\n", + "Обновите функцию получившуюся в предыдущем задании так, чтобы вместо произведения/деления вероятностей использовались сложение и вычитание логирифмов. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f55a362", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "b22785f4", + "metadata": {}, + "source": [ + "## Задание 5" + ] + }, + { + "cell_type": "markdown", + "id": "a1121e53", + "metadata": {}, + "source": [ + "Исследуйте gensim.models.Phrases. Проверьте сколько дефолтных scoring функций есть в этом классе. Попробуйте все доступные по умолчанию scoring функции и попробуйте настраивать для них значение threshold и min_count. Попробуйте сделать так, чтобы собиралось как можно больше нграммов. Попробуйте строить последовательность gensim.models.Phrases, чтобы строить более длинные нграммы" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "716fba84", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/first_module_intro/02_ngrams.ipynb b/notebooks/first_module_intro/02_ngrams.ipynb index 7045b73..1a6fdaa 100644 --- a/notebooks/first_module_intro/02_ngrams.ipynb +++ b/notebooks/first_module_intro/02_ngrams.ipynb @@ -20,20 +20,20 @@ }, { "cell_type": "code", - "execution_count": 200, - "id": "41cc8dc8", + "execution_count": 1, + "id": "2bb9ec35", "metadata": {}, "outputs": [], "source": [ "# to download data\n", - "#!mkdir data\n", + "# !mkdir data\n", "# !wget https://github.com/mannefedov/compling_nlp_hse_course/raw/master/data/lenta.txt.zip -P data\n", "# !unzip -o data/lenta.txt.zip -d data/" ] }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 2, "id": "756b4d59", "metadata": {}, "outputs": [], @@ -47,20 +47,9 @@ "execution_count": 3, "id": "8d6dc286", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Бои у Сопоцкина и Друскеник закончились отступлени'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "corpus[:50]" + "# corpus[:1000]" ] }, { @@ -78,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "277bf143", "metadata": {}, "outputs": [], @@ -89,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "05ec0387", "metadata": {}, "outputs": [], @@ -99,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 36, "id": "4a487ea7", "metadata": {}, "outputs": [], @@ -115,7 +104,15 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, + "id": "f149cfdf", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 37, "id": "31007149", "metadata": {}, "outputs": [ @@ -146,7 +143,7 @@ " '.']]" ] }, - "execution_count": 7, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -166,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 38, "id": "81cd58de", "metadata": {}, "outputs": [], @@ -176,7 +173,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 39, "id": "d12f7832", "metadata": {}, "outputs": [], @@ -187,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 40, "id": "6f255020", "metadata": {}, "outputs": [ @@ -215,7 +212,7 @@ " 'крепостью']]" ] }, - "execution_count": 10, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -242,7 +239,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 41, "id": "30b709d0", "metadata": {}, "outputs": [], @@ -255,7 +252,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 42, "id": "401932c3", "metadata": {}, "outputs": [], @@ -275,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 43, "id": "a4c91359", "metadata": {}, "outputs": [ @@ -294,7 +291,7 @@ " ('о', 7117)]" ] }, - "execution_count": 13, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -323,7 +320,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 44, "id": "f637e312", "metadata": {}, "outputs": [], @@ -336,13 +333,24 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 45, + "id": "148e0abd", + "metadata": {}, + "outputs": [], + "source": [ + "# russian_stopwords" + ] + }, + { + "cell_type": "code", + "execution_count": 46, "id": "a186038e", "metadata": { "scrolled": true }, "outputs": [], "source": [ + "\n", "token_counts = Counter()\n", "for sentence in tokenized_sentences:\n", " token_counts.update([token for token in sentence if token not in russian_stopwords])" @@ -350,7 +358,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 47, "id": "664ddb42", "metadata": {}, "outputs": [ @@ -369,7 +377,7 @@ " ('заявил', 2940)]" ] }, - "execution_count": 16, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -404,21 +412,31 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 48, "id": "ea69b13c", "metadata": {}, "outputs": [], "source": [ "def ngrammer(tokens, n=2):\n", " ngrams = []\n", - " for i in range(0,len(tokens)-n+1):\n", + " for i in range(len(tokens)-n+1):\n", " ngrams.append(' '.join(tokens[i:i+n]))\n", " return ngrams" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 49, + "id": "2f7cc13c", + "metadata": {}, + "outputs": [], + "source": [ + "# ngrammer('1234567')" + ] + }, + { + "cell_type": "code", + "execution_count": 50, "id": "7f2b0c06", "metadata": {}, "outputs": [], @@ -430,7 +448,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 51, "id": "018300fb", "metadata": {}, "outputs": [ @@ -449,7 +467,7 @@ " ('эхо москвы', 488)]" ] }, - "execution_count": 21, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -460,8 +478,8 @@ }, { "cell_type": "code", - "execution_count": 23, - "id": "3e3db5f6", + "execution_count": 73, + "id": "49320da7", "metadata": {}, "outputs": [ { @@ -476,10 +494,20 @@ " ('в том числе', 608),\n", " ('передает риа новости', 565),\n", " ('на северном кавказе', 470),\n", - " ('риа новости в', 461)]" + " ('риа новости в', 461),\n", + " ('риа новости со', 428),\n", + " ('новости со ссылкой', 408),\n", + " ('в соответствии с', 367),\n", + " ('в том что', 367),\n", + " ('после того как', 355),\n", + " ('сообщили риа новости', 332),\n", + " ('до сих пор', 327),\n", + " ('то же время', 325),\n", + " ('как сообщает риа', 324),\n", + " ('в то же', 324)]" ] }, - "execution_count": 23, + "execution_count": 73, "metadata": {}, "output_type": "execute_result" } @@ -490,12 +518,12 @@ " # можно убрать фильтр стоп-слов\n", " trigram_counts.update(ngrammer([token for token in sentence], 3))\n", "\n", - "trigram_counts.most_common(10)" + "trigram_counts.most_common(20)" ] }, { "cell_type": "markdown", - "id": "45846b03", + "id": "c4562e17", "metadata": {}, "source": [ "N можно повышать и дальше, но выше 3-грамм на таком небольшом корпусе подниматься особого смысла нет, так как большинство будет иметь 1 частотность, а в топе будут совсем клишированые фразы. Но на больших данных 4,5,6-граммы могут быть осмысленными. В целом такой простой подсчет частотностей по нграммам уже очень хороший способ что-то понять про данные и даже увидеть какие-то интересные зависимости. \n", @@ -506,14 +534,14 @@ { "cell_type": "code", "execution_count": null, - "id": "15a2d304", + "id": "d1f22e11", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", - "id": "3cfa86da", + "id": "aa7b3f15", "metadata": {}, "source": [ "### коллокации" @@ -531,7 +559,7 @@ }, { "cell_type": "markdown", - "id": "a6f49305", + "id": "85ca3963", "metadata": {}, "source": [ "Напишем функцию, которая будет высчитывать PMI из частот слова а и б и их общей частоты." @@ -539,7 +567,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 138, "id": "46d66b93", "metadata": {}, "outputs": [], @@ -577,7 +605,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 139, "id": "847bb843", "metadata": {}, "outputs": [], @@ -606,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 140, "id": "fd481e01", "metadata": {}, "outputs": [], @@ -629,7 +657,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 141, "id": "54396f05", "metadata": {}, "outputs": [], @@ -639,7 +667,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 142, "id": "9b09bd88", "metadata": {}, "outputs": [], @@ -657,7 +685,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 143, "id": "12c6b05b", "metadata": {}, "outputs": [ @@ -681,7 +709,7 @@ " ('равнине обманчиво-зыбкой.презрение', 0.5)]" ] }, - "execution_count": 44, + "execution_count": 143, "metadata": {}, "output_type": "execute_result" } @@ -700,7 +728,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 144, "id": "07ac44ff", "metadata": {}, "outputs": [], @@ -731,7 +759,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 145, "id": "ec18f79d", "metadata": {}, "outputs": [], @@ -741,7 +769,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 146, "id": "9548c7a2", "metadata": {}, "outputs": [ @@ -765,7 +793,7 @@ " ('возбуждено уголовное', 0.2983606557377049)]" ] }, - "execution_count": 47, + "execution_count": 146, "metadata": {}, "output_type": "execute_result" } @@ -784,7 +812,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 147, "id": "cce05f63", "metadata": {}, "outputs": [], @@ -798,6 +826,7 @@ " \n", " return score\n", "\n", + "\n", "# добавим параметр len_vocab\n", "def score_bigrams(unigrams, bigrams, scorer, threshold=-100000, min_count=0):\n", " ## посчитаем метрику для каждого нграмма\n", @@ -825,17 +854,17 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 150, "id": "1d37bf2a", "metadata": {}, "outputs": [], "source": [ - "bigram2score = score_bigrams(unigrams, bigrams, scorer_w2v, min_count=15)" + "bigram2score = score_bigrams(unigrams, bigrams, scorer_simple, min_count=1)" ] }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 151, "id": "0df71d92", "metadata": { "scrolled": true @@ -844,24 +873,24 @@ { "data": { "text/plain": [ - "[('dow jones', 2053.727832512315),\n", - " ('exit polls', 1973.5230769230768),\n", - " ('норильский никель', 1847.2176),\n", - " ('саудовской аравии', 1831.466983938132),\n", - " ('ak m', 1759.6570644718793),\n", - " ('подписных листов', 1733.5),\n", - " ('подписные листы', 1718.0223214285713),\n", - " ('wall street', 1690.2859686609686),\n", - " ('го чс', 1583.6913580246915),\n", - " ('всея руси', 1574.853794642857),\n", - " ('персидском заливе', 1554.8969696969698),\n", - " ('street journal', 1534.2010030864199),\n", - " ('следственном изоляторе', 1521.094861660079),\n", - " ('мобильном отряде', 1395.4203574203575),\n", - " ('шкале рихтера', 1385.0722591362126)]" + "[('сопоцкина друскеник', 0.5),\n", + " ('неприятель приблизившись', 0.5),\n", + " ('саноку обстреливалась', 0.5),\n", + " ('м.ю лермонтова', 0.5),\n", + " ('австрийский аэроплан', 0.5),\n", + " ('показывался аэроплан-птица', 0.5),\n", + " ('das ist', 0.5),\n", + " ('ist nesteroff', 0.5),\n", + " ('песнь нестерове', 0.5),\n", + " ('могучий унесся', 0.5),\n", + " ('шумели лязгали', 0.5),\n", + " ('зловеще гремели.и', 0.5),\n", + " ('гремели.и пламенно', 0.5),\n", + " ('жаждали битвы…величие', 0.5),\n", + " ('равнине обманчиво-зыбкой.презрение', 0.5)]" ] }, - "execution_count": 51, + "execution_count": 151, "metadata": {}, "output_type": "execute_result" } @@ -890,7 +919,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 153, "id": "36ae2834", "metadata": {}, "outputs": [], @@ -927,7 +956,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 154, "id": "641aa6ca", "metadata": {}, "outputs": [], @@ -937,8 +966,8 @@ }, { "cell_type": "code", - "execution_count": 64, - "id": "edfc0bae", + "execution_count": 155, + "id": "51a57805", "metadata": {}, "outputs": [ { @@ -1947,7 +1976,7 @@ " ...]" ] }, - "execution_count": 64, + "execution_count": 155, "metadata": {}, "output_type": "execute_result" } @@ -2003,7 +2032,7 @@ { "cell_type": "code", "execution_count": 118, - "id": "dfa0f455", + "id": "2f9ab50c", "metadata": {}, "outputs": [], "source": [ @@ -2066,6 +2095,35 @@ "p2 = gensim.models.phrases.Phraser(ph2)" ] }, + { + "cell_type": "code", + "execution_count": 258, + "id": "4de46fe8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['с',\n", + " 'раннего',\n", + " 'утра',\n", + " '14',\n", + " 'сентября',\n", + " 'огонь',\n", + " 'достиг',\n", + " 'значительного',\n", + " 'напряжения']" + ] + }, + "execution_count": 258, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tokenized_sentences[3]" + ] + }, { "cell_type": "code", "execution_count": 122, @@ -2092,30 +2150,6 @@ "p2[p[tokenized_sentences[3]]]" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "22b99b55", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01ae6d1a", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2a06360", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "05e794f1", @@ -2153,7 +2187,7 @@ "metadata": {}, "outputs": [], "source": [ - "finder2 = BigramCollocationFinder.from_documents(tokenized_sentences)" + "finder2 = BigramCollocationFinder.from_documents(tokenized_sentences, )" ] }, { @@ -2168,7 +2202,7 @@ }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 261, "id": "d0827cd1", "metadata": { "scrolled": true @@ -2177,35 +2211,35 @@ { "data": { "text/plain": [ - "[('риа', 'новости'),\n", - " ('об', 'этом'),\n", - " ('со', 'ссылкой'),\n", - " ('кроме', 'того'),\n", - " ('по', 'словам'),\n", - " ('а', 'также'),\n", - " ('сообщает', 'риа'),\n", - " ('ссылкой', 'на'),\n", - " ('настоящее', 'время'),\n", - " ('напомним', 'что'),\n", - " ('во', 'вторник'),\n", - " ('северном', 'кавказе'),\n", - " ('том', 'что'),\n", - " ('том', 'числе'),\n", - " ('как', 'сообщает'),\n", - " ('таким', 'образом'),\n", - " ('миллионов', 'долларов'),\n", - " ('по', 'данным'),\n", - " ('в', 'результате'),\n", - " ('эхо', 'москвы')]" + "[('0,0277/', '0,0281'),\n", + " ('0,06', 'миллиграм'),\n", + " ('0,0698/', '0,07'),\n", + " ('0,14', 'умарджбраилов'),\n", + " ('0,1895/', '0,191'),\n", + " ('0,191', '14,49'),\n", + " ('0,238/', '0,2395'),\n", + " ('0,70', 'процента.проведенное'),\n", + " ('00:16', 'отделилась'),\n", + " ('07.04.2000', '4233'),\n", + " ('1,0510-', '1,0520'),\n", + " ('1,22', 'рубля.стоимость'),\n", + " ('1,85', 'милиона'),\n", + " ('1,987', 'сек2'),\n", + " ('1-ая', 'градская'),\n", + " ('1-му', 'кадашевскому'),\n", + " ('1-с', 'бухгалтерия'),\n", + " ('1.4', 'срабатывает'),\n", + " ('10-14', 'дней.россия'),\n", + " ('10-ая', 'внеочередная')]" ] }, - "execution_count": 127, + "execution_count": 261, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "finder2.nbest(bigram_measures.likelihood_ratio, 20)" + "finder2.nbest(bigram_measures.pmi, 20, )" ] }, { @@ -2247,7 +2281,7 @@ } ], "source": [ - "finder3.nbest(trigram_measures.pmi, 20)" + "finder3.nbest(trigram_measures.lik, 20)" ] }, { @@ -2327,7 +2361,7 @@ "source": [ "У нас есть три основных способа посмотреть на конкретную вероятность:\n", "\n", - "1) в питоне по умолчанию используется запись маленьких и больших чисел через число e в степени. Степень выводится сразу после числа e (если в начале степени стоит - , то это число меньше единицы). Чем больше/меньше степень, тем больше/меньше число" + "1) в питоне по умолчанию используется запись маленьких и больших чисел через умножение на степень 10. Степень выводится сразу после символа e (если в начале степени стоит - , то это число меньше единицы). Чем больше/меньше степень, тем больше/меньше число. E используется просто как сокращение 10^, это не число e." ] }, { @@ -2389,7 +2423,9 @@ "cell_type": "code", "execution_count": 32, "id": "44d45ce0", - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [ { "name": "stdout", @@ -2513,7 +2549,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 273, "id": "3d33ddd0", "metadata": {}, "outputs": [ @@ -2523,7 +2559,7 @@ "(0.0, 0.6931471805599453)" ] }, - "execution_count": 25, + "execution_count": 273, "metadata": {}, "output_type": "execute_result" } @@ -2542,7 +2578,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 275, "id": "2ed0086a", "metadata": {}, "outputs": [ @@ -2552,7 +2588,7 @@ "0.10000000000000002" ] }, - "execution_count": 26, + "execution_count": 275, "metadata": {}, "output_type": "execute_result" } @@ -2561,6 +2597,27 @@ "np.exp(np.log(0.1))" ] }, + { + "cell_type": "code", + "execution_count": 278, + "id": "c41f93b4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.10000000000000009" + ] + }, + "execution_count": 278, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.exp(np.log1p(0.1)) - 1" + ] + }, { "cell_type": "markdown", "id": "e0a48b2b", @@ -2600,7 +2657,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 279, "id": "2793dbb9", "metadata": {}, "outputs": [ @@ -2610,7 +2667,7 @@ "0.0002" ] }, - "execution_count": 28, + "execution_count": 279, "metadata": {}, "output_type": "execute_result" } @@ -2621,7 +2678,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 280, "id": "ed897d24", "metadata": {}, "outputs": [ @@ -2631,7 +2688,7 @@ "0.0002000000000000002" ] }, - "execution_count": 29, + "execution_count": 280, "metadata": {}, "output_type": "execute_result" } @@ -2695,18 +2752,30 @@ }, { "cell_type": "code", - "execution_count": 176, + "execution_count": 298, "id": "32b49cee", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "-102.06520355013919" + ] + }, + "execution_count": 298, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "phrase = 'Технические возможности устаревшего российского судна не позволили разгрузить его у терминала'\n", + "# '{0:.50f}'.format(compute_joint_proba(phrase, probas))\n", "np.log(compute_joint_proba(phrase, probas))" ] }, { "cell_type": "code", - "execution_count": 195, + "execution_count": 299, "id": "62aa2df8", "metadata": {}, "outputs": [ @@ -2716,19 +2785,20 @@ "-17.86851797762613" ] }, - "execution_count": 195, + "execution_count": 299, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phrase = 'сообщает РИА НОВОСТИ'\n", + "# '{0:.50f}'.format(compute_joint_proba(phrase, probas))\n", "np.log(compute_joint_proba(phrase, probas))" ] }, { "cell_type": "markdown", - "id": "5b3c4f41", + "id": "1e69c0db", "metadata": {}, "source": [ "Но такой способ расчета вероятности предложения очень ненадежный, так как рассматривает каждое слово по отдельности." @@ -2736,8 +2806,8 @@ }, { "cell_type": "code", - "execution_count": 192, - "id": "26cb5e77", + "execution_count": 295, + "id": "d89bc36a", "metadata": {}, "outputs": [], "source": [ @@ -2746,8 +2816,8 @@ }, { "cell_type": "code", - "execution_count": 193, - "id": "713a9e16", + "execution_count": 296, + "id": "1b5a608d", "metadata": {}, "outputs": [ { @@ -2756,7 +2826,7 @@ "-93.62260103027181" ] }, - "execution_count": 193, + "execution_count": 296, "metadata": {}, "output_type": "execute_result" } @@ -2767,7 +2837,7 @@ }, { "cell_type": "markdown", - "id": "5577fc96", + "id": "974d234b", "metadata": {}, "source": [ "Слова в предложении - это не независимые события, выбор первого слова сильно влияет на вероятности выбрать второе, третье и так далее." @@ -2775,7 +2845,7 @@ }, { "cell_type": "markdown", - "id": "f3acc90a", + "id": "7e24b45f", "metadata": {}, "source": [ "Такие события можно оценивать по формуле полной вероятности:" @@ -2784,7 +2854,7 @@ { "cell_type": "code", "execution_count": 21, - "id": "8d7b5459", + "id": "255e9117", "metadata": {}, "outputs": [ { @@ -2808,7 +2878,7 @@ }, { "cell_type": "markdown", - "id": "3cb8b9c7", + "id": "d99c01cc", "metadata": {}, "source": [ "А если простыми словами, то для того, чтобы получить вероятность предложения, нужно перемножить `вероятность первого слова`, `вероятность второго слова, при условии первого`, `вероятность третьего при условии первого и второго`, `вероятность четвертого слова, при условии первого, второго и третьего` и так далее до вероятности последнего слова при условии всех предшешевствующих.\n", @@ -2819,7 +2889,7 @@ }, { "cell_type": "markdown", - "id": "c013d42f", + "id": "852a69d8", "metadata": {}, "source": [ "Но тут появляется проблема. Для того, чтобы расчитать полную вероятность предложения нужно, чтобы такое предложение уже встретилось в корпусе хотя бы 1 раз. Очевидно, что даже огромный корпус всего написанного текста не включает в себя все возможные тексты (тем более маленький корпус). Поэтому один из множителей в произведении будет нулевым, а значит и все произведение станет нулевым." @@ -2827,7 +2897,7 @@ }, { "cell_type": "markdown", - "id": "6cfd6db8", + "id": "0f81315b", "metadata": {}, "source": [ "Для того, чтобы этого избежать можно поубавить строгости и предположить, что вероятность слова зависит только от предыдущего слова. Это предположение называется марковским (в честь математика Андрея Маркова). Такую модель еще можно назвать биграммной." @@ -2835,7 +2905,7 @@ }, { "cell_type": "markdown", - "id": "2b17fa35", + "id": "e11afbfe", "metadata": {}, "source": [ "Чтобы расчитать вероятность с таким предположением, нам достаточно найти количество вхождений для каждого биграмма. А частоты отдельных слов у нас уже есть. " @@ -2843,7 +2913,7 @@ }, { "cell_type": "markdown", - "id": "703d50a2", + "id": "3274a46b", "metadata": {}, "source": [ "Вероятность первого слово можно по идее считать просто как вероятность униграмма, но можно сделать небольшое добавление в нашу модель - поставить в начала каждого предложения технический токен начала предложения, а вероятность первого слова рассчитывать как вероятность биграма старт-первое слово поделить на частоту старта. Дальше мы будем генерировать текст с помощью языковой модели и это поможет нам генерировать более красивые предложения.\n", @@ -2859,7 +2929,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9540460e", + "id": "8fc0ce2f", "metadata": {}, "outputs": [], "source": [ @@ -2871,7 +2941,7 @@ { "cell_type": "code", "execution_count": 185, - "id": "7de4c1c0", + "id": "6c1bda7b", "metadata": {}, "outputs": [], "source": [ @@ -2881,7 +2951,7 @@ { "cell_type": "code", "execution_count": 186, - "id": "cc86e70c", + "id": "bd295cda", "metadata": {}, "outputs": [ { @@ -2911,7 +2981,7 @@ { "cell_type": "code", "execution_count": null, - "id": "936b12c4", + "id": "0a23494d", "metadata": {}, "outputs": [], "source": [] @@ -2919,7 +2989,7 @@ { "cell_type": "code", "execution_count": 187, - "id": "ee368249", + "id": "c6de4d6e", "metadata": {}, "outputs": [], "source": [ @@ -2933,7 +3003,7 @@ }, { "cell_type": "markdown", - "id": "7866ad41", + "id": "b5c11e16", "metadata": {}, "source": [ "Чтобы посчитать условную вероятность мы можем поделить количество вхождений на количество вхождений первого слова. Обновим нашу функцию" @@ -2942,7 +3012,7 @@ { "cell_type": "code", "execution_count": 188, - "id": "f8d639b3", + "id": "bfdfa77f", "metadata": {}, "outputs": [], "source": [ @@ -2960,7 +3030,7 @@ }, { "cell_type": "markdown", - "id": "e81006ba", + "id": "9023d8ca", "metadata": {}, "source": [ "Теперь предложение из моего ноутбука не является более вероятным, чем кусок новостного текста" @@ -2969,7 +3039,7 @@ { "cell_type": "code", "execution_count": 191, - "id": "b6ab1213", + "id": "2e40bf3b", "metadata": {}, "outputs": [ { @@ -2991,8 +3061,8 @@ }, { "cell_type": "code", - "execution_count": 194, - "id": "a7eb719d", + "execution_count": 300, + "id": "28b6c33c", "metadata": {}, "outputs": [ { @@ -3001,20 +3071,20 @@ "-72.18104148985773" ] }, - "execution_count": 194, + "execution_count": 300, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "phrase = \"Расчитаем вероятность встретить такой текст в каждом из корпусов\"\n", + "phrase = \"Рассчитаем вероятность встретить такой текст в каждом из корпусов\"\n", "np.log(compute_joint_proba_markov_assumption(phrase, unigrams, bigrams))" ] }, { "cell_type": "code", "execution_count": null, - "id": "f912a23c", + "id": "c6efb6be", "metadata": {}, "outputs": [], "source": []