refactor
@ -17,7 +17,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -52,31 +52,30 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"c = '⨃'"
|
||||
"- 2. wiersz 5 + 6 = 11\n",
|
||||
"- 3. wiersz 16"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"10755"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ord(c)"
|
||||
"2A03"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"c = '⨃'"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -87,7 +86,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'⨃'"
|
||||
"10755"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
@ -95,10 +94,70 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ord(c)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'⨃'"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chr(10755)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"10755 - 2*16**3 - 10*16**2 - 0 * 16**1 - 3 *16**0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"10755 - 2*16**3 - 10*16**2 - 0* 16**1 - 3* 16**0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
@ -119,6 +178,15 @@
|
||||
"10755 - 2* 16**3 - 10* 16**2 - 0 * 16**1 - 3* 16**0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"2A03"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@ -129,7 +197,27 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"515"
|
||||
]
|
||||
},
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"10755 - 1 * 2**13 - 0 * 2 **12 - 1* 2 **11"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -138,7 +226,7 @@
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"execution_count": 29,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -147,6 +235,26 @@
|
||||
"10755 - 1*2**13 - 0*2**12 - 1*2**11 - 0*2**10 - 1*2**9 -0*2**8 -0*2**7-0*2**6-0*2**5-0*2**4-0*2**3-0*2**2-0*2**1 - 1*2**1 - 1*2**0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"-1533"
|
||||
]
|
||||
},
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"10755 - 1*2 ** 13 - 0* 2 ** 12"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@ -156,7 +264,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -165,7 +273,7 @@
|
||||
"14"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -176,7 +284,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 30,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -185,13 +293,13 @@
|
||||
"'0010101000000011'"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"execution_count": 30,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"'0010101000000011'"
|
||||
"''"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -201,6 +309,26 @@
|
||||
"1110xxxx\t10xxxxxx\t10xxxxxx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'11100010 10101000 10000011'"
|
||||
]
|
||||
},
|
||||
"execution_count": 32,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"'11100010 10101000 10000011'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@ -230,7 +358,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 29,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -239,7 +367,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -302,7 +430,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -311,7 +439,7 @@
|
||||
"'U'"
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -322,16 +450,105 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": 49,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"NR_INDEKSU = 426206"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 51,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'ϙ'"
|
||||
"'11001110'"
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"execution_count": 51,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"'11001110'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"110xxxxx 10xxxxxx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 53,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'11000011 10001110'"
|
||||
]
|
||||
},
|
||||
"execution_count": 53,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"'11000011 10001110'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 52,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"8"
|
||||
]
|
||||
},
|
||||
"execution_count": 52,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"len('11001110')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 50,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'Î'"
|
||||
]
|
||||
},
|
||||
"execution_count": 50,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -342,7 +559,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -351,7 +568,7 @@
|
||||
"'\\U00012856'"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -434,7 +651,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 37,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -443,7 +660,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -452,7 +669,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": 46,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -461,7 +678,27 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'\\x0e'"
|
||||
]
|
||||
},
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chr(14)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 41,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
@ -472,7 +709,7 @@
|
||||
"'00101100 00001010 01001010 01100001 01101011 00100000 01100010 01111001 11000101 10000010 00100000 01010011 01110100 01100101 01100110 01100101 01101011 00100000 01000010 01110101 01110010 01100011 01111010 01111001 01101101 01110101 01100011 01101000 01100001 11100010 10000000 10100110 00001010 11100010 10000000 10010100 00100000 01001010 01100001 00100000 01101110 01101001 01101011 01101111 01100111 01101111 00100000 01110011 01101001 11000100 10011001 00100000 01101110 01101001 01100101 00100000 01100010 01101111 01101010 11000100 10011001 00100001 00001010 01000011 01101000 01101111 11000100 10000111 01100010 01111001 00100000 01101110 01101001 01100101 01100100 11000101 10111010 01110111 01101001 01100101 01100100 11000101 10111010 11100010 10000000 10100110 00100000 01110100'"
|
||||
]
|
||||
},
|
||||
"execution_count": 12,
|
||||
"execution_count": 41,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -506,7 +743,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -515,7 +752,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": 43,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -524,7 +761,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": 44,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -533,7 +770,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": 45,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
@ -544,7 +781,7 @@
|
||||
"'0x2e 0x20 0x31 0x36 0x37 0x30 0x2c 0x20 0x70 0x72 0x7a 0x65 0x64 0x20 0x75 0x70 0x61 0x64 0x6b 0x69 0x65 0x6d 0x20 0x4b 0x61 0x6d 0x69 0x65 0xc5 0x84 0x63 0x61 0x20 0x69 0x20 0x68 0x61 0x6e 0x69 0x65 0x62 0x6e 0x79 0x6d 0x69 0x20 0x75 0x6b 0xc5 0x82 0x61 0x64 0x61 0x6d 0x69 0x20 0x62 0x75 0x63 0x7a 0x61 0x63 0x6b 0x69 0x6d 0x69 0x2c 0x20 0x6b 0x74 0xc3 0xb3 0x72 0x65 0x20 0x6f 0x62 0x6f 0x77 0x69 0xc4 0x85 0x7a 0x79 0x77 0x61 0xc5 0x82'"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"execution_count": 45,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -641,7 +878,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"execution_count": 56,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -657,7 +894,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"execution_count": 57,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -666,7 +903,7 @@
|
||||
"['A', 'B', 'a', 'b', 'ce', 'cef', 'Ą', 'ą', 'ż']"
|
||||
]
|
||||
},
|
||||
"execution_count": 33,
|
||||
"execution_count": 57,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -684,7 +921,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"execution_count": 58,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -693,7 +930,7 @@
|
||||
"['A', 'Ą', 'a', 'ą', 'B', 'b', 'ce', 'cef', 'ż']"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
"execution_count": 58,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -704,7 +941,16 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"execution_count": 59,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"?sorted"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 60,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -713,13 +959,134 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 36,
|
||||
"execution_count": 61,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tekst = [x for x in ' '.join(tekst).split(' ') if x ][NR_INDEKSU % 1000 : NR_INDEKSU % 1000 + 100]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 52,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['uczuła',\n",
|
||||
" 'odurzenie,',\n",
|
||||
" 'wróciła',\n",
|
||||
" 'do',\n",
|
||||
" 'swej',\n",
|
||||
" 'nursery',\n",
|
||||
" 'i',\n",
|
||||
" 'znów',\n",
|
||||
" 'się',\n",
|
||||
" 'zamknęła,',\n",
|
||||
" 'przestraszona',\n",
|
||||
" 'krzykami',\n",
|
||||
" 'i',\n",
|
||||
" 'odgłosami',\n",
|
||||
" 'uciekających',\n",
|
||||
" 'kroków.',\n",
|
||||
" 'Uczuła',\n",
|
||||
" 'ogarniającą',\n",
|
||||
" 'ją,',\n",
|
||||
" 'nieprzezwyciężoną',\n",
|
||||
" 'senność,',\n",
|
||||
" 'położyła',\n",
|
||||
" 'się',\n",
|
||||
" 'na',\n",
|
||||
" 'łóżeczku',\n",
|
||||
" 'i',\n",
|
||||
" 'na',\n",
|
||||
" 'bardzo',\n",
|
||||
" 'długo',\n",
|
||||
" 'straciła',\n",
|
||||
" 'świadomość',\n",
|
||||
" 'tego,',\n",
|
||||
" 'co',\n",
|
||||
" 'się',\n",
|
||||
" 'wkoło',\n",
|
||||
" 'niej',\n",
|
||||
" 'dzieje.',\n",
|
||||
" 'Tymczasem',\n",
|
||||
" 'zaszło',\n",
|
||||
" 'bardzo',\n",
|
||||
" 'wiele,',\n",
|
||||
" 'gdy',\n",
|
||||
" 'Mary',\n",
|
||||
" 'spała',\n",
|
||||
" 'snem',\n",
|
||||
" 'tak',\n",
|
||||
" 'twardym,',\n",
|
||||
" 'lecz',\n",
|
||||
" 'jej',\n",
|
||||
" 'już',\n",
|
||||
" 'nie',\n",
|
||||
" 'budziły',\n",
|
||||
" 'ani',\n",
|
||||
" 'jęki,',\n",
|
||||
" 'ani',\n",
|
||||
" 'odgłosy',\n",
|
||||
" 'wnoszonych',\n",
|
||||
" 'i',\n",
|
||||
" 'wynoszonych',\n",
|
||||
" 'przedmiotów.',\n",
|
||||
" 'Po',\n",
|
||||
" 'przebudzeniu',\n",
|
||||
" 'Mary',\n",
|
||||
" 'leżała',\n",
|
||||
" 'jeszcze,',\n",
|
||||
" 'patrząc',\n",
|
||||
" 'w',\n",
|
||||
" 'sufit.',\n",
|
||||
" 'W',\n",
|
||||
" 'domu',\n",
|
||||
" 'była',\n",
|
||||
" 'cisza',\n",
|
||||
" 'zupełna.',\n",
|
||||
" 'Nie',\n",
|
||||
" 'znała',\n",
|
||||
" 'ona',\n",
|
||||
" 'ciszy',\n",
|
||||
" 'takiej',\n",
|
||||
" 'nigdy',\n",
|
||||
" 'przedtem.',\n",
|
||||
" 'Nie',\n",
|
||||
" 'słyszała',\n",
|
||||
" 'ani',\n",
|
||||
" 'głosów,',\n",
|
||||
" 'ani',\n",
|
||||
" 'kroków',\n",
|
||||
" 'niczyich',\n",
|
||||
" 'i',\n",
|
||||
" 'ciekawa',\n",
|
||||
" 'była,',\n",
|
||||
" 'czy',\n",
|
||||
" 'już',\n",
|
||||
" 'wszyscy',\n",
|
||||
" 'wyzdrowieli',\n",
|
||||
" 'i',\n",
|
||||
" 'czy',\n",
|
||||
" 'trwoga',\n",
|
||||
" 'minęła.',\n",
|
||||
" 'Ciekawa',\n",
|
||||
" 'też']"
|
||||
]
|
||||
},
|
||||
"execution_count": 52,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"tekst"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
819
wyk/01_Jezyk.ipynb
Normal file
@ -0,0 +1,819 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
|
||||
"<div class=\"alert alert-block alert-info\">\n",
|
||||
"<h1> Modelowanie języka </h1>\n",
|
||||
"<h2> 1. <i>Język i jego zapis</i> [wykład]</h2> \n",
|
||||
"<h3> Filip Graliński (2022)</h3>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Język — różne perspektywy\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Słowo wstępne\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"W matematyce istnieją dwa spojrzenia na rzeczywistość: ciągłe i dyskretne.\n",
|
||||
"\n",
|
||||
"Otaczająca nas rzeczywistość fizyczna jest z natury ciągła\n",
|
||||
"(przynajmniej jeśli nie operujemy w mikroskali), lecz język\n",
|
||||
"jest dyskretnym wyłomem w ciągłej rzeczywistości.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Lingwistyka matematyczna\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Przypomnijmy sobie definicję języka przyjętą w lingwistyce\n",
|
||||
"matematycznej, w kontekście, na przykład, teorii automatów.\n",
|
||||
"\n",
|
||||
"****Alfabetem**** nazywamy skończony zbiór symboli.\n",
|
||||
"\n",
|
||||
"****Łańcuchem**** (****napisem****) nad alfabetem $\\Sigma$ nazywamy dowolny, skończony,\n",
|
||||
"ciąg złożony z symboli z $\\Sigma$.\n",
|
||||
"\n",
|
||||
"****Językiem**** nazywamy dowolny, skończony bądź nieskończony, zbiór łańcuchów.\n",
|
||||
"\n",
|
||||
"W tym formalnym ujęciu językami są na przykład następujące zbiory:\n",
|
||||
"\n",
|
||||
"- $\\{\\mathit{poniedziałek},\\mathit{wtorek},\\mathit{środa},\\mathit{czwartek},\\mathit{piątek},\\mathit{sobota},\\mathit{niedziela}\\}$\n",
|
||||
"- $\\{\\mathit{ab},\\mathit{abb},\\mathit{abbb},\\mathit{abbbb},\\ldots\\}$\n",
|
||||
"\n",
|
||||
"To podejście, z jednej strony oczywiście nie do końca się pokrywa się z potocznym\n",
|
||||
"rozumieniem słowa *język*, z drugiej kojarzy nam się z takimi\n",
|
||||
"narzędziami informatyki jak wyrażenia regularne, automaty skończenie\n",
|
||||
"stanowe czy gramatyki języków programowania.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"abbb"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import regex as re\n",
|
||||
"rx = re.compile(r'ab+')\n",
|
||||
"\n",
|
||||
"rx.search('żabbba').group(0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import rstr\n",
|
||||
"\n",
|
||||
"rstr.xeger(r'ab+')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Ujęcie probabilistyczne\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Na tym wykładzie przyjmiemy inną perspektywą, częściowo ciągłą, opartą\n",
|
||||
"na probabilistyce. Język będziemy definiować poprzez ****rozkład\n",
|
||||
"prawdopodobieństwa****: sensownym wypowiedziom czy tekstom będziemy\n",
|
||||
"przypisywać stosunkowe wysokie prawdopodobieństwo, „ułomnym” tekstom — niższe (być może zerowe).\n",
|
||||
"\n",
|
||||
"Na ogół nie mamy jednak do czynienia z językiem jako takim tylko z\n",
|
||||
"jego przybliżeniami, ****modelami**** (model może być lepszy lub gorszy,\n",
|
||||
"ale przynajmniej powinien być użyteczny…). Formalnie $M$ nazywamy\n",
|
||||
"modelem języka (nad skończonym alfabetem $\\Sigma$), jeśli określa dyskretny rozkład prawdopodobieństwa $P_M$:\n",
|
||||
"\n",
|
||||
"$$P_M \\colon \\Sigma^{*} \\rightarrow [0,1].$$\n",
|
||||
"\n",
|
||||
"Rzecz jasna, skoro mamy do czynienia z rozkładem prawdopodobieństwa, to:\n",
|
||||
"\n",
|
||||
"$$\\sum_{\\alpha \\in \\Sigma^{*}} P_M(\\alpha) = 1.$$\n",
|
||||
"\n",
|
||||
"Jeśli $M$ ma być modelem języka polskiego, oczekiwalibyśmy, że dla\n",
|
||||
"napisów:\n",
|
||||
"\n",
|
||||
"- $z_1$ — *W tym stanie rzeczy pan Ignacy coraz częściej myślał o Wokulskim.*\n",
|
||||
"- $z_2$ — *Po wypełniony zbiornik pełny i należne kwotę, usłyszała w attendant*\n",
|
||||
"- $z_3$ — *xxxxyźźźźźit backspace hoooooooooop x y z*\n",
|
||||
"\n",
|
||||
"zachodzić będzie:\n",
|
||||
"\n",
|
||||
"$$ P_M(z_1) > P_M(z_2) > P_M(z_3). $$\n",
|
||||
"\n",
|
||||
"****Pytanie**** Jakiej konkretnie wartości prawdopodobieństwa\n",
|
||||
"spodziewalibyśmy się dla zdania *Dzisiaj rano kupiłem w piekarni sześć bułek*\n",
|
||||
"dla sensownego modelu języka polskiego?\n",
|
||||
"\n",
|
||||
"Moglibyśmy sprowadzić tę definicję języka do tej „dyskretnej”, tzn.\n",
|
||||
"moglibyśmy przyjąć, że łańcuch $\\alpha$ należy do języka wyznaczonego\n",
|
||||
"przez model $M$, jeśli $P_M(\\alpha) > 0$.\n",
|
||||
"\n",
|
||||
"****Pytanie**** Czy moglibyśmy w ten sposób opisać język nieskończony? Czy może istnieć\n",
|
||||
"dyskretny rozkład prawdopodobieństwa dla nieskończonego zbioru?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Co jest symbolem?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Model języka daje rozkład prawdopodobieństwa nad zbiorem łańcuchów\n",
|
||||
"opartym na skończonym alfabecie, tj. zbiorze symboli. W praktyce\n",
|
||||
"alfabet nie musi być zgodny z potocznym czy językoznawczym rozumieniem\n",
|
||||
"tego słowa. To znaczy alfabet może być zbiorem znaków (liter), ale\n",
|
||||
"modelować język możemy też przyjmując inny typ symboli: sylaby,\n",
|
||||
"morfemy (cząstki wyrazów) czy po prostu całe wyrazy.\n",
|
||||
"\n",
|
||||
"Powinniśmy przy tym pamiętać, że, koniec końców, w pamięci komputera\n",
|
||||
"wszelkiego rodzaju łańcuchy są zapisywane jako ciągi zer i jedynek — bitów.\n",
|
||||
"Omówmy pokrótce techniczną stronę modelowania języka.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kodowanie znaków\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Cóż może być prostszego od pliku tekstowego?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
" Ala ma kota.\n",
|
||||
"\n",
|
||||
"Komputer nic nie wie o literach.\n",
|
||||
"\n",
|
||||
"… w rzeczywistości operuje tylko na liczbach …\n",
|
||||
"\n",
|
||||
"… czy raczej na zerach i jedynkach …\n",
|
||||
"\n",
|
||||
"… a tak naprawdę na ciągłym sygnale elektrycznym …\n",
|
||||
"\n",
|
||||
"![img](./01_Jezyk/digitalsignal.jpg)\n",
|
||||
"\n",
|
||||
"… zera i jedynki są w naszej głowie …\n",
|
||||
"\n",
|
||||
"… co jest dziwne, *naprawdę* dziwne …\n",
|
||||
"\n",
|
||||
"… ale nikt normalny się tym nie przejmuje.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Jak zakodować literę?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zakodowanie pikseli składających się na kształtu (****glyfu****) litery A\n",
|
||||
"*oczywiście* nie jest dobrym pomysłem.\n",
|
||||
"\n",
|
||||
"![img](./01_Jezyk/raster.png)\n",
|
||||
"\n",
|
||||
"Nie, potrzebujemy *arbitralnego* kodowania dla wszystkich możliwych\n",
|
||||
"kształtów litery A (*w naszych głowach*): A, $\\mathcal{A}$,\n",
|
||||
"$\\mathbb{A}$, $\\mathfrak{A}$ powinny otrzymać ten sam kod, powiedzmy 65\n",
|
||||
"(binarnie: 1000001).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### ASCII\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"ASCII to 7-bitowy (****nie**** 8-bitowy!) system kodowania znaków.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0: \u0000\n",
|
||||
"1: \u0001\n",
|
||||
"2: \u0002\n",
|
||||
"3: \u0003\n",
|
||||
"4: \u0004\n",
|
||||
"5: \u0005\n",
|
||||
"6: \u0006\n",
|
||||
"7: \u0007\n",
|
||||
"8: \b\n",
|
||||
"9:\n",
|
||||
"10:\n",
|
||||
"\n",
|
||||
"11: \u000b",
|
||||
"\n",
|
||||
"12: \f",
|
||||
"\n",
|
||||
"13:\n",
|
||||
"14: \u000e\n",
|
||||
"15: \u000f\n",
|
||||
"16: \u0010\n",
|
||||
"17: \u0011\n",
|
||||
"18: \u0012\n",
|
||||
"19: \u0013\n",
|
||||
"20: \u0014\n",
|
||||
"21: \u0015\n",
|
||||
"22: \u0016\n",
|
||||
"23: \u0017\n",
|
||||
"24: \u0018\n",
|
||||
"25: \u0019\n",
|
||||
"26: \u001a\n",
|
||||
"27: \u001b\n",
|
||||
"28: \u001c",
|
||||
"\n",
|
||||
"29: \u001d",
|
||||
"\n",
|
||||
"30: \u001e",
|
||||
"\n",
|
||||
"31: \u001f\n",
|
||||
"32:\n",
|
||||
"33: !\n",
|
||||
"34: \"\n",
|
||||
"35: #\n",
|
||||
"36: $\n",
|
||||
"37: %\n",
|
||||
"38: &\n",
|
||||
"39: '\n",
|
||||
"40: (\n",
|
||||
"41: )\n",
|
||||
"42: *\n",
|
||||
"43: +\n",
|
||||
"44: ,\n",
|
||||
"45: -\n",
|
||||
"46: .\n",
|
||||
"47: /\n",
|
||||
"48: 0\n",
|
||||
"49: 1\n",
|
||||
"50: 2\n",
|
||||
"51: 3\n",
|
||||
"52: 4\n",
|
||||
"53: 5\n",
|
||||
"54: 6\n",
|
||||
"55: 7\n",
|
||||
"56: 8\n",
|
||||
"57: 9\n",
|
||||
"58: :\n",
|
||||
"59: ;\n",
|
||||
"60: <\n",
|
||||
"61: =\n",
|
||||
"62: >\n",
|
||||
"63: ?\n",
|
||||
"64: @\n",
|
||||
"65: A\n",
|
||||
"66: B\n",
|
||||
"67: C\n",
|
||||
"68: D\n",
|
||||
"69: E\n",
|
||||
"70: F\n",
|
||||
"71: G\n",
|
||||
"72: H\n",
|
||||
"73: I\n",
|
||||
"74: J\n",
|
||||
"75: K\n",
|
||||
"76: L\n",
|
||||
"77: M\n",
|
||||
"78: N\n",
|
||||
"79: O\n",
|
||||
"80: P\n",
|
||||
"81: Q\n",
|
||||
"82: R\n",
|
||||
"83: S\n",
|
||||
"84: T\n",
|
||||
"85: U\n",
|
||||
"86: V\n",
|
||||
"87: W\n",
|
||||
"88: X\n",
|
||||
"89: Y\n",
|
||||
"90: Z\n",
|
||||
"91: [\n",
|
||||
"92: \\\n",
|
||||
"93: ]\n",
|
||||
"94: ^\n",
|
||||
"95: _\n",
|
||||
"96: `\n",
|
||||
"97: a\n",
|
||||
"98: b\n",
|
||||
"99: c\n",
|
||||
"100: d\n",
|
||||
"101: e\n",
|
||||
"102: f\n",
|
||||
"103: g\n",
|
||||
"104: h\n",
|
||||
"105: i\n",
|
||||
"106: j\n",
|
||||
"107: k\n",
|
||||
"108: l\n",
|
||||
"109: m\n",
|
||||
"110: n\n",
|
||||
"111: o\n",
|
||||
"112: p\n",
|
||||
"113: q\n",
|
||||
"114: r\n",
|
||||
"115: s\n",
|
||||
"116: t\n",
|
||||
"117: u\n",
|
||||
"118: v\n",
|
||||
"119: w\n",
|
||||
"120: x\n",
|
||||
"121: y\n",
|
||||
"122: z\n",
|
||||
"123: {\n",
|
||||
"124: |\n",
|
||||
"125: }\n",
|
||||
"126: ~\n",
|
||||
"127: "
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for code in range(0, 128):\n",
|
||||
" print(f'{code}: {chr(code)}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Jak zejść na poziom bitów?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Linux — wiersz poleceń\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Linux command line:\n",
|
||||
"\n",
|
||||
" $ echo 'Ala ma kota' > file.txt\n",
|
||||
" $ hexdump -C file.txt\n",
|
||||
" 00000000 41 6c 61 20 6d 61 20 6b 6f 74 61 0a |Ala ma kota.|\n",
|
||||
" 0000000c\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Edytor tekstu (Emacs)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![img](./01_Jezyk/hexl-mode.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Uwaga!\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- kiedy dzieje się coś dziwnego, sprawdź, co tak *naprawdę* jest w pliku\n",
|
||||
"- ASCII jest 7-bitowym kodowaniem (128 znaków)\n",
|
||||
" - choć zazwyczaj uzupełnionym (ang. *padded*) do 8 bitów\n",
|
||||
" - nie mów plik *plik ASCII*, kiedy masz na myśli *prosty/czysty plik tekstowy* (ang. *plain text file*)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Higiena plików tekstowych\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Piekło końca wiersza\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![img](./01_Jezyk/dante.jpg)\n",
|
||||
"\n",
|
||||
"Więcej na [https://re-research.pl/pl/post/2017-01-28-00042-anatomia-pliku-tekstowego-2.html](https://re-research.pl/pl/post/2017-01-28-00042-anatomia-pliku-tekstowego-2.html)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Dobre rady\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- żadnych niepotrzebnych spacji na końcu wiersza\n",
|
||||
"\n",
|
||||
"- żadnych niepotrzebnych pustych wierszy na końcu pliku\n",
|
||||
"\n",
|
||||
"- … ale ostatni wiersz powinien zakończyć się znakiem końca wiersza\n",
|
||||
"\n",
|
||||
"- nie używać znaków tabulacji (zamiast tego 4 spacje)\n",
|
||||
" - wyjątek: pliki TSV\n",
|
||||
" - wyjątek: pliki Makefile\n",
|
||||
"\n",
|
||||
"- uwaga na niestandardowe spacje i dziwne znaki o zerowej długości\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Unikod\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"ASCII obejmuje 128 znaków: litery alfabetu łacińskiego (właściwie angielskiego),\n",
|
||||
"cyfry, znaki interpunkcyjne, znaki specjalne itd.\n",
|
||||
"\n",
|
||||
"Co z pozostałymi znakami? Polskimi ogonkami, czeskimi haczykami,\n",
|
||||
"francuskimi akcentami, cyrylicą, koreańskim alfabetem, chińskimi\n",
|
||||
"znakami, rongorongo?\n",
|
||||
"\n",
|
||||
"워싱턴, 부산, 삼성\n",
|
||||
"\n",
|
||||
"Rozwiązaniem jest Unikod (ang. *Unicode*) system, który przypisuje\n",
|
||||
"znakom używanym przez ludzkość liczby (kody, ang. *code points*).\n",
|
||||
"\n",
|
||||
"| Znak|Kod ASCII|Kod Unikodowy|\n",
|
||||
"|---|---|---|\n",
|
||||
"| 9|57|57|\n",
|
||||
"| a|97|97|\n",
|
||||
"| ą|-|261|\n",
|
||||
"| ł|-|322|\n",
|
||||
"| $\\aleph$|-|1488|\n",
|
||||
"| ặ|-|7861|\n",
|
||||
"| ☣|-|9763|\n",
|
||||
"| 😇|-|128519|\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### UTF-8\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Kody znaków są pojęciem abstrakcyjnym. Potrzebujemy konkretnego ****kodowania****\n",
|
||||
"by zamienić kody w sekwencję bajtów. Najpopularniejszym kodowaniem jest UTF-8.\n",
|
||||
"\n",
|
||||
"W kodowaniu UTF-8 znaki zapisywane za pomocą 1, 2, 3, 4, 5 lub 6 bajtów\n",
|
||||
"(w praktyce — raczej to 4 bajtów).\n",
|
||||
"\n",
|
||||
"| Znak|Kod Unikodowy|Szesnastkowo|UTF-8 (binarnie)|\n",
|
||||
"|---|---|---|---|\n",
|
||||
"| 9|57|U+0049|01001001|\n",
|
||||
"| a|97|U+0061|01100001|\n",
|
||||
"| ą|261|U+0105|11000100:10000101|\n",
|
||||
"| ł|322|U+0142|11000101:10000010|\n",
|
||||
"| $\\aleph$|1488|U+05D0|11010111:10010000|\n",
|
||||
"| ặ|7861|U+1EB7|11100001:10111010:10110111|\n",
|
||||
"| ☣|9763|U+2623|11100010:10011000:10100011|\n",
|
||||
"| 😇|128519|U+1f607|11110000:10011111:10011000:10000111|\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### UTF-8 — ogólny schemat zamiany kodu na bajty\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- 0x00 do 0x7F – 0xxxxxxx,\n",
|
||||
"- 0x80 do 0x7FF – 110xxxxx 10xxxxxx\n",
|
||||
"- 0x800 do 0xFFFF — 1110xxxx 10xxxxxx 10xxxxxx\n",
|
||||
"- 0x10000 do 0x1FFFFF – 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n",
|
||||
"- 0x200000 do 0x3FFFFFF – 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n",
|
||||
"- 0x4000000 do 0x7FFFFFFF – 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n",
|
||||
"\n",
|
||||
"Symbol x oznacza znaczący bit.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### *Źdźbło* to ile bajtów w UTF-8?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Jeśli wczytać jako wiersz w języku C, 11 bajtów!\n",
|
||||
"\n",
|
||||
"![img](./01_Jezyk/zdzblo.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Dlaczego UTF-8 jest doskonałym systemem kodowania?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- wstecznie kompatybilny z ASCII\n",
|
||||
" - plik ASCII jest poprawnym plikiem UTF-8\n",
|
||||
"- nie zajmuje dużo miejsca\n",
|
||||
" - chyba że w tekście jest dużo „dziwnych” znaków\n",
|
||||
"- proste grepowanie działa\n",
|
||||
" - `grep UAM text-in-utf8.txt` zadziała\n",
|
||||
" - ale nawet nie próbuj: `grep SRPOL text-in-utf16.txt`\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Porady\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- zawsze używaj UTF-8\n",
|
||||
" - bądź asertywny! jeśli w pracy każą używać czegoś innego — rezygnuj z pracy\n",
|
||||
" - **NIE** używaj innych unikodowych kodowań: UTF-16, UTF-32, UCS-2\n",
|
||||
" - **NIE** używaj nieunikodowych systemów kodowania\n",
|
||||
" - ISO-8859-2, Windows-1250, Mazovia, IEA Świerk, …\n",
|
||||
"- uwaga na pułapki UTF-8\n",
|
||||
" - ustalenie długości napisu w znakach wymaga przejścia znak po znaku\n",
|
||||
" - jeśli napis w kodowaniu UTF-8 zajmuje 9 bajtów, ile to znaków?\n",
|
||||
" 3, 4, 5, 6, 7, 8 lub 9!\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### **NIE** używaj sekwencji BOM\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![img](./01_Jezyk/evil-bom.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Unikod/UTF-8 a języki programowania\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Pamiętaj, żeby być konsekwentnym!\n",
|
||||
"\n",
|
||||
"- kodowanie kodu źródłowego (literały!)\n",
|
||||
" - czasami podawane na początku pliku\n",
|
||||
" - … albo brane z ustawień *locale*\n",
|
||||
" - … albo — domyślnie — UTF-8 (w nowszych językach programowania)\n",
|
||||
"- kodowanie standardowego wejścia/wyjścia i plików\n",
|
||||
"- jak sekwencje bajtów są interpretowane w czasie działania programu?\n",
|
||||
" - *Źdźbło* jest łańcuchem złożonym z 6 czy 9 elementów??\n",
|
||||
" - 9 bajtów\n",
|
||||
" - 6 kodów\n",
|
||||
" - `\"Źdźbło\"[1]` …\n",
|
||||
" - `d`\n",
|
||||
" - … albo śmieci\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Python 2\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#!/usr/bin/python2\n",
|
||||
"# -*- coding: utf-8 -*-\n",
|
||||
"import sys\n",
|
||||
"for line in sys.stdin:\n",
|
||||
" line = line.decode('utf-8').rstrip()\n",
|
||||
" if \"źdźbło\".decode('utf-8') in line:\n",
|
||||
" print len(line), ' ', line"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Python3\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#!/usr/bin/python3\n",
|
||||
"import sys\n",
|
||||
"for line in sys.stdin:\n",
|
||||
" line = line.strip()\n",
|
||||
" if \"źdźbło\" in line:\n",
|
||||
" print(len(line), ' ', line)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Uwaga: zakładając, że zmienna środowiskowa `LANG` jest ustawiona na UTF-8.\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
|
||||
}
|
BIN
wyk/01_Jezyk.org
Normal file
BIN
wyk/01_Jezyk/dante.jpg
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
wyk/01_Jezyk/digitalsignal.jpg
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
wyk/01_Jezyk/evil-bom.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
wyk/01_Jezyk/hexl-mode.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
wyk/01_Jezyk/raster.png
Normal file
After Width: | Height: | Size: 301 B |
BIN
wyk/01_Jezyk/zdzblo.pdf
Normal file
BIN
wyk/01_Jezyk/zdzblo.png
Normal file
After Width: | Height: | Size: 43 KiB |
39
wyk/01_Jezyk/zdzblo.tex
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
\documentclass{article}
|
||||
\usepackage[a6paper]{geometry}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{bytefield}
|
||||
\thispagestyle{empty}
|
||||
\begin{document}
|
||||
|
||||
\begin{bytefield}{8}
|
||||
\bitheader[endianness=big]{0-7} \\
|
||||
\begin{leftwordgroup}{Ź}
|
||||
\bitboxes{1}{11000101} \\
|
||||
\bitboxes{1}{10111001}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{d}
|
||||
\bitboxes{1}{01100100}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{ź}
|
||||
\bitboxes{1}{11000101} \\
|
||||
\bitboxes{1}{10111010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{b}
|
||||
\bitboxes{1}{01100010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{ł}
|
||||
\bitboxes{1}{11000101} \\
|
||||
\bitboxes{1}{10000010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{o}
|
||||
\bitboxes{1}{01101111}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{\textit{koniec wiersza}}
|
||||
\bitboxes{1}{00001010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{\textit{koniec napisu}}
|
||||
\bitboxes{1}{00000000}
|
||||
\end{leftwordgroup}
|
||||
\end{bytefield}
|
||||
\end{document}
|
1780
wyk/02_Jezyki.ipynb
Normal file
801
wyk/02_Jezyki.org
Normal file
@ -0,0 +1,801 @@
|
||||
* Języki i ich prawa
|
||||
|
||||
Jakim rozkładom statystycznym podlegają języki?
|
||||
|
||||
** Język naturalny albo „Pan Tadeusz” w liczbach
|
||||
|
||||
Przygotujmy najpierw „infrastrukturę” do /segmentacji/ tekstu na różnego rodzaju jednostki.
|
||||
Używać będziemy generatorów.
|
||||
|
||||
*Pytanie* Dlaczego generatory zamiast list?
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
import requests
|
||||
|
||||
url = 'https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt'
|
||||
pan_tadeusz = requests.get(url).content.decode('utf-8')
|
||||
|
||||
pan_tadeusz[100:150]
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
Księga pierwsza
|
||||
|
||||
|
||||
|
||||
Gospodarstwo
|
||||
|
||||
Powrót pani
|
||||
:end:
|
||||
|
||||
*** Znaki
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
from itertools import islice
|
||||
|
||||
def get_characters(t):
|
||||
yield from t
|
||||
|
||||
list(islice(get_characters(pan_tadeusz), 100, 150))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
['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']
|
||||
:end:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
from collections import Counter
|
||||
|
||||
c = Counter(get_characters(pan_tadeusz))
|
||||
|
||||
c
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
Counter({' ': 63444, 'a': 30979, 'i': 29353, 'e': 25343, 'o': 23050, 'z': 22741, 'n': 15505, 'r': 15328, 's': 15255, 'w': 14625, 'c': 14153, 'y': 13732, 'k': 12362, 'd': 11465, '\r': 10851, '\n': 10851, 't': 10757, 'm': 10269, 'ł': 10059, ',': 9130, 'p': 8031, 'u': 7699, 'l': 6677, 'j': 6586, 'b': 5753, 'ę': 5534, 'ą': 4794, 'g': 4775, 'h': 3915, 'ż': 3334, 'ó': 3097, 'ś': 2524, '.': 2380, 'ć': 1956, ';': 1445, 'P': 1265, 'W': 1258, ':': 1152, '!': 1083, 'S': 1045, 'T': 971, 'I': 795, 'N': 793, 'Z': 785, 'J': 729, '—': 720, 'A': 698, 'K': 683, 'ń': 651, 'M': 585, 'B': 567, 'O': 567, 'C': 556, 'D': 552, '«': 540, '»': 538, 'R': 489, '?': 441, 'ź': 414, 'f': 386, 'G': 358, 'L': 316, 'H': 309, 'Ż': 219, 'U': 184, '…': 157, '*': 150, '(': 76, ')': 76, 'Ś': 71, 'F': 47, 'é': 43, '-': 33, 'Ł': 24, 'E': 23, '/': 19, 'Ó': 13, '8': 10, '9': 8, '2': 6, 'v': 5, 'Ź': 4, '1': 4, '3': 3, 'x': 3, 'V': 3, '7': 2, '4': 2, '5': 2, 'q': 2, 'æ': 2, 'à': 1, 'Ć': 1, '6': 1, '0': 1})
|
||||
:end:
|
||||
|
||||
Napiszmy pomocniczą funkcję, która zwraca *listę frekwencyjną*.
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
Counter({' ': 63444, 'a': 30979, 'i': 29353, 'e': 25343, 'o': 23050, 'z': 22741, 'n': 15505, 'r': 15328, 's': 15255, 'w': 14625, 'c': 14153, 'y': 13732, 'k': 12362, 'd': 11465, '\r': 10851, '\n': 10851, 't': 10757, 'm': 10269, 'ł': 10059, ',': 9130, 'p': 8031, 'u': 7699, 'l': 6677, 'j': 6586, 'b': 5753, 'ę': 5534, 'ą': 4794, 'g': 4775, 'h': 3915, 'ż': 3334, 'ó': 3097, 'ś': 2524, '.': 2380, 'ć': 1956, ';': 1445, 'P': 1265, 'W': 1258, ':': 1152, '!': 1083, 'S': 1045, 'T': 971, 'I': 795, 'N': 793, 'Z': 785, 'J': 729, '—': 720, 'A': 698, 'K': 683, 'ń': 651, 'M': 585, 'B': 567, 'O': 567, 'C': 556, 'D': 552, '«': 540, '»': 538, 'R': 489, '?': 441, 'ź': 414, 'f': 386, 'G': 358, 'L': 316, 'H': 309, 'Ż': 219, 'U': 184, '…': 157, '*': 150, '(': 76, ')': 76, 'Ś': 71, 'F': 47, 'é': 43, '-': 33, 'Ł': 24, 'E': 23, '/': 19, 'Ó': 13, '8': 10, '9': 8, '2': 6, 'v': 5, 'Ź': 4, '1': 4, '3': 3, 'x': 3, 'V': 3, '7': 2, '4': 2, '5': 2, 'q': 2, 'æ': 2, 'à': 1, 'Ć': 1, '6': 1, '0': 1})
|
||||
:end:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
from collections import Counter
|
||||
from collections import OrderedDict
|
||||
|
||||
def freq_list(g, top=None):
|
||||
c = Counter(g)
|
||||
|
||||
if top is None:
|
||||
items = c.items()
|
||||
else:
|
||||
items = c.most_common(top)
|
||||
|
||||
return OrderedDict(sorted(items, key=lambda t: -t[1]))
|
||||
|
||||
freq_list(get_characters(pan_tadeusz), top=8)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
OrderedDict([(' ', 63444), ('a', 30979), ('i', 29353), ('e', 25343), ('o', 23050), ('z', 22741), ('n', 15505), ('r', 15328)])
|
||||
:end:
|
||||
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from collections import OrderedDict
|
||||
|
||||
def rang_freq_with_labels(name, g, top=None):
|
||||
freq = freq_list(g, top)
|
||||
|
||||
plt.figure(figsize=(12, 3))
|
||||
plt.ylabel('liczba wystąpień')
|
||||
|
||||
plt.bar(freq.keys(), freq.values())
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
rang_freq_with_labels('pt-chars', get_characters(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-chars.png]]
|
||||
|
||||
*** Słowa
|
||||
|
||||
Co rozumiemy pod pojęciem słowa czy wyrazu, nie jest oczywiste. W praktyce zależy to od wyboru *tokenizatora*.
|
||||
|
||||
Załóżmy, że przez wyraz rozumieć będziemy nieprzerwany ciąg liter bądź cyfr (oraz gwiazdek
|
||||
— to za chwilę ułatwi nam analizę pewnego tekstu…).
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
from itertools import islice
|
||||
import regex as re
|
||||
|
||||
def get_words(t):
|
||||
for m in re.finditer(r'[\p{L}0-9\*]+', t):
|
||||
yield m.group(0)
|
||||
|
||||
list(islice(get_words(pan_tadeusz), 100, 130))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
['Ty', 'co', 'gród', 'zamkowy', 'Nowogródzki', 'ochraniasz', 'z', 'jego', 'wiernym', 'ludem', 'Jak', 'mnie', 'dziecko', 'do', 'zdrowia', 'powróciłaś', 'cudem', 'Gdy', 'od', 'płaczącej', 'matki', 'pod', 'Twoją', 'opiekę', 'Ofiarowany', 'martwą', 'podniosłem', 'powiekę', 'I', 'zaraz']
|
||||
:end:
|
||||
|
||||
Zobaczmy 20 najczęstszych wyrazów.
|
||||
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
rang_freq_with_labels('pt-words-20', get_words(pan_tadeusz), top=20)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words-20.png]]
|
||||
|
||||
Zobaczmy pełny obraz, już bez etykiet.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
|
||||
def rang_freq(name, g):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.plot(range(1, len(freq.values())+1), freq.values())
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
rang_freq('pt-words', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words.png]]
|
||||
|
||||
Widać, jak różne skale obejmuje ten wykres. Zastosujemy logartm,
|
||||
najpierw tylko do współrzędnej y.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
|
||||
def rang_log_freq(name, g):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.plot(range(1, len(freq.values())+1), [log(y) for y in freq.values()])
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
rang_log_freq('pt-words-log', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words-log.png]]
|
||||
|
||||
**Pytanie** Dlaczego widzimy coraz dłuższe „schodki”?
|
||||
|
||||
*** Hapax legomena
|
||||
|
||||
Z poprzedniego wykresu możemy odczytać, że ok. 2/3 wyrazów wystąpiło
|
||||
dokładnie 1 raz. Słowa występujące jeden raz w danym korpusie noszą
|
||||
nazwę /hapax legomena/ (w liczbie pojedynczej /hapax legomenon/, ἅπαξ
|
||||
λεγόμενον, „raz powiedziane”, żargonowo: „hapaks”).
|
||||
|
||||
„Prawdziwe” hapax legomena, słowa, które wystąpiły tylko raz w /całym/
|
||||
korpusie tekstów danego języka (np. starożytnego) rzecz jasna
|
||||
sprawiają olbrzymie trudności w tłumaczeniu. Przykładem jest greckie
|
||||
słowo ἐπιούσιος, przydawka odnosząca się do chleba w modlitwie „Ojcze
|
||||
nasz”. Jest to jedyne poświadczenie tego słowa w całym znanym korpusie
|
||||
greki (nie tylko z Pisma Świętego). W języku polskim tłumaczymy je na
|
||||
„powszedni”, ale na przykład w rosyjskim przyjął się odpowiednik
|
||||
„насущный” — o przeciwstawnym do polskiego znaczeniu!
|
||||
|
||||
W sumie podobne problemy hapaksy mogą sprawiać metodom statystycznym
|
||||
przy przetwarzaniu jakiekolwiek korpusu.
|
||||
|
||||
*** Wykres log-log
|
||||
|
||||
Jeśli wspomniany wcześniej wykres narysujemy używając skali
|
||||
logarytmicznej dla **obu** osi, otrzymamy kształt zbliżony do linii prostej.
|
||||
|
||||
Tę własność tekstów nazywamy **prawem Zipfa**.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
|
||||
def log_rang_log_freq(name, g):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.plot([log(x) for x in range(1, len(freq.values())+1)], [log(y) for y in freq.values()])
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
log_rang_log_freq('pt-words-log-log', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words-log-log.png]]
|
||||
|
||||
*** Związek między frekwencją a długością
|
||||
|
||||
Powiązane z prawem Zipfa prawo językowe opisuje zależność między
|
||||
częstością użycia słowa a jego długością. Generalnie im krótsze słowo, tym częstsze.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
def freq_vs_length(name, g, top=None):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.scatter([len(x) for x in freq.keys()], [log(y) for y in freq.values()],
|
||||
facecolors='none', edgecolors='r')
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
freq_vs_length('pt-lengths', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-lengths.png]]
|
||||
|
||||
** N-gramy
|
||||
|
||||
W modelowaniu języka często rozpatruje się n-gramy, czyli podciągi o
|
||||
rozmiarze $n$.
|
||||
|
||||
Na przykład /digramy/ (/bigramy/) to zbitki dwóch jednostek, np. liter albo wyrazów.
|
||||
|
||||
|$n$| $n$-gram| nazwa |
|
||||
|---+---------+---------------|
|
||||
| 1 | 1-gram | unigram |
|
||||
| 2 | 2-gram | digram/bigram |
|
||||
| 3 | 3-gram | trigram |
|
||||
| 4 | 4-gram | tetragram |
|
||||
| 5 | 5-gram | pentagram |
|
||||
|
||||
|
||||
*Pytanie:* Jak nazywa się 6-gram?
|
||||
|
||||
Jak widać, dla symetrii mówimy czasami o unigramach, jeśli operujemy
|
||||
po prostu na jednostkach, nie na ich podciągach.
|
||||
|
||||
*** N-gramy z Pana Tadeusza
|
||||
|
||||
Statystyki, które policzyliśmy dla pojedynczych liter czy wyrazów możemy powtórzyć dla n-gramów.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
def ngrams(iter, size):
|
||||
ngram = []
|
||||
for item in iter:
|
||||
ngram.append(item)
|
||||
if len(ngram) == size:
|
||||
yield tuple(ngram)
|
||||
ngram = ngram[1:]
|
||||
|
||||
list(ngrams("kotek", 3))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
[('k', 'o', 't'), ('o', 't', 'e'), ('t', 'e', 'k')]
|
||||
:end:
|
||||
|
||||
Zauważmy, że policzyliśmy wszystkie n-gramy, również częściowo pokrywające się.
|
||||
|
||||
Zawsze powinniśmy się upewnić, czy jest jasne, czy chodzi o n-gramy znakowe czy wyrazowe
|
||||
|
||||
*** 3-gramy znakowe
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
log_rang_log_freq('pt-3-char-ngrams-log-log', ngrams(get_characters(pan_tadeusz), 3))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-3-char-ngrams-log-log.png]]
|
||||
|
||||
*** 2-gramy wyrazowe
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
log_rang_log_freq('pt-2-word-ngrams-log-log', ngrams(get_words(pan_tadeusz), 3))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-2-word-ngrams-log-log.png]]
|
||||
|
||||
** Tajemniczy język Manuskryptu Wojnicza
|
||||
|
||||
[[https://pl.wikipedia.org/wiki/Manuskrypt_Wojnicza][Manuskrypt Wojnicza]] to powstały w XV w. manuskrypt spisany w
|
||||
tajemniczym alfabecie, do dzisiaj nieodszyfrowanym. Rękopis stanowi
|
||||
jedną z największych zagadek historii (i lingwistyki).
|
||||
|
||||
[[./02_Jezyki/voynich135.jpg][Źródło: https://commons.wikimedia.org/wiki/File:Voynich_Manuscript_(135).jpg]]
|
||||
|
||||
Sami zbadajmy statystyczne własności tekstu manuskryptu. Użyjmy
|
||||
transkrypcji Vnow, gdzie poszczególne znaki tajemniczego alfabetu
|
||||
zamienione na litery alfabetu łacińskiego, cyfry i gwiazdkę. Jak
|
||||
transkrybować manuskrypt, pozostaje sprawą dyskusyjną, natomiast wybór
|
||||
takiego czy innego systemu transkrypcji nie powinien wpływać
|
||||
dramatycznie na analizę statystyczną.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
import requests
|
||||
|
||||
voynich_url = 'http://www.voynich.net/reeds/gillogly/voynich.now'
|
||||
voynich = requests.get(voynich_url).content.decode('utf-8')
|
||||
|
||||
voynich = re.sub(r'\{[^\}]+\}|^<[^>]+>|[-# ]+', '', voynich, flags=re.MULTILINE)
|
||||
|
||||
voynich = voynich.replace('\n\n', '#')
|
||||
voynich = voynich.replace('\n', ' ')
|
||||
voynich = voynich.replace('#', '\n')
|
||||
|
||||
voynich = voynich.replace('.', ' ')
|
||||
|
||||
voynich[100:150]
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
9 OR 9FAM ZO8 QOAR9 Q*R 8ARAM 29 [O82*]OM OPCC9 OP
|
||||
:end:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
rang_freq_with_labels('voy-chars', get_characters(voynich))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/voy-chars.png]]
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
log_rang_log_freq('voy-log-log', get_words(voynich))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/voy-log-log.png]]
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
rang_freq_with_labels('voy-words-20', get_words(voynich), top=20)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/voy-words-20.png]]
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
log_rang_log_freq('voy-words-log-log', get_words(voynich))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/voy-words-log-log.png]]
|
||||
|
||||
** Język DNA
|
||||
|
||||
Kod genetyczny przejawia własności zaskakująco podobne do języków naturalnych.
|
||||
Przede wszystkim ma charakter dyskretny, genotyp to ciąg symboli ze skończonego alfabetu.
|
||||
Podstawowe litery są tylko cztery, reprezentują one nukleotydy, z których zbudowana jest nić DNA:
|
||||
a, g, c, t.
|
||||
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
import requests
|
||||
|
||||
dna_url = 'https://raw.githubusercontent.com/egreen18/NanO_GEM/master/rawGenome.txt'
|
||||
dna = requests.get(dna_url).content.decode('utf-8')
|
||||
|
||||
dna = ''.join(dna.split('\n')[1:])
|
||||
dna = dna.replace('N', 'A')
|
||||
|
||||
dna[0:100]
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
TATAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTA
|
||||
:end:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
rang_freq_with_labels('dna-chars', get_characters(dna))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/dna-chars.png]]
|
||||
|
||||
*** Tryplety — znaczące cząstki genotypu
|
||||
|
||||
Nukleotydy rzeczywiście są jak litery, same w sobie nie niosą
|
||||
znaczenia. Dopiero ciągi trzech nukleotydów, /tryplety/, kodują jeden
|
||||
z dwudziestu aminokwasów.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
genetic_code = {
|
||||
'ATA':'I', 'ATC':'I', 'ATT':'I', 'ATG':'M',
|
||||
'ACA':'T', 'ACC':'T', 'ACG':'T', 'ACT':'T',
|
||||
'AAC':'N', 'AAT':'N', 'AAA':'K', 'AAG':'K',
|
||||
'AGC':'S', 'AGT':'S', 'AGA':'R', 'AGG':'R',
|
||||
'CTA':'L', 'CTC':'L', 'CTG':'L', 'CTT':'L',
|
||||
'CCA':'P', 'CCC':'P', 'CCG':'P', 'CCT':'P',
|
||||
'CAC':'H', 'CAT':'H', 'CAA':'Q', 'CAG':'Q',
|
||||
'CGA':'R', 'CGC':'R', 'CGG':'R', 'CGT':'R',
|
||||
'GTA':'V', 'GTC':'V', 'GTG':'V', 'GTT':'V',
|
||||
'GCA':'A', 'GCC':'A', 'GCG':'A', 'GCT':'A',
|
||||
'GAC':'D', 'GAT':'D', 'GAA':'E', 'GAG':'E',
|
||||
'GGA':'G', 'GGC':'G', 'GGG':'G', 'GGT':'G',
|
||||
'TCA':'S', 'TCC':'S', 'TCG':'S', 'TCT':'S',
|
||||
'TTC':'F', 'TTT':'F', 'TTA':'L', 'TTG':'L',
|
||||
'TAC':'Y', 'TAT':'Y', 'TAA':'_', 'TAG':'_',
|
||||
'TGC':'C', 'TGT':'C', 'TGA':'_', 'TGG':'W',
|
||||
}
|
||||
|
||||
def get_triplets(t):
|
||||
for triplet in re.finditer(r'.{3}', t):
|
||||
yield genetic_code[triplet.group(0)]
|
||||
|
||||
rang_freq_with_labels('dna-aminos', get_triplets(dna))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/dna-aminos.png]]
|
||||
|
||||
*** „Zdania” w języku DNA
|
||||
|
||||
Z aminokwasów zakodowanych przez tryplet budowane są białka.
|
||||
Maszyneria budująca białka czyta sekwencję aż do napotkania
|
||||
trypletu STOP (_ powyżej). Taka sekwencja to /gen/.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
def get_genes(triplets):
|
||||
gene = []
|
||||
for ammino in triplets:
|
||||
if ammino == '_':
|
||||
yield gene
|
||||
gene = []
|
||||
else:
|
||||
gene.append(ammino)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.hist([len(g) for g in get_genes(get_triplets(dna))], bins=100)
|
||||
|
||||
fname = '02_Jezyki/dna_length.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
fname
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/dna_length.png]]
|
||||
|
||||
** Entropia
|
||||
|
||||
*Entropia* ($E$) to miara nieuporządkowania, niepewności, niewiedzy. Im
|
||||
większa entropia, tym mniej wiemy. Pojęcie to pierwotnie wywodzi się z
|
||||
termodynamiki, później znaleziono wiele zaskakujących analogii i zastosowań w
|
||||
innych dyscyplinach nauki.
|
||||
|
||||
*** Entropia w fizyce
|
||||
|
||||
W termodynamice entropia jest miarą nieuporządkowania układów
|
||||
fizycznych, na przykład pojemników z gazem. Przykładowo, wyobraźmy
|
||||
sobie dwa pojemniki z gazem, w którym panuje różne temperatury.
|
||||
|
||||
[[./02_Jezyki/gas-low-entropy.drawio.png]]
|
||||
|
||||
Jeśli usuniemy przegrodę między pojemnikami, temperatura się wyrówna,
|
||||
a uporządkowanie się zmniejszy.
|
||||
|
||||
[[./02_Jezyki/gas-high-entropy.drawio.png]]
|
||||
|
||||
Innymi słowy, zwiększy się stopień nieuporządkowania układu, czyli właśnie entropia.
|
||||
|
||||
*** II prawo termodynamiki
|
||||
|
||||
Jedno z najbardziej fundamentalnych praw fizyki, II prawo
|
||||
termodynamiki głosi, że w układzie zamkniętym entropia nie spada.
|
||||
|
||||
**Pytanie**: Czy to, że napisałem te materiały do wykładu i
|
||||
/uporządkowałem/ wiedzę odnośnie do statystycznych własności języka, nie
|
||||
jest sprzeczne z II prawem termodynamiki?
|
||||
|
||||
Konsekwencją II prawa termodynamiki jest śmierć cieplna Wszechświata
|
||||
(zob. [wizualizacja przyszłości Wszechświata](https://www.youtube.com/watch?v=uD4izuDMUQA)).
|
||||
|
||||
*** Entropia w teorii informacji
|
||||
|
||||
Pojęcie entropii zostało „odkryte” na nowo przez Claude'a Shannona,
|
||||
gdy wypracował ogólną teorię informacji.
|
||||
|
||||
Teoria informacji zajmuje się między innymi zagadnieniem optymalnego kodowania komunikatów.
|
||||
|
||||
Wyobraźmy sobie pewne źródło (generator) losowych komunikatów z
|
||||
zamkniętego zbioru symboli ($\Sigma$; nieprzypadkowo używamy oznaczeń
|
||||
z poprzedniego wykładu). Nadawca $N$ chce przesłać komunikat o wyniku
|
||||
losowania do odbiorcy $O$ używając zer i jedynek (bitów).
|
||||
Teorioinformacyjną entropię można zdefiniować jako średnią liczbę
|
||||
bitów wymaganych do przesłania komunikatu.
|
||||
|
||||
[[./02_Jezyki/communication.drawio.png]]
|
||||
|
||||
*** Obliczanie entropii — proste przykłady
|
||||
|
||||
Załóżmy, że nadawca chce przekazać odbiorcy informację o wyniku rzutu monetą.
|
||||
Entropia wynosi wówczas rzecz jasna 1 — na jedno losowanie wystarczy jeden bit
|
||||
(informację o tym, że wypadł orzeł, możemy zakodować na przykład za pomocą zera,
|
||||
zaś to, że wypadła reszka — za pomocą jedynki).
|
||||
|
||||
Rozpatrzmy przypadek, gdy nadawca rzuca ośmiościenną kością. Aby przekazać
|
||||
wynik, potrzebuje wówczas 3 bity (a więc entropia ośmiościennej kości
|
||||
wynosi 3 bity). Przykładowe kodowanie może mieć następującą postać:
|
||||
|
||||
| Wynik | Kodowanie |
|
||||
|-------+-----------|
|
||||
| 1 | 001 |
|
||||
| 2 | 010 |
|
||||
| 3 | 011 |
|
||||
| 4 | 100 |
|
||||
| 5 | 101 |
|
||||
| 6 | 110 |
|
||||
| 7 | 111 |
|
||||
| 8 | 000 |
|
||||
|
||||
*** Obliczenie entropii — trudniejszy przykład
|
||||
|
||||
Załóżmy, że $\Sigma = \{A, B, C, D\}$, natomiast poszczególne komunikaty
|
||||
są losowane zgodnie z następującym rozkładem prawdopodobieństwa:
|
||||
$P(A)=1/2$, $P(B)=1/4$, $P(C)=1/8$, $P(D)=1/8$. Ile wynosi entropia w
|
||||
takim przypadku? Można by sądzić, że 2, skoro wystarczą 2 bity do
|
||||
przekazania wyniku losowania przy zastosowaniu następującego kodowania:
|
||||
|
||||
| Wynik | Kodowanie |
|
||||
|-------+-----------|
|
||||
| A | 00 |
|
||||
| B | 01 |
|
||||
| C | 10 |
|
||||
| D | 11 |
|
||||
|
||||
Problem w tym, że w rzeczywistości nie jest to /optymalne/ kodowanie.
|
||||
Możemy sprytnie zmniejszyć średnią liczbę bitów wymaganych do
|
||||
przekazania losowego wyniku przypisując częstszym wynikom krótsze
|
||||
kody, rzadszym zaś — dłuższe. Oto takie optymalne kodowanie:
|
||||
|
||||
| Wynik | Kodowanie |
|
||||
|-------+-----------|
|
||||
| A | 0 |
|
||||
| B | 10 |
|
||||
| C | 110 |
|
||||
| D | 111 |
|
||||
|
||||
|
||||
Używając takiego kodowanie średnio potrzebujemy:
|
||||
|
||||
$$\frac{1}{2}1 + \frac{1}{4}2 + \frac{1}{8}3 + \frac{1}{8}3 = 1,75$$
|
||||
|
||||
bita. Innymi słowy, entropia takiego źródła wynosi 1,75 bita.
|
||||
|
||||
*** Kodowanie musi być jednoznaczne!
|
||||
|
||||
Można by sądzić, że da się stworzyć jeszcze krótsze kodowanie dla omawianego rozkładu nierównomiernego:
|
||||
|
||||
| Wynik | Kodowanie |
|
||||
|-------+-----------|
|
||||
| A | 0 |
|
||||
| B | 1 |
|
||||
| C | 01 |
|
||||
| D | 11 |
|
||||
|
||||
Niestety, nie jest to właściwe rozwiązanie — kodowanie musi być
|
||||
jednoznaczne nie tylko dla pojedynczego komunikatu, lecz dla całej sekwencji.
|
||||
Na przykład ciąg 0111 nie jest jednoznaczny przy tym kodowaniu (ABBB czy CD?).
|
||||
Podane wcześniej kodowanie spełnia warunek jednoznaczności, ciąg 0111 można odkodować tylko
|
||||
jako AD.
|
||||
|
||||
|
||||
*** Ogólny wzór na entropię.
|
||||
|
||||
Na podstawie poprzedniego przykładu można dojść do intuicyjnego wniosku, że
|
||||
optymalny kod dla wyniku o prawdopodobieństwie $p$ ma długość $-\log_2(p)$, a zatem ogólnie
|
||||
entropia źródła o rozkładzie prawdopodobieństwa $\{p_1,\ldots,p_|\Sigma|\}$ wynosi:
|
||||
|
||||
$$E = -\sum_{i=1}^{|\Sigma|} p_i\log_2(p_i)$$.
|
||||
|
||||
Zauważmy, że jest to jeden z nielicznych przypadków, gdy w nauce naturalną
|
||||
podstawą logarytmu jest 2 zamiast… podstawy logarytmu naturalnego ($e$).
|
||||
|
||||
Teoretycznie można mierzyć entropię używając logarytmu naturalnego
|
||||
($\ln$), jednostką entropii będzie wówczas *nat* zamiast bita,
|
||||
niewiele to jednak zmienia i jest mniej poręczne i trudniejsze do interpretacji
|
||||
(przynajmniej w kontekście informatyki) niż operowanie na bitach.
|
||||
|
||||
**Pytanie** Ile wynosi entropia zwykłej sześciennej kostki? Jak wygląda
|
||||
optymalne kodowanie wyników rzutu taką kostką?
|
||||
|
||||
*** Entropia dla próby Bernoulliego
|
||||
|
||||
Wiemy już, że entropia dla rzutu monetą wynosi 1 bit. A jaki będzie wynik dla źle wyważonej monety?
|
||||
|
||||
#+BEGIN_SRC python :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
import numpy as np
|
||||
|
||||
def binomial_entropy(p):
|
||||
return -(p * log(p, 2) + (1-p) * log(1-p, 2))
|
||||
|
||||
x = list(np.arange(0.001,1,0.001))
|
||||
y = [binomial_entropy(x) for x in x]
|
||||
plt.figure().clear()
|
||||
plt.xlabel('prawdopodobieństwo wylosowania orła')
|
||||
plt.ylabel('entropia')
|
||||
plt.plot(x, y)
|
||||
|
||||
fname = f'02_Jezyki/binomial-entropy.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
fname
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/binomial-entropy.png]]
|
||||
|
||||
*Pytanie* Dla oszukańczej monety (np. dla której wypada zawsze orzeł) entropia
|
||||
wynosi 0, czy to wynik zgodny z intuicją?
|
||||
|
||||
** Entropia a język
|
||||
|
||||
Tekst w danym języku możemy traktować jako ciąg symboli (komunikatów) losowanych według jakiegoś
|
||||
rozkładu prawdopodobieństwa. W tym sensie możemy mówić o entropii języka.
|
||||
|
||||
Oczywiście, jak zawsze, musimy jasno stwierdzić, czym są symbole
|
||||
języka: literami, wyrazami czy jeszcze jakimiś innymi jednostkami.
|
||||
|
||||
*** Pomiar entropii języka — pierwsze przybliżenie
|
||||
|
||||
Załóżmy, że chcemy zmierzyć entropię języka polskiego na przykładzie
|
||||
„Pana Tadeusza” — na poziomie znaków. W pierwszym przybliżeniu można
|
||||
by policzyć liczbę wszystkich znaków…
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
chars_in_pan_tadeusz = len(set(get_characters(pan_tadeusz)))
|
||||
chars_in_pan_tadeusz
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
95
|
||||
:end:
|
||||
|
||||
… założyć jednostajny rozkład prawdopodobieństwa i w ten sposób policzyć entropię:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
from math import log
|
||||
|
||||
95 * (1/95) * log(95, 2)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
6.569855608330948
|
||||
:end:
|
||||
|
||||
*** Mniej rozrzutne kodowanie
|
||||
|
||||
Przypomnijmy sobie jednak, że rozkład jednostek języka jest zawsze
|
||||
skrajnie nierównomierny! Jeśli uwzględnić ten nierównomierny rozkład
|
||||
znaków, można opracować o wiele efektywniejszy sposób zakodowania znaków składających się na „Pana Tadeusza”
|
||||
(częste litery, np. „a” i „e” powinny mieć krótkie kody, a rzadkie, np. „ź” — dłuższe).
|
||||
|
||||
Policzmy entropię przy takim założeniu:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
from collections import Counter
|
||||
from math import log
|
||||
|
||||
def unigram_entropy(t):
|
||||
counter = Counter(t)
|
||||
|
||||
total = counter.total()
|
||||
return -sum((p := count / total) * log(p, 2) for count in counter.values())
|
||||
|
||||
unigram_entropy(get_characters(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
4.938605272823633
|
||||
:end:
|
||||
|
||||
(Jak dowiemy się na kolejnym wykładzie, zastosowaliśmy tutaj *unigramowy model języka*).
|
||||
|
||||
*** Ile wynosi entropia rękopisu Wojnicza?
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
unigram_entropy(get_characters(voynich))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
3.902708104423842
|
||||
:end:
|
||||
|
||||
*** Rzeczywista entropia?
|
||||
|
||||
W rzeczywistości entropia jest jeszcze mniejsza, tekst nie jest
|
||||
generowany przecież według rozkładu wielomianowego. Istnieją rzecz
|
||||
jasna pewne zależności między znakami, np. niemożliwe, żeby po „ń”
|
||||
wystąpiły litera „a” czy „e”. Na poziomie wyrazów zależności mogę mieć
|
||||
jeszcze bardziej skrajny charakter, np. po wyrazie „przede” prawie na
|
||||
pewno wystąpi „wszystkim”, co oznacza, że w takiej sytuacji słowo
|
||||
„wszystkim” może zostać zakodowane za pomocą 0 (!) bitów.
|
||||
|
||||
Można uwzględnić takie zależności i uzyskać jeszcze lepsze kodowanie,
|
||||
a co za tym idzie lepsze oszacowanie entropii. (Jak wkrótce się
|
||||
dowiemy, oznacza to użycie digramowego, trigramowego, etc. modelu języka).
|
||||
|
||||
*** Rozmiar skompresowanego pliku jako przybliżenie entropii
|
||||
|
||||
Celem algorytmów kompresji jest właściwie wyznaczanie efektywnych
|
||||
sposobów kodowania danych. Możemy więc użyć rozmiaru skompresowanego pliku w bitach
|
||||
(po podzieleniu przez oryginalną długość) jako dobrego przybliżenia entropii.
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
import zlib
|
||||
|
||||
def entropy_by_compression(t):
|
||||
compressed = zlib.compress(t.encode('utf-8'))
|
||||
return 8 * len(compressed) / len(t)
|
||||
|
||||
entropy_by_compression(pan_tadeusz)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
3.673019884633768
|
||||
:end:
|
||||
|
||||
Dla porównania wynik dla rękopisu Wojnicza:
|
||||
|
||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
||||
entropy_by_compression(voynich)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
2.942372881355932
|
||||
:end:
|
||||
|
||||
*** Gra Shannona
|
||||
|
||||
Innym sposobem oszacowania entropii tekstu jest użycie… ludzi. Można poprosić rodzimych użytkowników
|
||||
danego języka o przewidywanie kolejnych liter (bądź wyrazów) i w ten sposób oszacować entropię.
|
||||
|
||||
*Projekt* Zaimplementuj aplikację webową, która umożliwi „rozegranie” gry Shannona.
|
BIN
wyk/02_Jezyki/binomial-entropy.png
Normal file
After Width: | Height: | Size: 26 KiB |
1
wyk/02_Jezyki/communication.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-03-05T13:05:15.969Z" agent="5.0 (X11)" etag="T1jv8GjlxjBRy82UXK3g" version="16.2.2" type="device"><diagram id="E-zPRpFz5prVeiZgI5WF" name="Page-1">1VbbcpswEP0aHpMxEGznMbFzmTZtPc1Dk0cZrUGJ0LpC2JCvrwTC3OzcO9P6waM9klbsObtaOf4sya8kWcffkAJ3vBHNHX/ueN7piav/DVBUQOAFFRBJRivIbYBb9gQWHFk0YxTSzkKFyBVbd8EQhYBQdTAiJW67y1bIu6euSQQD4DYkfIj+YlTFFTr1Jg1+DSyK65Pd8Wk1k5B6sY0kjQnFbQvyLxx/JhFVNUryGXDDXc1Lte/ywOzuwyQI9ZoNX6X3O78fXS/phv3kIss2X7wj62VDeGYD/k4o2YbEfrMqaiL056/NMEv4WahQOv75BqRimqobsgS+wJQphkIvWaJSmLQWnHEWmQmFa43GKuHacPUQM8WZgNlOvJEG7SfpvZAfjNXdMagzDzABJQu9xG7wTizpRc/eNhr6Fopb8o0tRmzWRDvPDbF6YLl9A88nA55/0CVD+b8THfj/GNHBgOiDBK845GfmitBUgKB2OA85SVMWdvmTmAkKtEMc0MHV8SJtLVqCPbTUmAROFNt03e/jyp6wQKYPbtJ/2lNl0qM7xUyGYHe174yeo8B7wZEiMgI1cFRKtwv7/WqOB2o+EkGcWeBMDf6ISSbYIwkf2EBlo05ZL10hia2QUCsFck/pJIxS4+NcQsqeyLL0Z0RfmyDLsINzJ5g/Vz+2GdnNTQtoJ8jh7D1YbEejY7dun+/NkHoJrlYp/BXNpnuluLUmShVjhILwiwbtlVez5gbNRVYK9wBKFfZ9QDKFXVkhZ+rObD8OrHXfmpnn1nNpFLUhdKB3beO+9OD3fvVs46W0Om4WIJkmzmTUm24IzVNZis/waV8aVaW91MqHufPqRPnQtTsZFOoVCJDE9C8dY5EskQ9r9ON9rb7LdTov9FPM9reyaXZzKq0yp8qPT2h8bu+F4U6GjW/8OY1Pm80rsarS5qntX/wB</diagram></mxfile>
|
BIN
wyk/02_Jezyki/communication.drawio.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
wyk/02_Jezyki/dna-aminos.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
wyk/02_Jezyki/dna-chars.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
wyk/02_Jezyki/dna_length.png
Normal file
After Width: | Height: | Size: 13 KiB |
1
wyk/02_Jezyki/gas-high-entropy.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-03-05T10:14:12.443Z" agent="5.0 (X11)" etag="UjtYN9dZJ1n-mtJw7vZr" version="16.2.2" type="device"><diagram id="zkchOmJWayHcCaytrl_I" name="Page-1">jZPfb4MgEMf/Gh+bKFS3vs513bLsqUv2TIQKLXiO0mr31w/l/JVmydAofO444HtHRHPT7iyr5QdwoSMS8zaizxEhm3Xivx24BZCSNIDSKh5QMoG9+hEIY6QXxcV54egAtFP1EhZQVaJwC8ashWbpdgC9XLVmpbgD+4Lpe/qluJOBPpKHib8KVcph5STbBIthgzOGOEvGoQmoPxzdRjS3AC70TJsL3Wk36BIUePnDOm7Misr9Z8LpuNrG5ppe31ylDf1+P+6yFR7jyvQFDxyRtX8/ww937m6DHBYuFRddxDiiT41UTuxrVnTWxuffM+mM9qPEd8/OwmmUjXpyUFrnoMH20egh7Z6OQ+VmPLQxwsyS9c1bcN/COtH+KUgyyuzLU4ARzt68C04gFGsMS5OmOG6mRJM1MjlLcoaMYW2VY+hJft/BDAzDKdO9bXZd6PYX</diagram></mxfile>
|
BIN
wyk/02_Jezyki/gas-high-entropy.drawio.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
1
wyk/02_Jezyki/gas-low-entropy.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-03-05T10:11:11.528Z" agent="5.0 (X11)" etag="-eu0Wo5sdhkbwVuXUHS7" version="16.2.2" type="device"><diagram id="zkchOmJWayHcCaytrl_I" name="Page-1">5ZVRT8IwEMc/zR5NtpUVeBRENMYnTHw0db1t1W7FUhj46b3RbmMwEk3UmJgQcv3f7a79/QvzyDTfzjVbZveKg/RCn289cuWF4XgQ4Hcl7KwQhZEVUi24lYJWWIh3cKLv1LXgsOoUGqWkEcuuGKuigNh0NKa1KrtliZLdqUuWwomwiJk8VR8FN5lVR+Gw1W9ApFk9OaBjm8lZXexarDLGVWml/eHIzCNTrZSxUb6dgqzY1Vwsgesz2WZjGgrzmQdeXy5mfr6JNremkDl5u3uZ04vQdtkwuXYHdps1u5qAVuuCQ9XE98ikzISBxZLFVbZEy1HLTC5xFWC4Mlq9NqQIKomQcqqk0vtuJEmAxnFTeZDhw/GzX41wWwJtYHv2rEFDEG8eqByM3mGJeyAk7vrsjtZl62HgePnZgX/Uacxdm7Rp3ZLFwMH9Amjy26A5g1HSC5rGI3hOvgc0if4a6KgHNJU4dcLFBsPU7E8+wM/DU2CDugIHdoqODEJMps+Fmm2hCjgywklMirTAZYxYAfVJBV3gv8ylS+SC82pMr+3di/EdPw965NogOnGN9phGfso0+hXTwv9pGhn9mmm4bN9L+9zBy53MPgA=</diagram></mxfile>
|
BIN
wyk/02_Jezyki/gas-low-entropy.drawio.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
wyk/02_Jezyki/pt-2-word-ngrams-log-log.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
wyk/02_Jezyki/pt-3-char-ngrams-log-log.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
wyk/02_Jezyki/pt-chars.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
wyk/02_Jezyki/pt-lengths.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
wyk/02_Jezyki/pt-words-20.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
wyk/02_Jezyki/pt-words-log-log.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
wyk/02_Jezyki/pt-words-log.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
wyk/02_Jezyki/pt-words.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
wyk/02_Jezyki/voy-chars.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
wyk/02_Jezyki/voy-log-log.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
wyk/02_Jezyki/voy-words-20.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
wyk/02_Jezyki/voy-words-log-log.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
wyk/02_Jezyki/voynich135.jpg
Normal file
After Width: | Height: | Size: 3.3 MiB |