840 lines
32 KiB
Plaintext
840 lines
32 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Podział na jednostki podwyrazowe\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Słownik nie może być za duży…\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Jeśli używamy wyuczalnych zanurzeń słów (embeddingów), wówczas musimy\n",
|
||
"je dopisać do listy parametrów całego modelu — jest to $|V|n$ wag,\n",
|
||
"gdzie $n$ to rozmiar embeddingów; w wypadku uczenia dodatkowo musimy\n",
|
||
"jeszcze pamiętać związane z embeddingami gradienty. Pamięć RAM karty\n",
|
||
"graficznej jest rzecz jasna ograniczona, słownik więc nie może być\n",
|
||
"dowolnie duży. Dla danego modelu karty graficznej dość łatwo ustalić\n",
|
||
"maksymalny rozmiar słownika — jest „twarde” ograniczenie, które musimy\n",
|
||
"spełnić.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Czy rzeczywiście słownik może być taki duży?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Ile jest różnych form fleksyjnych w języku polskim? Zobaczmy w słowniku PoliMorf…\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"a\n",
|
||
"aa\n",
|
||
"AA\n",
|
||
"Aachen\n",
|
||
"Aalborg\n",
|
||
"Aalborgiem\n",
|
||
"Aalborgowi\n",
|
||
"Aalborgu\n",
|
||
"AAP\n",
|
||
"Aar\n",
|
||
"Aarem\n",
|
||
"Aarowi\n",
|
||
"Aaru\n",
|
||
"Aarze\n",
|
||
"Aara\n",
|
||
"Aarą\n",
|
||
"Aarę\n",
|
||
"Aaro\n",
|
||
"Aary\n",
|
||
"Aarze\n",
|
||
"uniq: błąd zapisu: Przerwany potok\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! wget -q 'http://zil.ipipan.waw.pl/PoliMorf?action=AttachFile&do=get&target=PoliMorf-0.6.7.tab.gz' -O - | zcat | cut -f 1 | uniq | head -n 20"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"3844535\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! wget -q 'http://zil.ipipan.waw.pl/PoliMorf?action=AttachFile&do=get&target=PoliMorf-0.6.7.tab.gz' -O - | zcat | cut -f 1 | sort -u | wc -l"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**Pytanie** W którym języku europejskim wyrazów będzie jeszcze więcej niż języku polskim?\n",
|
||
"\n",
|
||
"Tak naprawdę form jest jeszcze więcej, oczywiście PoliMorf nie wyczerpuje zbioru…\n",
|
||
"\n",
|
||
"**Pytanie** Podaj przykłady „oczywistych” wyrazów, których nie ma w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów?\n",
|
||
"\n",
|
||
"Z drugiej strony, w PoliMorfie jest dużo dziwnych, „sztucznych” wyrazów.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"niebiałościenną\n",
|
||
"nieponadosobowości\n",
|
||
"nieknerający\n",
|
||
"inspektoratów\n",
|
||
"Korytkowskich\n",
|
||
"elektrostatyczności\n",
|
||
"Okola\n",
|
||
"bezsłowny\n",
|
||
"indygowcu\n",
|
||
"gadany\n",
|
||
"nieładowarkowościach\n",
|
||
"niepawężnicowate\n",
|
||
"Thom\n",
|
||
"poradlmy\n",
|
||
"olejący\n",
|
||
"Ziemianinów\n",
|
||
"stenotropizmami\n",
|
||
"wigiliowości\n",
|
||
"pognanej\n",
|
||
"niekinezyterapeutycznym\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! wget -q 'http://zil.ipipan.waw.pl/PoliMorf?action=AttachFile&do=get&target=PoliMorf-0.6.7.tab.gz' -O - | zcat | cut -f 1 | shuf -n 20"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Inaczej, zobaczmy, ile różnych wyrazów jest w jakimś rzeczywistym zbiorze tekstów, rozpatrzmy\n",
|
||
"teksty zebrane na potrzeby identyfikacji płci autora tekstu:\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"# Out[7]:"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! git clone --single-branch --depth 1 git://gonito.net/petite-difference-challenge2"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort -u > vocab.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"ˆ\n",
|
||
"ˇ\n",
|
||
"゚\n",
|
||
"a\n",
|
||
"A\n",
|
||
"á\n",
|
||
"Á\n",
|
||
"à\n",
|
||
"À\n",
|
||
"ă\n",
|
||
"Ă\n",
|
||
"â\n",
|
||
"Â\n",
|
||
"å\n",
|
||
"Å\n",
|
||
"ä\n",
|
||
"Ä\n",
|
||
"Ã\n",
|
||
"ā\n",
|
||
"aa\n",
|
||
"aA\n",
|
||
"Aa\n",
|
||
"AA\n",
|
||
"aĂ\n",
|
||
"AĂ\n",
|
||
"aâ\n",
|
||
"aÂ\n",
|
||
"Aâ\n",
|
||
"aÅ\n",
|
||
"aÄ\n",
|
||
"ª\n",
|
||
"aaa\n",
|
||
"aAa\n",
|
||
"Aaa\n",
|
||
"AaA\n",
|
||
"AAa\n",
|
||
"AAA\n",
|
||
"aaaa\n",
|
||
"aAaa\n",
|
||
"Aaaa\n",
|
||
"AaAa\n",
|
||
"AAaa\n",
|
||
"AAAa\n",
|
||
"AAAA\n",
|
||
"aaaaa\n",
|
||
"Aaaaa\n",
|
||
"AaaaA\n",
|
||
"AAaaa\n",
|
||
"AAAAA\n",
|
||
"aaaaaa\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! head -n 50 vocab.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"2974556 vocab.txt\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! wc -l vocab.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Co gorsza, nawet jak weźmiemy cały taki słownik bez ograniczeń i tak\n",
|
||
"nie pokryje on sporej części tekstów przetwarzanych w czasie inferencji.\n",
|
||
"Zobaczmy, ilu wyrazów ze zbioru deweloperskiego nie będzie w słowniku.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"81380\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! cat petite-difference-challenge2/dev-0/in.tsv | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort -u | comm vocab.txt - -13 | wc -l"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Takie wyrazy nazywamy wyrazami **OOV** (*out-of-vocabulary*).\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Obcięcie słownika\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Najprostszy sposób ograniczenia słownika to po prostu obcięcie do $N$ najczęstszych słów.\n",
|
||
"\n",
|
||
"Spróbujmy zastosować do korpusu „płci”:\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"sort: błąd zapisu: 'standardowe wyjście': Przerwany potok\n",
|
||
"sort: błąd zapisu\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort | uniq -c | sort -k 1rn | head -n 50000 | sort -k 2 > vocab50000.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Daje to lepszy efekt niż można się spodziewać. Odrzucamy w ten sposób\n",
|
||
"tylko bardzo rzadkie słowa (albo takie, które wystąpiły tylko raz w\n",
|
||
"korpusie — tzw. *hapax legomena*), choć tych słów jest bardzo dużo.\n",
|
||
"\n",
|
||
"**Zagadka**: 50000 najczęstszych słów (1,9% **typów**) pokrywa jaki odsetek **wystąpień**?\n",
|
||
"\n",
|
||
"Rozkład normalny w języku nie jest… normalny — nie spotkamy się z nim\n",
|
||
"badając języki. W tekstach dominują „skrzywione” rozkłady z długimi,\n",
|
||
"„chudymi” ogonami.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort | uniq -c | sort -k 1rn | cut -f 1 > freqs.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'word-distribution.png'"
|
||
]
|
||
},
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAEFCAYAAAD69rxNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAXf0lEQVR4nO3deZSdVZnv8e9TQ+YRUiEhIYQhBDDMhSB4kUFZkaalrwtYoNJ2yzUXb+ttbg8qehVv32UvV+ui2742l5tWBG0aW5S2kSYMjYzKVAlTSJgkAoEMBSEhIWMl+/5xTmWoU5U6qXNOndpV389aWanznvec93mz9ceu/b7v3pFSQpKUn4Z6FyBJ6hsDXJIyZYBLUqYMcEnKlAEuSZlq6s+DTZo0Kc2cObM/DylJ2Vu4cOFbKaWWrtv7NcBnzpxJW1tbfx5SkrIXEa92t90hFEnKlAEuSZkywCUpUwa4JGXKAJekTBngkpQpA1ySMpVFgN+7dBXX3v9yvcuQpAEliwC//4V2vv/QsnqXIUkDShYBDuDCE5K0pywCPKLeFUjSwJNFgAPY/5akPWUR4HbAJalUFgEuSSqVTYB7DVOS9pRFgIdXMSWpRBYBDt5GKEldZRPgkqQ9ZRPg9r8laU9ZBLhD4JJUKosAB+yCS1IXvQZ4RFwfEasjYnE37/1FRKSImFSb8orH8VEeSSpRTg/8BmBu140RcRDwEeC1KtfULTvgkrSnXgM8pfQgsKabt/4W+CL9kK2OgUtSqT6NgUfEx4A3UkpPl7HvvIhoi4i29vb2vhxOktSNfQ7wiBgFfBX4ejn7p5Tmp5RaU0qtLS0t+3q43b+nz5+VpMGoLz3ww4BDgKcj4nfAdGBRREypZmG7cwRFkko17esHUkrPApM7XxdDvDWl9FYV6yo9bi2/XJIyVM5thDcDjwCzI2J5RFxe+7K61tDfR5Skga/XHnhK6dJe3p9ZtWr2epz+OIok5SOLJzGdTlaSSmUR4ADJUXBJ2kMWAW7/W5JKZRHg4Bi4JHWVR4DbBZekEnkEON4HLkldZRHgTicrSaWyCHBJUql8AtwxFEnaQxYB7nM8klQqiwAHH+SRpK6yCHA74JJUKosABx/kkaSusghwx8AlqVQWAQ7ehCJJXWUR4D7II0mlsghwcFFjSeqqnCXVro+I1RGxeLdt346I5yPimYj414iYUMsiHQOXpFLl9MBvAOZ22XYPMCeldCzwInBVleuSJPWi1wBPKT0IrOmy7e6UUkfx5aPA9BrUtmcdtT6AJGWmGmPgnwEW9PRmRMyLiLaIaGtvb+/TARxBkaRSFQV4RHwV6ABu6mmflNL8lFJrSqm1paWlz8fyGqYk7amprx+MiE8D5wPnpFrfIuJVTEkq0acAj4i5wJeAD6WUNla3JElSOcq5jfBm4BFgdkQsj4jLge8BY4F7IuKpiLiulkXa/5akUr32wFNKl3az+Qc1qKVXKSXC4RRJAjJ5EtPMlqRSWQR4J+9EkaRdsghwJ7OSpFJZBLgkqVRWAe4IiiTtkkWAexFTkkplEeCdnBNcknbJIsDtgEtSqSwCvJP9b0naJYsAdwxckkplEeCdHAKXpF2yCHDnP5GkUlkEeKfkKLgk7ZRVgEuSdskqwB0Dl6Rdsghwh8AlqVQWAS5JKlXOkmrXR8TqiFi827b9IuKeiHip+PfE2pYpSeqqnB74DcDcLtu+DNybUpoF3Ft8XTPOBy5JpXoN8JTSg8CaLpsvAG4s/nwj8AfVLaunWvrjKJKUh76OgR+QUloBUPx7ck87RsS8iGiLiLb29vY+HcyLmJJUquYXMVNK81NKrSml1paWlsq+ywd5JGmnvgb4qoiYClD8e3X1SiplB1ySSvU1wG8DPl38+dPAv1WnnL1zDFySdinnNsKbgUeA2RGxPCIuB74FfCQiXgI+UnxdM46BS1Kppt52SCld2sNb51S5ll7ZAZekXbJ4EtP7wCWpVBYBLkkqlUWAd46Bb9/hIIokdcoiwJsbC2V2bN9R50okaeDIK8DtgUvSTlkEeFNjYQxla4c9cEnqlEWANxcD3B64JO2SRYA3NTgGLkldZRHgnWPgWw1wSdopkwAvDqFsdwhFkjplEeBNO+9CsQcuSZ2yCPDmhkIPfJs9cEnaKY8AbyqUuc0xcEnaKYsAb2pwDFySusoiwDvvQrEHLkm7ZBHgTT7II0klsghwe+CSVKqiAI+I/xERz0XE4oi4OSJGVKuw3Q3rfJDHuVAkaac+B3hETAP+O9CaUpoDNAKXVKuw3Y1obgRgswEuSTtVOoTSBIyMiCZgFPBm5SWVGjmsGOBbt9fi6yUpS30O8JTSG8B3gNeAFcC6lNLdXfeLiHkR0RYRbe3t7X061shiD3yjAS5JO1UyhDIRuAA4BDgQGB0Rn+q6X0ppfkqpNaXU2tLS0qdjNTYEw5oa2Lito6/lStKgU8kQyoeBZSml9pTSNuBW4LTqlFVq9LBGNm6xBy5JnSoJ8NeAUyNiVEQEcA6wtDpllRo9vIkNW+yBS1KnSsbAHwN+BiwCni1+1/wq1VVizPAm1m82wCWpU1MlH04pXQ1cXaVa9mrsiCY2bNnWH4eSpCxk8SQmwLgRzfbAJWk3+QT4yGbWbbIHLkmdsgnw8SObWbfRAJekTtkE+MRRw1i/pcP5UCSpKJsA3290MwBrN22tcyWSNDBkE+ATRw8DYM17BrgkQUYB3jJmOADt67fUuRJJGhiyCfDJ4wpTja9+1wCXJMgowA8YV+iBr3x3c50rkaSBIZsAHzWsiXEjmli5zgCXJMgowAGmTRzFm2s31bsMSRoQsgrw6RNH8vo7G+tdhiQNCFkF+Iz9RvHamo2klOpdiiTVXVYBPnP/UWzetoPV3kooSZkF+KTRALzS/l6dK5Gk+ssqwA9rGQPAy6vX17kSSaq/rAJ86vgRjB3exIurNtS7FEmqu4oCPCImRMTPIuL5iFgaER+oVmE9HI/ZU8aydMW7tTyMJGWh0h74d4E7U0pHAsdRw0WNOx194DiWrniXHTu8E0XS0NbnAI+IccAZwA8AUkpbU0prq1RXj+ZMG897W7ez7G0vZEoa2irpgR8KtAM/jIgnI+L7ETG6604RMS8i2iKirb29vYLDFRw7fTwAT7++tuLvkqScVRLgTcCJwP9NKZ0AvAd8uetOKaX5KaXWlFJrS0tLBYcrmDV5LGOGN7HotXcq/i5JylklAb4cWJ5Seqz4+mcUAr2mGhuCE2ZM4IllBrikoa3PAZ5SWgm8HhGzi5vOAZZUpapenHro/rywaj1vbfCJTElDV6V3oXwBuCkingGOB/664orK8MHDJwHw65ff6o/DSdKA1FTJh1NKTwGt1SmlfHOmjWfCqGYeeLGdC46f1t+Hl6QBIasnMTs1NgRnHtHCfc+vpmP7jnqXI0l1kWWAA8ydM4V3Nm7jsWVr6l2KJNVFtgH+oSMmM3pYI7948o16lyJJdZFtgI8c1sjcOVO5c/FKNm/bXu9yJKnfZRvgABccfyDrt3Rw79LV9S5Fkvpd1gF+2mH7M2XcCG5Z+Hq9S5Gkfpd1gDc1NnBR63QeeLGdZW85uZWkoSXrAAe47NSDaWoIbvzN7+pdiiT1q+wDfPK4Efz+sQfyL0+8zpr3tta7HEnqN9kHOMBnzziUTdu28/V/W1zvUiSp3wyKAD9q6jj+06xJ3P7MCt5Yu6ne5UhSvxgUAQ7wJ2cdDsCVP3myzpVIUv8YNAF+6qH7M23CSJ743Ts89+a6epcjSTU3aAIc4HufOAGAy29oq3MlklR7gyrAT5gxkfcdOI6V727m5wuX17scSaqpQRXgAD/8o5MB+PNbnmabU81KGsQGXYBPHjeCz5x+CADfufuFOlcjSbVTcYBHRGNEPBkRt1ejoGr42vlHcdbsFv7fA69w3wtOdCVpcKpGD/xPgaVV+J6qiQiuufh4xg5v4o9/+ISLH0salCoK8IiYDvwe8P3qlFM9E0cP44sfPRKAs75zPymlOlckSdVVaQ/874AvAj1eLYyIeRHRFhFt7e3tFR5u31x26sGcOGMC6zd38IfXP96vx5akWutzgEfE+cDqlNLCve2XUpqfUmpNKbW2tLT09XB9dssVpwHw0Etv8a0Fz/f78SWpVirpgZ8OfCwifgf8BDg7Iv6pKlVVUWND8PhXzwHgugd+y0+fcPEHSYNDnwM8pXRVSml6SmkmcAnwq5TSp6pWWRVNHjuCX37+gwB88efPsODZFXWuSJIqN+juA+/JMdPH73zI53M3LeLu51bWuSJJqkxVAjyldH9K6fxqfFctnXXkZK795IkAzPvxQu6wJy4pY0OmB97pvGOm8veXFia9+m83LeLWRc6ZIilPQy7AAT523IFc96mTAPiznz7NdQ/8ts4VSdK+G5IBDjB3zhR+Mu9UAL614Hn+7F+e8mEfSVkZsgEOhUUgfvXnHwLg1iff4JxrHmBLx/Y6VyVJ5RnSAQ5waMsYnvzaR2hsCF5pf4/Z//NOXn37vXqXJUm9GvIBDoV5U17433P54OGTAPjQt+/nhl8vq3NVkrR3BnhRU2MD//RfTuGb/3kOAN/45RKu+PFCtu9wXFzSwGSAd/HJUw7mts+fDsCdz63ksK/cwaLX3qlzVZJUygDvxrHTJ/DMN86l9eCJAHz82t/wV79cQodLtEkaQAzwHowb0cwtV3yAay4+DoDrf72M1m/+B4vfWFfnyiSpwADfi4jg4ydO55lvnMt5x0xh7cZtnP9/Hua//riNDVs66l2epCHOAC/DuBHNXPvJk/j2hccCcNdzq5hz9V0seHaFQS6pbgzwfXBR60E8/KWz+NyZhwGFWQ1P/9avWL1+sw8ASep30Z+Pj7e2tqa2trZ+O14t3ff8au5espKbHy8sEDFtwkge/tJZRESdK5M02ETEwpRSa9ftTfUoZjA468jJvP+Q/Thm2gQeeqmdBYtXMufquxg/spnbvvBBJo0ZXu8SJQ1yBngFRg9v4hOnzOCcoyYzY/9RLH9nE//+zAo++6M2xo9s5tyjp/CJU2bUu0xJg5QBXgUHjBvBVR89inWbtrFu4zbWb97Gk6+t5aVVGxgzovBPfPTUsRw+eWydK5U0mPR5DDwiDgJ+BEwBdgDzU0rf3dtnBtMYeG+++e9L+MeHds2ncuSUsdx55Rl1rEhSrnoaA68kwKcCU1NKiyJiLLAQ+IOU0pKePjOUArxj+w5eXbORlOC7977EgmdXMOuAQg88gCs/PItz3zelvkVKykLVL2KmlFYAK4o/r4+IpcA0oMcAH0qaGhs4rGUMAJ/+wMFs2badzv9UPvhiO3c+t5KTio/qA4wc1sioYY5oSSpfVW4jjIiZwIPAnJTSu13emwfMA5gxY8ZJr776asXHy925f/sAL67asMe2kc2NPHLV2UwYNaxOVUkaqGp2G2FEjAF+DlzZNbwBUkrzgflQGEKp9HiDwbcvPI6nl6/d+Xrpine5+fHXeX7lemZNHrPHvqOHNzGiubGfK5SUg4oCPCKaKYT3TSmlW6tT0uB33EETOO6gCTtf/+a3b3Hz469zyfxHS/adMm4Ej1x1tg8ISSrR5wCPQqL8AFiaUrqmeiUNPSfP3I/vXHQcG7fuOa/Kwy+9xd1LVrGlY4e9cEklKumBnw5cBjwbEU8Vt30lpXRHxVUNMc2NDVx40vRu37t7ySouv/EJmhq6n7bm/GOnclHrQbUsT9IAVcldKA9TuCNONfL+Q/bj5JkT2bBlO1A6WdYrqzfw3pYOA1waorxvbQA7cso4brnitB7f/8wNT7B6/eZ+rEjSQGKAZ2xkcyMvrtrA3L97sKz9p08cxfzLTqKhwV+cpMHAAM/YRa3T6dhR3jqdr769kf9Yuor1WzoYP7K5xpVJ6g8GeMbOnD2ZM2dPLmvfHz/6Kl/7xeLiwhMGuDQYGOBDxPDGwl0sq9ZtISq89tzUEEwc7ROjUr0Z4EPE6OGFpv797z1cle/73idO4PxjD6zKd0nqGwN8iDjnqMn8zYXHsqWjvDHznmzr2MFf3b6EN9duqlJlkvrKAB8iRjQ3cnEV7hffWgzwbdud1kaqN1el1z5pbiyMn2+tsCcvqXIGuPZJRNDUEGXfviipdhxC0T5ragz++bHXuGfJqnqX0q0Jo4bxwz86eeeFW2mw8n/h2mdfOHsWi99YV+8yurVi3WYeX7aGN9Zu4ogDXERag5sBrn32J2cdXu8SerTg2RV87qZFbN/hRVYNfo6Ba1DpnOfFANdQYIBrUGksrly0owprvUoDnQGuQaXRHriGEANcg4pDKBpKKgrwiJgbES9ExMsR8eVqFSX1VecQigGuoaDPAR4RjcA/AB8FjgYujYijq1WY1Bc7h1AcA9cQUMlthO8HXk4pvQIQET8BLgCWVKMwqS86A/wvb3mGUcMa61yNtMtff/wYTp65X1W/s5IAnwa8vtvr5cApXXeKiHnAPIAZM2ZUcDipd+87cBwXt05nw5aOepci7WFkc/U7FJUEeHerApT83ppSmg/MB2htbfX3WtXU6OFN/M2Fx9W7DKlfVHIRczmw+/yk04E3KytHklSuSgL8CWBWRBwSEcOAS4DbqlOWJKk3fR5CSSl1RMTngbuARuD6lNJzVatMkrRXFU1mlVK6A7ijSrVIkvaBT2JKUqYMcEnKlAEuSZkywCUpU5H6cc6IiGgHXu3jxycBb1WxnHryXAauwXQ+nsvA1JdzOTil1NJ1Y78GeCUioi2l1FrvOqrBcxm4BtP5eC4DUzXPxSEUScqUAS5JmcopwOfXu4Aq8lwGrsF0Pp7LwFS1c8lmDFyStKeceuCSpN0Y4JKUqQEX4L0tlBwFf198/5mIOLEedZajjHM5MyLWRcRTxT9fr0ed5YiI6yNidUQs7uH9nNqlt3PJqV0Oioj7ImJpRDwXEX/azT5ZtE2Z55JF20TEiIh4PCKeLp7L/+pmn8rbJaU0YP5QmJb2t8ChwDDgaeDoLvucByygsCLQqcBj9a67gnM5E7i93rWWeT5nACcCi3t4P4t2KfNccmqXqcCJxZ/HAi9m/P+Zcs4li7Yp/luPKf7cDDwGnFrtdhloPfCdCyWnlLYCnQsl7+4C4Eep4FFgQkRM7e9Cy1DOuWQjpfQgsGYvu+TSLuWcSzZSSitSSouKP68HllJYr3Z3WbRNmeeSheK/9Ybiy+bin653jFTcLgMtwLtbKLlrA5azz0BQbp0fKP6atSAi3tc/pdVELu1SruzaJSJmAidQ6O3tLru22cu5QCZtExGNEfEUsBq4J6VU9XapaEGHGihnoeSyFlMeAMqpcxGFOQ42RMR5wC+AWbUurEZyaZdyZNcuETEG+DlwZUrp3a5vd/ORAds2vZxLNm2TUtoOHB8RE4B/jYg5KaXdr7tU3C4DrQdezkLJuSym3GudKaV3O3/NSoXVjZojYlL/lVhVubRLr3Jrl4hophB4N6WUbu1ml2zaprdzya1tAFJKa4H7gbld3qq4XQZagJezUPJtwB8Wr+CeCqxLKa3o70LL0Ou5RMSUiIjiz++n0B5v93ul1ZFLu/Qqp3Yp1vkDYGlK6Zoedsuibco5l1zaJiJaij1vImIk8GHg+S67VdwuA2oIJfWwUHJEXFF8/zoKa3CeB7wMbAT+uF717k2Z53Ih8LmI6AA2AZek4uXpgSYibqZwB8CkiFgOXE3hwkxW7QJlnUs27QKcDlwGPFscbwX4CjADsmubcs4ll7aZCtwYEY0U/iPz05TS7dXOMh+ll6RMDbQhFElSmQxwScqUAS5JmTLAJSlTBrgk1Uj0MnFaN/tfHBFLihNg/XOv+3sXiiTVRkScAWygMOfJnF72nQX8FDg7pfRORExOKa3e22fsgUtSjXQ3cVpEHBYRd0bEwoh4KCKOLL71WeAfUkrvFD+71/AGA1yS+tt84AsppZOAvwCuLW4/AjgiIn4dEY9GRNdH70sMqCcxJWkwK07UdRpwS3FGAIDhxb+bKEzMdSaFeVEeKk6Atban7zPAJan/NABrU0rHd/PecuDRlNI2YFlEvEAh0J/Y25dJkvpBcXrcZRFxEexcVu244tu/AM4qbp9EYUjllb19nwEuSTVSnDjtEWB2RCyPiMuBTwKXR8TTwHPsWqnrLuDtiFgC3Af8ZUpprzMtehuhJGXKHrgkZcoAl6RMGeCSlCkDXJIyZYBLUqYMcEnKlAEuSZn6/0eQrxlOiW/HAAAAAElFTkSuQmCC\n",
|
||
"text/plain": [
|
||
"<Figure size 432x288 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {
|
||
"needs_background": "light"
|
||
},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"%matplotlib inline\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"import re\n",
|
||
"from math import log\n",
|
||
"\n",
|
||
"freqs = []\n",
|
||
"\n",
|
||
"with open('freqs.txt', 'r') as fh:\n",
|
||
" for line in fh:\n",
|
||
" m = re.match(r'\\s*(\\d+)', line)\n",
|
||
" if m:\n",
|
||
" freqs.append(log(float(m.group(1))))\n",
|
||
"\n",
|
||
"plt.plot(range(len(freqs)), freqs)\n",
|
||
"fname = 'word-distribution.png'\n",
|
||
"plt.savefig(fname)\n",
|
||
"fname"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"[[file:# Out[25]:\n",
|
||
"\n",
|
||
" 'word-distribution.png'\n",
|
||
"\n",
|
||
"![img](./obipy-resources/c0TrCn.png)]]\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Lematyzacja\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Lematyzacja wydaje się dobrym pomysłem, zwłaszcza dla języków dla bogatej fleksji:\n",
|
||
"\n",
|
||
"- znacznie redukujemy słownik,\n",
|
||
"- formy fleksyjne tego samego wyrazu są traktowane tak samo (co wydaje się słuszne).\n",
|
||
"\n",
|
||
"W praktyce współcześnie **nie** stosuje się lematyzacji (w połączeniu z\n",
|
||
"metodami opartymi na sieciach neuronowych):\n",
|
||
"\n",
|
||
"- lematyzacja wymaga wiedzy językowej (reguł lub słownika),\n",
|
||
" wytworzenie takiej wiedzy może być kosztowne, obecnie preferowane\n",
|
||
" są metody niezależne od języka;\n",
|
||
"- tracimy pewną informację niesioną przez formę fleksyjną (co w szczególnych\n",
|
||
" przypadkach może być niefortunne, np. *aspiracja* i *aspiracje*);\n",
|
||
"- lematyzacja nie jest trywialnym problemem ze względu na niejednoznaczności\n",
|
||
" (*Lekarzu, lecz się sam*);\n",
|
||
"- niektóre niejednoznaczności są seryjne, wybór lematu może być arbitralny,\n",
|
||
" np. czy *posiadanie*, *gotowanie*, *skakanie* to rzeczowniki czy czasowniki?\n",
|
||
" a *urządzenie*, *mieszkanie*?\n",
|
||
"- zazwyczaj sieci neuronowe (czy nawet prostsze modele typu Word2vec)\n",
|
||
" są w stanie nauczyć się rekonstruowania zależności między formami fleksyjnymi\n",
|
||
" (i więcej: błędnych form, błędów ortograficznych, form archaicznych itd.)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Zejście na poziom znaków\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Skoro słownik wyrazów jest zbyt duży, to może zejść na poziom znaków?\n",
|
||
"\n",
|
||
"- pojedynczy znak alfabetu wprawdzie nic nie znaczy (co znaczy *h*?)\n",
|
||
"\n",
|
||
"- … ale rozmiar wejścia przy kodowaniu gorącą jedynką\n",
|
||
" dramatycznie się zmniejsza\n",
|
||
"\n",
|
||
"- może działać, jeśli dodać wielowarstwową sieć\n",
|
||
" neuronową\n",
|
||
"\n",
|
||
"- … ale może być bardzo kosztowne obliczeniowo\n",
|
||
"\n",
|
||
"A może coś pośredniego między znakami a wyrazami?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### BPE\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Ani znaki, ani wyrazy — coś pomiędzy: jednostki podwyrazowe (*subword\n",
|
||
"units*). Moglibyśmy np. dzielić wyraz *superkomputera* na dwie\n",
|
||
"jednostki *super/+/komputera*, a może nawet trzy: *super/+/komputer/+/a*?\n",
|
||
"\n",
|
||
"Najpopularniejszy algorytm podziału na jednostki podwyrazowe to BPE\n",
|
||
"(*byte-pair encoding*), zainspirowany algorytmami kompresji danych.\n",
|
||
"Lista jednostek jest automatycznie indukowana na podstawie tekstu (nie\n",
|
||
"potrzeba żadnej wiedzy o języku!). Ich liczba musi być natomiast z góry\n",
|
||
"określona.\n",
|
||
"\n",
|
||
"W kroku początkowym zaznaczamy końce wyrazów (tokenów), robimy to po\n",
|
||
"to, żeby jednostki podwyrazowe nie przekraczały granic wyrazów.\n",
|
||
"\n",
|
||
"Następnie wykonujemy tyle kroków iteracji, ile wynosi rozmiar zadanego\n",
|
||
"słownika. W każdym kroku szukamy najczęstszego bigramu, od tego\n",
|
||
"momentu traktujemy go jako całostkę (wkładamy go do „pudełka”).\n",
|
||
"\n",
|
||
"![img](./bpe.png)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Implementacja w Pythonie\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"['e$', 'to', 'to$', 'be$', 't$', 'th', 'or', 'or$', 'no', 'not$']"
|
||
]
|
||
},
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from collections import Counter\n",
|
||
"\n",
|
||
"def replace_bigram(l, b, r):\n",
|
||
" i = 0\n",
|
||
" while i < len(l) - 1:\n",
|
||
" if (l[i], l[i+1]) == b:\n",
|
||
" l[i:i+2] = [r]\n",
|
||
" i += 1\n",
|
||
" return l\n",
|
||
"\n",
|
||
"def learn_bpe_vocab(d, max_vocab_size):\n",
|
||
" d = list(d.replace(' ', '$') + '$')\n",
|
||
"\n",
|
||
" vocab = []\n",
|
||
"\n",
|
||
" for ix in range(0, max_vocab_size):\n",
|
||
" bigrams = [(d[i], d[i+1]) for i in range(0, len(d) - 1) if d[i][-1] != '$']\n",
|
||
" selected_bigram = Counter(bigrams).most_common(1)[0][0]\n",
|
||
"\n",
|
||
" new_subword = selected_bigram[0] + selected_bigram[1]\n",
|
||
" d = replace_bigram(d, selected_bigram, new_subword)\n",
|
||
"\n",
|
||
" vocab.append(new_subword)\n",
|
||
"\n",
|
||
" return vocab\n",
|
||
"\n",
|
||
"vocab1 = learn_bpe_vocab('to be or not to be that is the question', 10)\n",
|
||
"vocab1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Słownik jednostek podwyrazowych możemy zastosować do dowolnego tekstu, np. do tekstu,\n",
|
||
"na którym słownik był wyuczony:\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'to$ be$ or$ not$ to$ be$ th a t$ i s $ th e$ q u e s t i o n $'"
|
||
]
|
||
},
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"def apply_bpe_vocab(vocab, d):\n",
|
||
" d = list(d.replace(' ', '$') + '$')\n",
|
||
" vocab_set = set(vocab)\n",
|
||
"\n",
|
||
" modified = True\n",
|
||
" while modified:\n",
|
||
" ix = 0\n",
|
||
" modified = False\n",
|
||
" while ix < len(d) - 1:\n",
|
||
" bigram = d[ix] + d[ix+1]\n",
|
||
" if bigram in vocab_set:\n",
|
||
" d[ix:ix+2] = [bigram]\n",
|
||
" modified = True\n",
|
||
" else:\n",
|
||
" ix += 1\n",
|
||
"\n",
|
||
" return d\n",
|
||
"\n",
|
||
"' '.join(apply_bpe_vocab(vocab1, 'to be or not to be that is the question'))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Zauważmy, że oprócz jednostek podwyrazowych zostały izolowane litery,\n",
|
||
"zazwyczaj dodajemy je do słownika. (I zazwyczaj, słownik jest trochę\n",
|
||
"większy niż wartość podana jako parametr przy uczeniu BPE — jest\n",
|
||
"większy o znaki i specjalne tokeny typu `UNK`, `BOS`, `EOS`, `PAD`.)\n",
|
||
"\n",
|
||
"**Pytanie**: Jaki problem może pojawić przy zastosowaniu BPE dla tekstu,\n",
|
||
"gdzie pojawiają się chińskie znaki? Jak można sobie z nim poradzić?\n",
|
||
"\n",
|
||
"Słownik jednostek podwyrazowych można stosować dla dowolnego tekstu:\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'to m $ w i l l $ be$ th e$ b e s t$'"
|
||
]
|
||
},
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"' '.join(apply_bpe_vocab(vocab1, 'tom will be the best'))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Jak można zauważyć algorytm BPE daje dwa rodzaje jednostek podwyrazowych:\n",
|
||
"\n",
|
||
"- jednostki, które mogą doklejane na początku wyrazu;\n",
|
||
"- jednostki, które stanowią koniec wyrazu, w szczególności są całym wyrazem.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Gotowa implementacja\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Po raz pierwszy BPE użyto do neuronowego tłumaczenia maszynowego.\n",
|
||
"Użyjmy modułu autorstwa Rica Sennricha ([https://github.com/rsennrich/subword-nmt](https://github.com/rsennrich/subword-nmt)).\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"! pip install subword-nmt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Wyindukujmy słownik dla zbioru uczącego zadania identyfikacji płci\n",
|
||
"autora tekstu:\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | python -m subword_nmt.learn_bpe -s 50000 -v > bpe_vocab.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Procedura trwa kilka minut, trzeba uzbroić się w cierpliwość (ale wypisywanie bigramów przyspieszy!).\n",
|
||
"\n",
|
||
" pair 0: n i -> ni (frequency 17625075)\n",
|
||
" pair 1: i e -> ie (frequency 11471590)\n",
|
||
" pair 2: c z -> cz (frequency 9143490)\n",
|
||
" pair 3: ni e</w> -> nie</w> (frequency 7901783)\n",
|
||
" pair 4: p o -> po (frequency 7790826)\n",
|
||
" pair 5: r z -> rz (frequency 7542046)\n",
|
||
" pair 6: s t -> st (frequency 7269069)\n",
|
||
" pair 7: e m</w> -> em</w> (frequency 7207280)\n",
|
||
" pair 8: d z -> dz (frequency 6860931)\n",
|
||
" pair 9: s z -> sz (frequency 6609907)\n",
|
||
" pair 10: r a -> ra (frequency 6601618)\n",
|
||
" pair 11: o w -> ow (frequency 6395963)\n",
|
||
" pair 12: i e</w> -> ie</w> (frequency 5906869)\n",
|
||
" pair 13: n a -> na (frequency 5300380)\n",
|
||
" pair 14: r o -> ro (frequency 5181363)\n",
|
||
" pair 15: n a</w> -> na</w> (frequency 5125807)\n",
|
||
" pair 16: a ł -> ał (frequency 4786696)\n",
|
||
" pair 17: j e -> je (frequency 4599579)\n",
|
||
" pair 18: s i -> si (frequency 4300984)\n",
|
||
" pair 19: a l -> al (frequency 4276823)\n",
|
||
" pair 20: t e -> te (frequency 4033344)\n",
|
||
" pair 21: w i -> wi (frequency 3939063)\n",
|
||
" pair 22: c h</w> -> ch</w> (frequency 3919410)\n",
|
||
" pair 23: c h -> ch (frequency 3661410)\n",
|
||
" pair 24: k o -> ko (frequency 3629840)\n",
|
||
" pair 25: z a -> za (frequency 3625424)\n",
|
||
" pair 26: t a -> ta (frequency 3570094)\n",
|
||
" pair 27: p rz -> prz (frequency 3494551)\n",
|
||
" pair 28: g o</w> -> go</w> (frequency 3279997)\n",
|
||
" pair 29: a r -> ar (frequency 3081492)\n",
|
||
" pair 30: si ę</w> -> się</w> (frequency 2973681)\n",
|
||
" ...\n",
|
||
" pair 49970: brz mieniu</w> -> brzmieniu</w> (frequency 483)\n",
|
||
" pair 49971: bieżą cych</w> -> bieżących</w> (frequency 483)\n",
|
||
" pair 49972: biegu nkę</w> -> biegunkę</w> (frequency 483)\n",
|
||
" pair 49973: ban kowości</w> -> bankowości</w> (frequency 483)\n",
|
||
" pair 49974: ba ku</w> -> baku</w> (frequency 483)\n",
|
||
" pair 49975: ba cznie</w> -> bacznie</w> (frequency 483)\n",
|
||
" pair 49976: Przypad kowo</w> -> Przypadkowo</w> (frequency 483)\n",
|
||
" pair 49977: MA Ł -> MAŁ (frequency 483)\n",
|
||
" pair 49978: Lep pera</w> -> Leppera</w> (frequency 483)\n",
|
||
" pair 49979: Ko za -> Koza (frequency 483)\n",
|
||
" pair 49980: Jak byś</w> -> Jakbyś</w> (frequency 483)\n",
|
||
" pair 49981: Geni alne</w> -> Genialne</w> (frequency 483)\n",
|
||
" pair 49982: Że nada</w> -> Żenada</w> (frequency 482)\n",
|
||
" pair 49983: ń czykiem</w> -> ńczykiem</w> (frequency 482)\n",
|
||
" pair 49984: zwie ń -> zwień (frequency 482)\n",
|
||
" pair 49985: zost ałaś</w> -> zostałaś</w> (frequency 482)\n",
|
||
" pair 49986: zni szczona</w> -> zniszczona</w> (frequency 482)\n",
|
||
" pair 49987: ze stawi -> zestawi (frequency 482)\n",
|
||
" pair 49988: za sób</w> -> zasób</w> (frequency 482)\n",
|
||
" pair 49989: węd rówkę</w> -> wędrówkę</w> (frequency 482)\n",
|
||
" pair 49990: wysko czyła</w> -> wyskoczyła</w> (frequency 482)\n",
|
||
" pair 49991: wyle czenia</w> -> wyleczenia</w> (frequency 482)\n",
|
||
" pair 49992: wychowaw cze</w> -> wychowawcze</w> (frequency 482)\n",
|
||
" pair 49993: w t -> wt (frequency 482)\n",
|
||
" pair 49994: un da -> unda (frequency 482)\n",
|
||
" pair 49995: udzie lałem</w> -> udzielałem</w> (frequency 482)\n",
|
||
" pair 49996: tę czy</w> -> tęczy</w> (frequency 482)\n",
|
||
" pair 49997: tro sce</w> -> trosce</w> (frequency 482)\n",
|
||
" pair 49998: słusz ności</w> -> słuszności</w> (frequency 482)\n",
|
||
" pair 49999: su me</w> -> sume</w> (frequency 482\n",
|
||
"\n",
|
||
"Zastosujmy teraz wyindukowany słownik BPE dla jakiegoś rzeczywistego tekstu.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Cier@@ piałem na straszne la@@ gi kilkanaście sekund lub dłużej czarnego ekranu przy próbie przełą@@ czenia się uruchomienia prawie każdej aplikacji Dodatkowo telefon mi się wyłą@@ czał czasem bez powodu sam z siebie albo rese@@ tował Ostatnio nawet przeglądarka zaczęła się często zawie@@ szać i Android proponował wymu@@ szone zamknięcie Do tego te problemy z połączeniem do komputera przez USB "
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"! echo 'Cierpiałem na straszne lagi – kilkanaście sekund lub dłużej czarnego ekranu przy próbie przełączenia się / uruchomienia prawie każdej aplikacji. Dodatkowo telefon mi się wyłączał czasem bez powodu – sam z siebie, albo resetował. Ostatnio nawet przeglądarka zaczęła się często zawieszać i Android proponował wymuszone zamknięcie. Do tego te problemy z połączeniem do komputera przez USB.' | perl -C -ne 'print \"$& \" while/\\p{L}+/g;' | python -m subword_nmt.apply_bpe -c bpe_vocab.txt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Ta konkretna implementacja zaznacza za pomocą sekwencji ~@@ ~ koniec jednostki podwyrazowej.\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.9.2"
|
||
},
|
||
"org": null
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
}
|