658 lines
52 KiB
Plaintext
658 lines
52 KiB
Plaintext
|
{
|
||
|
"cells": [
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"### Entropia\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"**Entropia** ($E$) to miara nieuporządkowania, niepewności, niewiedzy. Im\n",
|
||
|
"większa entropia, tym mniej wiemy. Pojęcie to pierwotnie wywodzi się z\n",
|
||
|
"termodynamiki, później znaleziono wiele zaskakujących analogii i zastosowań w\n",
|
||
|
"innych dyscyplinach nauki.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Entropia w fizyce\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"W termodynamice entropia jest miarą nieuporządkowania układów\n",
|
||
|
"fizycznych, na przykład pojemników z gazem. Przykładowo, wyobraźmy\n",
|
||
|
"sobie dwa pojemniki z gazem, w którym panuje różne temperatury.\n",
|
||
|
"\n",
|
||
|
"![img](./03_Entropia/gas-low-entropy.drawio.png)\n",
|
||
|
"\n",
|
||
|
"Jeśli usuniemy przegrodę między pojemnikami, temperatura się wyrówna,\n",
|
||
|
"a uporządkowanie się zmniejszy.\n",
|
||
|
"\n",
|
||
|
"![img](./03_Entropia/gas-high-entropy.drawio.png)\n",
|
||
|
"\n",
|
||
|
"Innymi słowy, zwiększy się stopień nieuporządkowania układu, czyli właśnie entropia.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### II prawo termodynamiki\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Jedno z najbardziej fundamentalnych praw fizyki, II prawo\n",
|
||
|
"termodynamiki głosi, że w układzie zamkniętym entropia nie spada.\n",
|
||
|
"\n",
|
||
|
"****Pytanie****: Czy to, że napisałem te materiały do wykładu i\n",
|
||
|
"*uporządkowałem* wiedzę odnośnie do statystycznych własności języka, nie\n",
|
||
|
"jest sprzeczne z II prawem termodynamiki?\n",
|
||
|
"\n",
|
||
|
"Konsekwencją II prawa termodynamiki jest śmierć cieplna Wszechświata\n",
|
||
|
"(zob. [wizualizacja przyszłości Wszechświata]([https://www.youtube.com/watch?v=uD4izuDMUQA](https://www.youtube.com/watch?v=uD4izuDMUQA))).\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Entropia w teorii informacji\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Pojęcie entropii zostało „odkryte” na nowo przez Claude'a Shannona,\n",
|
||
|
"gdy wypracował ogólną teorię informacji.\n",
|
||
|
"\n",
|
||
|
"Teoria informacji zajmuje się między innymi zagadnieniem optymalnego kodowania komunikatów.\n",
|
||
|
"\n",
|
||
|
"Wyobraźmy sobie pewne źródło (generator) losowych komunikatów z\n",
|
||
|
"zamkniętego zbioru symboli ($\\Sigma$; nieprzypadkowo używamy oznaczeń\n",
|
||
|
"z poprzedniego wykładu). Nadawca $N$ chce przesłać komunikat o wyniku\n",
|
||
|
"losowania do odbiorcy $O$ używając zer i jedynek (bitów).\n",
|
||
|
"Teorioinformacyjną entropię można zdefiniować jako średnią liczbę\n",
|
||
|
"bitów wymaganych do przesłania komunikatu.\n",
|
||
|
"\n",
|
||
|
"![img](./03_Entropia/communication.drawio.png)\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Obliczanie entropii — proste przykłady\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Załóżmy, że nadawca chce przekazać odbiorcy informację o wyniku rzutu monetą.\n",
|
||
|
"Entropia wynosi wówczas rzecz jasna 1 — na jedno losowanie wystarczy jeden bit\n",
|
||
|
"(informację o tym, że wypadł orzeł, możemy zakodować na przykład za pomocą zera,\n",
|
||
|
"zaś to, że wypadła reszka — za pomocą jedynki).\n",
|
||
|
"\n",
|
||
|
"Rozpatrzmy przypadek, gdy nadawca rzuca ośmiościenną kością. Aby przekazać\n",
|
||
|
"wynik, potrzebuje wówczas 3 bity (a więc entropia ośmiościennej kości\n",
|
||
|
"wynosi 3 bity). Przykładowe kodowanie może mieć następującą postać:\n",
|
||
|
"\n",
|
||
|
"| Wynik|Kodowanie|\n",
|
||
|
"|---|---|\n",
|
||
|
"| 1|001|\n",
|
||
|
"| 2|010|\n",
|
||
|
"| 3|011|\n",
|
||
|
"| 4|100|\n",
|
||
|
"| 5|101|\n",
|
||
|
"| 6|110|\n",
|
||
|
"| 7|111|\n",
|
||
|
"| 8|000|\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Obliczenie entropii — trudniejszy przykład\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Załóżmy, że $\\Sigma = \\{A, B, C, D\\}$, natomiast poszczególne komunikaty\n",
|
||
|
"są losowane zgodnie z następującym rozkładem prawdopodobieństwa:\n",
|
||
|
"$P(A)=1/2$, $P(B)=1/4$, $P(C)=1/8$, $P(D)=1/8$. Ile wynosi entropia w\n",
|
||
|
"takim przypadku? Można by sądzić, że 2, skoro wystarczą 2 bity do\n",
|
||
|
"przekazania wyniku losowania przy zastosowaniu następującego kodowania:\n",
|
||
|
"\n",
|
||
|
"| Wynik|Kodowanie|\n",
|
||
|
"|---|---|\n",
|
||
|
"| A|00|\n",
|
||
|
"| B|01|\n",
|
||
|
"| C|10|\n",
|
||
|
"| D|11|\n",
|
||
|
"\n",
|
||
|
"Problem w tym, że w rzeczywistości nie jest to *optymalne* kodowanie.\n",
|
||
|
"Możemy sprytnie zmniejszyć średnią liczbę bitów wymaganych do\n",
|
||
|
"przekazania losowego wyniku przypisując częstszym wynikom krótsze\n",
|
||
|
"kody, rzadszym zaś — dłuższe. Oto takie optymalne kodowanie:\n",
|
||
|
"\n",
|
||
|
"| Wynik|Kodowanie|\n",
|
||
|
"|---|---|\n",
|
||
|
"| A|0|\n",
|
||
|
"| B|10|\n",
|
||
|
"| C|110|\n",
|
||
|
"| D|111|\n",
|
||
|
"\n",
|
||
|
"Używając takiego kodowanie średnio potrzebujemy:\n",
|
||
|
"\n",
|
||
|
"$$\\frac{1}{2}1 + \\frac{1}{4}2 + \\frac{1}{8}3 + \\frac{1}{8}3 = 1,75$$\n",
|
||
|
"\n",
|
||
|
"bita. Innymi słowy, entropia takiego źródła wynosi 1,75 bita.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Kodowanie musi być jednoznaczne!\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Można by sądzić, że da się stworzyć jeszcze krótsze kodowanie dla omawianego rozkładu nierównomiernego:\n",
|
||
|
"\n",
|
||
|
"| Wynik|Kodowanie|\n",
|
||
|
"|---|---|\n",
|
||
|
"| A|0|\n",
|
||
|
"| B|1|\n",
|
||
|
"| C|01|\n",
|
||
|
"| D|11|\n",
|
||
|
"\n",
|
||
|
"Niestety, nie jest to właściwe rozwiązanie — kodowanie musi być\n",
|
||
|
"jednoznaczne nie tylko dla pojedynczego komunikatu, lecz dla całej sekwencji.\n",
|
||
|
"Na przykład ciąg 0111 nie jest jednoznaczny przy tym kodowaniu (ABBB czy CD?).\n",
|
||
|
"Podane wcześniej kodowanie spełnia warunek jednoznaczności, ciąg 0111 można odkodować tylko\n",
|
||
|
"jako AD.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Ogólny wzór na entropię.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Na podstawie poprzedniego przykładu można dojść do intuicyjnego wniosku, że\n",
|
||
|
"optymalny kod dla wyniku o prawdopodobieństwie $p$ ma długość $-\\log_2(p)$, a zatem ogólnie\n",
|
||
|
"entropia źródła o rozkładzie prawdopodobieństwa $\\{p_1,\\ldots,p_|\\Sigma|\\}$ wynosi:\n",
|
||
|
"\n",
|
||
|
"$$E = -\\sum_{i=1}^{|\\Sigma|} p_i\\log_2(p_i)$$.\n",
|
||
|
"\n",
|
||
|
"Zauważmy, że jest to jeden z nielicznych przypadków, gdy w nauce naturalną\n",
|
||
|
"podstawą logarytmu jest 2 zamiast… podstawy logarytmu naturalnego ($e$).\n",
|
||
|
"\n",
|
||
|
"Teoretycznie można mierzyć entropię używając logarytmu naturalnego\n",
|
||
|
"($\\ln$), jednostką entropii będzie wówczas **nat** zamiast bita,\n",
|
||
|
"niewiele to jednak zmienia i jest mniej poręczne i trudniejsze do interpretacji\n",
|
||
|
"(przynajmniej w kontekście informatyki) niż operowanie na bitach.\n",
|
||
|
"\n",
|
||
|
"****Pytanie**** Ile wynosi entropia zwykłej sześciennej kostki? Jak wygląda\n",
|
||
|
"optymalne kodowanie wyników rzutu taką kostką?\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Entropia dla próby Bernoulliego\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Wiemy już, że entropia dla rzutu monetą wynosi 1 bit. A jaki będzie wynik dla źle wyważonej monety?\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"data": {
|
||
|
"image/png": "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
|
||
|
"text/plain": [
|
||
|
"<matplotlib.figure.Figure>"
|
||
|
]
|
||
|
},
|
||
|
"metadata": {},
|
||
|
"output_type": "display_data"
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"import matplotlib.pyplot as plt\n",
|
||
|
"from math import log\n",
|
||
|
"import numpy as np\n",
|
||
|
"\n",
|
||
|
"def binomial_entropy(p):\n",
|
||
|
" return -(p * log(p, 2) + (1-p) * log(1-p, 2))\n",
|
||
|
"\n",
|
||
|
"x = list(np.arange(0.001,1,0.001))\n",
|
||
|
"y = [binomial_entropy(x) for x in x]\n",
|
||
|
"plt.figure().clear()\n",
|
||
|
"plt.xlabel('prawdopodobieństwo wylosowania orła')\n",
|
||
|
"plt.ylabel('entropia')\n",
|
||
|
"plt.plot(x, y)\n",
|
||
|
"\n",
|
||
|
"fname = f'03_Entropia/binomial-entropy.png'\n",
|
||
|
"\n",
|
||
|
"plt.savefig(fname)\n",
|
||
|
"\n",
|
||
|
"fname"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"**Pytanie** Dla oszukańczej monety (np. dla której wypada zawsze orzeł) entropia\n",
|
||
|
"wynosi 0, czy to wynik zgodny z intuicją?\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"### Entropia a język\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Tekst w danym języku możemy traktować jako ciąg symboli (komunikatów) losowanych według jakiegoś\n",
|
||
|
"rozkładu prawdopodobieństwa. W tym sensie możemy mówić o entropii języka.\n",
|
||
|
"\n",
|
||
|
"Oczywiście, jak zawsze, musimy jasno stwierdzić, czym są symbole\n",
|
||
|
"języka: literami, wyrazami czy jeszcze jakimiś innymi jednostkami.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Pomiar entropii języka — pierwsze przybliżenie\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Załóżmy, że chcemy zmierzyć entropię języka polskiego na przykładzie\n",
|
||
|
"„Pana Tadeusza” — na poziomie znaków. W pierwszym przybliżeniu można\n",
|
||
|
"by policzyć liczbę wszystkich znaków…\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"['K', 's', 'i', 'ę', 'g', 'a', ' ', 'p', 'i', 'e', 'r', 'w', 's', 'z', 'a', '\\r', '\\n', '\\r', '\\n', '\\r', '\\n', '\\r', '\\n', 'G', 'o', 's', 'p', 'o', 'd', 'a', 'r', 's', 't', 'w', 'o', '\\r', '\\n', '\\r', '\\n', 'P', 'o', 'w', 'r', 'ó', 't', ' ', 'p', 'a', 'n', 'i']"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"import requests\n",
|
||
|
"from itertools import islice\n",
|
||
|
"\n",
|
||
|
"url = 'https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt'\n",
|
||
|
"pan_tadeusz = requests.get(url).content.decode('utf-8')\n",
|
||
|
"\n",
|
||
|
"def get_characters(t):\n",
|
||
|
" yield from t\n",
|
||
|
"\n",
|
||
|
"list(islice(get_characters(pan_tadeusz), 100, 150))"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"95"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"chars_in_pan_tadeusz = len(set(get_characters(pan_tadeusz)))\n",
|
||
|
"chars_in_pan_tadeusz"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"… założyć jednostajny rozkład prawdopodobieństwa i w ten sposób policzyć entropię:\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"6.569855608330948"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"from math import log\n",
|
||
|
"\n",
|
||
|
"95 * (1/95) * log(95, 2)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Mniej rozrzutne kodowanie\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Przypomnijmy sobie jednak, że rozkład jednostek języka jest zawsze\n",
|
||
|
"skrajnie nierównomierny! Jeśli uwzględnić ten nierównomierny rozkład\n",
|
||
|
"znaków, można opracować o wiele efektywniejszy sposób zakodowania znaków składających się na „Pana Tadeusza”\n",
|
||
|
"(częste litery, np. „a” i „e” powinny mieć krótkie kody, a rzadkie, np. „ź” — dłuższe).\n",
|
||
|
"\n",
|
||
|
"Policzmy entropię przy takim założeniu:\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"4.938605272823633"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"from collections import Counter\n",
|
||
|
"from math import log\n",
|
||
|
"\n",
|
||
|
"def unigram_entropy(t):\n",
|
||
|
" counter = Counter(t)\n",
|
||
|
"\n",
|
||
|
" total = counter.total()\n",
|
||
|
" return -sum((p := count / total) * log(p, 2) for count in counter.values())\n",
|
||
|
"\n",
|
||
|
"unigram_entropy(get_characters(pan_tadeusz))"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"(Jak dowiemy się na kolejnym wykładzie, zastosowaliśmy tutaj **unigramowy model języka**).\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Ile wynosi entropia rękopisu Wojnicza?\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"9 OR 9FAM ZO8 QOAR9 Q*R 8ARAM 29 [O82*]OM OPCC9 OP"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"import requests\n",
|
||
|
"import re\n",
|
||
|
"\n",
|
||
|
"voynich_url = 'http://www.voynich.net/reeds/gillogly/voynich.now'\n",
|
||
|
"voynich = requests.get(voynich_url).content.decode('utf-8')\n",
|
||
|
"\n",
|
||
|
"voynich = re.sub(r'\\{[^\\}]+\\}|^<[^>]+>|[-# ]+', '', voynich, flags=re.MULTILINE)\n",
|
||
|
"\n",
|
||
|
"voynich = voynich.replace('\\n\\n', '#')\n",
|
||
|
"voynich = voynich.replace('\\n', ' ')\n",
|
||
|
"voynich = voynich.replace('#', '\\n')\n",
|
||
|
"\n",
|
||
|
"voynich = voynich.replace('.', ' ')\n",
|
||
|
"\n",
|
||
|
"voynich[100:150]"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"3.902708104423842"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"unigram_entropy(get_characters(voynich))"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Rzeczywista entropia?\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"W rzeczywistości entropia jest jeszcze mniejsza, tekst nie jest\n",
|
||
|
"generowany przecież według rozkładu wielomianowego. Istnieją rzecz\n",
|
||
|
"jasna pewne zależności między znakami, np. niemożliwe, żeby po „ń”\n",
|
||
|
"wystąpiły litera „a” czy „e”. Na poziomie wyrazów zależności mogę mieć\n",
|
||
|
"jeszcze bardziej skrajny charakter, np. po wyrazie „przede” prawie na\n",
|
||
|
"pewno wystąpi „wszystkim”, co oznacza, że w takiej sytuacji słowo\n",
|
||
|
"„wszystkim” może zostać zakodowane za pomocą 0 (!) bitów.\n",
|
||
|
"\n",
|
||
|
"Można uwzględnić takie zależności i uzyskać jeszcze lepsze kodowanie,\n",
|
||
|
"a co za tym idzie lepsze oszacowanie entropii. (Jak wkrótce się\n",
|
||
|
"dowiemy, oznacza to użycie digramowego, trigramowego, etc. modelu języka).\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Rozmiar skompresowanego pliku jako przybliżenie entropii\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Celem algorytmów kompresji jest właściwie wyznaczanie efektywnych\n",
|
||
|
"sposobów kodowania danych. Możemy więc użyć rozmiaru skompresowanego pliku w bitach\n",
|
||
|
"(po podzieleniu przez oryginalną długość) jako dobrego przybliżenia entropii.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"3.673019884633768"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"import zlib\n",
|
||
|
"\n",
|
||
|
"def entropy_by_compression(t):\n",
|
||
|
" compressed = zlib.compress(t.encode('utf-8'))\n",
|
||
|
" return 8 * len(compressed) / len(t)\n",
|
||
|
"\n",
|
||
|
"entropy_by_compression(pan_tadeusz)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Dla porównania wynik dla rękopisu Wojnicza:\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"2.942372881355932"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"entropy_by_compression(voynich)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"#### Gra Shannona\n",
|
||
|
"\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Innym sposobem oszacowania entropii tekstu jest użycie… ludzi. Można poprosić rodzimych użytkowników\n",
|
||
|
"danego języka o przewidywanie kolejnych liter (bądź wyrazów) i w ten sposób oszacować entropię.\n",
|
||
|
"\n",
|
||
|
"**Projekt** Zaimplementuj aplikację webową, która umożliwi „rozegranie” gry Shannona.\n",
|
||
|
"\n"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"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.10.2"
|
||
|
},
|
||
|
"org": null
|
||
|
},
|
||
|
"nbformat": 4,
|
||
|
"nbformat_minor": 1
|
||
|
}
|