Drobne poprawki w wykładzie
This commit is contained in:
parent
f804311da1
commit
72db2aa687
@ -15,16 +15,14 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Wyszukiwarki - wprowadzenie\n",
|
||||
"\n",
|
||||
"## Systemy wyszukiwania informacji (information retrieval systems)\n",
|
||||
"\n",
|
||||
"![System wyszukiwania informacji](system-wyszukiwania-informacji.png)"
|
||||
"![Schemat systemu wyszukiwania informacji](system-wyszukiwania-informacji.png)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -36,7 +34,7 @@
|
||||
"source": [
|
||||
"## Wyszukiwarki\n",
|
||||
"\n",
|
||||
"![Wyszukiwarki](wyszukiwarka-internetowa.png)"
|
||||
"![Schemat wyszukiwarki internetowej](wyszukiwarka-internetowa.png)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -108,7 +106,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Dostępne są też \"ekstrakty\" czystego tekstu - zob. http://data.statmt.org/ngrams/raw/, np. 59 GB czystego tekstu po polsku z 2012 roku."
|
||||
"Dostępne są też „ekstrakty” czystego tekstu — zob. http://data.statmt.org/ngrams/raw/, np. 59 GB czystego tekstu po polsku z 2012 roku."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -303,7 +301,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Odpytywać \"pasożytniczo\" inną wyszukiwarkę"
|
||||
"### Odpytywać „pasożytniczo” inną wyszukiwarkę"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -312,7 +310,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# see https://hackernoon.com/how-to-scrape-google-with-python-bo7d2tal\n",
|
||||
"# zob. https://hackernoon.com/how-to-scrape-google-with-python-bo7d2tal\n",
|
||||
"\n",
|
||||
"import urllib\n",
|
||||
"import requests\n",
|
||||
|
@ -328,7 +328,7 @@
|
||||
"\n",
|
||||
"* urllib\n",
|
||||
"* request\n",
|
||||
"* Beautiful Soup (do parsowania HTML-a)"
|
||||
"* Beautiful Soup (do parsowania dokumentów HTML)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2,15 +2,13 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"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> Ekstrakcja informacji </h1>\n",
|
||||
"<h2> 5. <i>G\u0119ste reprezentacje wektorowe</i> [wyk\u0142ad]</h2> \n",
|
||||
"<h3> Filip Grali\u0144ski (2021)</h3>\n",
|
||||
"<h2> 5. <i>Gęste reprezentacje wektorowe</i> [wykład]</h2> \n",
|
||||
"<h3> Filip Graliński (2021)</h3>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
|
||||
@ -20,19 +18,19 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Zag\u0119szczamy wektory\n",
|
||||
"# Zagęszczamy wektory\n",
|
||||
"\n",
|
||||
"Podstawowy problem z wektorow\u0105 reprezentacj\u0105 typu tf-idf polega na tym, \u017ce wektory dokument\u00f3w (i macierz ca\u0142ej kolekcji dokument\u00f3w) s\u0105 _rzadkie_, tzn. zawieraj\u0105 du\u017co zer. W praktyce potrzebujemy bardziej \"g\u0119stej\" czy \"kompaktowej\" reprezentacji numerycznej dokument\u00f3w. \n",
|
||||
"Podstawowy problem z wektorową reprezentacją typu tf-idf polega na tym, że wektory dokumentów (i macierz całej kolekcji dokumentów) są _rzadkie_, tzn. zawierają dużo zer. W praktyce potrzebujemy bardziej \"gęstej\" czy \"kompaktowej\" reprezentacji numerycznej dokumentów. \n",
|
||||
"\n",
|
||||
"## _Hashing trick_\n",
|
||||
"\n",
|
||||
"Powierzchownie problem mo\u017cemy rozwi\u0105za\u0107 przez u\u017cycie tzw. _sztuczki z haszowaniem_ (_hashing trick_). B\u0119dziemy potrzebowa\u0107 funkcji mieszaj\u0105cej (haszuj\u0105cej) $H$, kt\u00f3ra rzutuje napisy na liczby, kt\u00f3rych reprezentacja binarna sk\u0142ada si\u0119 z $b$ bit\u00f3w:\n",
|
||||
"Powierzchownie problem możemy rozwiązać przez użycie tzw. _sztuczki z haszowaniem_ (_hashing trick_). Będziemy potrzebować funkcji mieszającej (haszującej) $H$, która rzutuje napisy na liczby, których reprezentacja binarna składa się z $b$ bitów:\n",
|
||||
"\n",
|
||||
"$$H : \\Sigma^{*} \\rightarrow \\{0,\\dots,2^b-1\\}$$\n",
|
||||
"\n",
|
||||
"($\\Sigma^{*}$ to zbi\u00f3r wszystkich napis\u00f3w.)\n",
|
||||
"($\\Sigma^{*}$ to zbiór wszystkich napisów.)\n",
|
||||
"\n",
|
||||
"**Pytanie:** Czy funkcja $H$ mo\u017ce by\u0107 r\u00f3\u017cnowarto\u015bciowa?\n",
|
||||
"**Pytanie:** Czy funkcja $H$ może być różnowartościowa?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -40,7 +38,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Jako funkcji $H$ mo\u017cemy np. u\u017cy\u0107 funkcji MurmurHash2 lub 3."
|
||||
"Jako funkcji $H$ możemy np. użyć funkcji MurmurHash2 lub 3."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -138,14 +136,14 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Pytanie:** podobne napisy maj\u0105 zupe\u0142nie r\u00f3\u017cne warto\u015bci funkcji haszuj\u0105cej, czy to dobrze, czy to \u017ale?"
|
||||
"**Pytanie:** podobne napisy mają zupełnie różne wartości funkcji haszującej, czy to dobrze, czy to źle?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Musimy tylko sparametryzowa\u0107 nasz\u0105 funkcj\u0119 rozmiarem \"odcisku\" (parametr $b$)."
|
||||
"Musimy tylko sparametryzować naszą funkcję rozmiarem „odcisku” (parametr $b$)."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -204,12 +202,12 @@
|
||||
"\n",
|
||||
"import Data.Text\n",
|
||||
"\n",
|
||||
"-- pomocnicza funkcja, kt\u00f3ra konwertuje warto\u015b\u0107 specjalnego\n",
|
||||
"-- typu Hash64 do zwyk\u0142ej liczby ca\u0142kowitej\n",
|
||||
"-- pomocnicza funkcja, która konwertuje wartość specjalnego\n",
|
||||
"-- typu Hash64 do zwykłej liczby całkowitej\n",
|
||||
"hashValueAsInteger :: Hash64 -> Integer\n",
|
||||
"hashValueAsInteger = toInteger . asWord64\n",
|
||||
"\n",
|
||||
"-- unpack to funkcja, kt\u00f3ra warto\u015b\u0107 typu String konwertuje do Text\n",
|
||||
"-- unpack to funkcja, która wartość typu String konwertuje do Text\n",
|
||||
"hash :: Integer -> Text -> Integer\n",
|
||||
"hash b t = hashValueAsInteger (hash64 $ unpack t) `mod` (2 ^ b)\n",
|
||||
"\n",
|
||||
@ -224,21 +222,21 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Pytanie:** Jakie warto\u015bci $b$ b\u0119d\u0105 bezsensowne?"
|
||||
"**Pytanie:** Jakie wartości $b$ będą bezsensowne?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Sztuczka z haszowaniem polega na tym, \u017ce zamiast numerowa\u0107 s\u0142owa korzystaj\u0105c ze s\u0142ownika, po prostu u\u017cywamy funkcji haszuj\u0105cej. W ten spos\u00f3b wektor b\u0119dzie _zawsze_ rozmiar $2^b$ - bez wzgl\u0119du na rozmiar s\u0142ownika."
|
||||
"Sztuczka z haszowaniem polega na tym, że zamiast numerować słowa korzystając ze słownika, po prostu używamy funkcji haszującej. W ten sposób wektor będzie _zawsze_ rozmiar $2^b$ - bez względu na rozmiar słownika."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zacznijmy od przywo\u0142ania wszystkich potrzebnych definicji."
|
||||
"Zacznijmy od przywołania wszystkich potrzebnych definicji."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -256,8 +254,8 @@
|
||||
"isStopWord :: Text -> Bool\n",
|
||||
"isStopWord \"w\" = True\n",
|
||||
"isStopWord \"jest\" = True\n",
|
||||
"isStopWord \"\u017ce\" = True\n",
|
||||
"isStopWord w = w \u2248 [re|^\\p{P}+$|]\n",
|
||||
"isStopWord \"że\" = True\n",
|
||||
"isStopWord w = w ≈ [re|^\\p{P}+$|]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"removeStopWords :: [Text] -> [Text]\n",
|
||||
@ -288,10 +286,10 @@
|
||||
"mockInflectionDictionary = Map.fromList [\n",
|
||||
" (\"kota\", \"kot\"),\n",
|
||||
" (\"butach\", \"but\"),\n",
|
||||
" (\"masz\", \"mie\u0107\"),\n",
|
||||
" (\"ma\", \"mie\u0107\"),\n",
|
||||
" (\"masz\", \"mieć\"),\n",
|
||||
" (\"ma\", \"mieć\"),\n",
|
||||
" (\"buta\", \"but\"),\n",
|
||||
" (\"zgubi\u0142em\", \"zgubi\u0107\")]\n",
|
||||
" (\"zgubiłem\", \"zgubić\")]\n",
|
||||
"\n",
|
||||
"lemmatizeWord :: Map Text Text -> Text -> Text\n",
|
||||
"lemmatizeWord dict w = findWithDefault w w dict\n",
|
||||
@ -523,10 +521,10 @@
|
||||
" where n = vectorNorm vs\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"(\u2715) :: [Double] -> [Double] -> Double\n",
|
||||
"(\u2715) v1 v2 = sum $ Prelude.zipWith (*) v1 v2\n",
|
||||
"(✕) :: [Double] -> [Double] -> Double\n",
|
||||
"(✕) v1 v2 = sum $ Prelude.zipWith (*) v1 v2\n",
|
||||
"\n",
|
||||
"cosineSim v1 v2 = toUnitVector v1 \u2715 toUnitVector v2\n",
|
||||
"cosineSim v1 v2 = toUnitVector v1 ✕ toUnitVector v2\n",
|
||||
"\n",
|
||||
"paintMatrix cosineSim labelsLimited limitedL"
|
||||
]
|
||||
@ -535,9 +533,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Powy\u017csza macierz reprezentuje por\u00f3wnanie przy u\u017cyciu podobie\u0144stwa kosinusowego. Spr\u00f3bujmy teraz u\u017cy\u0107 g\u0119stszych wektor\u00f3w przy u\u017cyciu hashing trick. Jako warto\u015b\u0107 $b$ przyjmijmy 6.\n",
|
||||
"Powyższa macierz reprezentuje porównanie przy użyciu podobieństwa kosinusowego. Spróbujmy teraz użyć gęstszych wektorów przy użyciu hashing trick. Jako wartość $b$ przyjmijmy 6.\n",
|
||||
"\n",
|
||||
"Zobaczmy najpierw, w kt\u00f3re \"przegr\u00f3dki\" b\u0119d\u0105 wpada\u0142y poszczeg\u00f3lne wyrazy s\u0142ownika.\n",
|
||||
"Zobaczmy najpierw, w które \"przegródki\" będą wpadały poszczególne wyrazy słownika.\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
@ -565,18 +563,18 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Pytanie:** Czy jakie\u015b dwa termy wpad\u0142y do jednej przegr\u00f3dki?"
|
||||
"**Pytanie:** Czy jakieś dwa termy wpadły do jednej przegródki?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Stw\u00f3rzmy najpierw funkcj\u0119, kt\u00f3ra b\u0119dzie wektoryzowa\u0142a pojedynczy term $t$. Po prostu stworzymy wektor, kt\u00f3re b\u0119dzie mia\u0142 rozmiar $2^b$, wsz\u0119dzie b\u0119dzie mia\u0142 0 z wyj\u0105tkiem pozycji o numerze $H_b(t)$ - tam wpiszmy odwrotn\u0105 cz\u0119sto\u015b\u0107 dokumentow\u0105.\n",
|
||||
"Stwórzmy najpierw funkcję, która będzie wektoryzowała pojedynczy term $t$. Po prostu stworzymy wektor, które będzie miał rozmiar $2^b$, wszędzie będzie miał 0 z wyjątkiem pozycji o numerze $H_b(t)$ - tam wpiszmy odwrotną częstość dokumentową.\n",
|
||||
"\n",
|
||||
"$$\\vec{t} = [0,\\dots,\\idf_c t,\\dots,0]$$\n",
|
||||
"\n",
|
||||
"Teraz dla dokumentu $d = (t_1,\\dots,t_n)$ i dla schematu wa\u017cenia tf-idf:\n",
|
||||
"Teraz dla dokumentu $d = (t_1,\\dots,t_n)$ i dla schematu ważenia tf-idf:\n",
|
||||
"\n",
|
||||
"$$\\vec{d} = \\sum \\vec{t_i}$$"
|
||||
]
|
||||
@ -632,7 +630,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Teraz wystarczy zsumowa\u0107 wektory dla poszczeg\u00f3lnych s\u0142\u00f3w, \u017ceby otrzyma\u0107 wektor dokumentu. Najpierw zdefiniujmy sobie sum\u0119 wektorow\u0105."
|
||||
"Teraz wystarczy zsumować wektory dla poszczególnych słów, żeby otrzymać wektor dokumentu. Najpierw zdefiniujmy sobie sumę wektorową."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -661,7 +659,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Przydatna b\u0119dzie jeszcze funkcja, kt\u00f3ra tworzy wektor z samymi zerami o zadanej d\u0142ugo\u015bci:"
|
||||
"Przydatna będzie jeszcze funkcja, która tworzy wektor z samymi zerami o zadanej długości:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -854,7 +852,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zobaczmy, jak zag\u0119szczenie wp\u0142ywa na macierz podobie\u0144stwa."
|
||||
"Zobaczmy, jak zagęszczenie wpływa na macierz podobieństwa."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -896,19 +894,19 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Pytanie:** Co si\u0119 stanie, gdy zwi\u0119kszymy $b$, a co je\u015bli zmniejszymi?\n",
|
||||
"**Pytanie:** Co się stanie, gdy zwiększymy $b$, a co jeśli zmniejszymi?\n",
|
||||
"\n",
|
||||
"Zalety sztuczki z haszowaniem:\n",
|
||||
"\n",
|
||||
"* zagwarantowany sta\u0142y rozmiar wektora\n",
|
||||
"* zagwarantowany stały rozmiar wektora\n",
|
||||
"* szybsze obliczenia\n",
|
||||
"* w naturalny spos\u00f3b uwzgl\u0119dniamy termy, kt\u00f3rych nie by\u0142o w pocz\u0105tkowej kolekcji (ale uwaga na idf!)\n",
|
||||
"* nie musimy pami\u0119ta\u0107 odzworowania rzutuj\u0105cego s\u0142owa na ich numery\n",
|
||||
"* w naturalny sposób uwzględniamy termy, których nie było w początkowej kolekcji (ale uwaga na idf!)\n",
|
||||
"* nie musimy pamiętać odzworowania rzutującego słowa na ich numery\n",
|
||||
"\n",
|
||||
"Wady:\n",
|
||||
"\n",
|
||||
"* dwa r\u00f3\u017cne s\u0142owa mog\u0105 wpa\u015b\u0107 do jednej przegr\u00f3dki (szczeg\u00f3lnie cz\u0119ste, je\u015bli $b$ jest za ma\u0142e)\n",
|
||||
"* je\u015bli $b$ ustawimy za du\u017ce, wektory mog\u0105 by\u0107 nawet wi\u0119ksze ni\u017c w przypadku standardowego podej\u015bcia\n",
|
||||
"* dwa różne słowa mogą wpaść do jednej przegródki (szczególnie częste, jeśli $b$ jest za małe)\n",
|
||||
"* jeśli $b$ ustawimy za duże, wektory mogą być nawet większe niż w przypadku standardowego podejścia\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
@ -921,11 +919,11 @@
|
||||
"source": [
|
||||
"## Word2vec\n",
|
||||
"\n",
|
||||
"A mo\u017ce istnieje dobra wr\u00f3\u017cka, kt\u00f3ra da\u0142aby nam dobre wektory s\u0142\u00f3w (z kt\u00f3rych b\u0119dziemy sk\u0142adali proste wektory dokument\u00f3w przez sumowanie)?\n",
|
||||
"A może istnieje dobra wróżka, która dałaby nam dobre wektory słów (z których będziemy składali proste wektory dokumentów przez sumowanie)?\n",
|
||||
"\n",
|
||||
"**Pytanie:** Jakie w\u0142asno\u015bci powinny mie\u0107 dobre wektory s\u0142\u00f3w?\n",
|
||||
"**Pytanie:** Jakie własności powinny mieć dobre wektory słów?\n",
|
||||
"\n",
|
||||
"Tak! Istniej\u0105 gotowe \"bazy danych\" wektor\u00f3w. Jedn\u0105 z najpopularniejszych (i najstarszych) metod uzyskiwania takich wektor\u00f3w jest Word2vec. Jak dok\u0142adnie Word2vec, dowiemy si\u0119 p\u00f3\u017aniej, na dzisiaj po prostu u\u017cyjmy tych wektor\u00f3w.\n",
|
||||
"Tak! Istnieją gotowe \"bazy danych\" wektorów. Jedną z najpopularniejszych (i najstarszych) metod uzyskiwania takich wektorów jest Word2vec. Jak dokładnie Word2vec, dowiemy się później, na dzisiaj po prostu użyjmy tych wektorów.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
@ -943,7 +941,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Najpierw wprowad\u017amy alternatywn\u0105 normalizacj\u0119 zgodn\u0105 z tym, jak zosta\u0142 wygenerowany model."
|
||||
"Najpierw wprowadźmy alternatywną normalizację zgodną z tym, jak został wygenerowany model."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1331,7 +1329,7 @@
|
||||
"toOurVector :: WVector -> [Double]\n",
|
||||
"toOurVector (WVector v _) = map realToFrac $ V.toList v\n",
|
||||
"\n",
|
||||
"balwanV = toOurVector $ fromJust $ getVector model \"ba\u0142wan\"\n",
|
||||
"balwanV = toOurVector $ fromJust $ getVector model \"bałwan\"\n",
|
||||
"balwanV\n",
|
||||
"Prelude.length balwanV\n",
|
||||
"\n",
|
||||
@ -1397,7 +1395,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Mo\u017cemy pr\u00f3bowa\u0107 mno\u017cy\u0107 wektory z modelu Word2vec z idf. Najpierw zdefiniujmy mno\u017cenie przez skalar."
|
||||
"Możemy próbować mnożyć wektory z modelu Word2vec z idf. Najpierw zdefiniujmy mnożenie przez skalar."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1426,7 +1424,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Teraz b\u0119dziemy przemna\u017cali wektory Word2vec przez idf (jako skalar)."
|
||||
"Teraz będziemy przemnażali wektory Word2vec przez idf (jako skalar)."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1620,11 +1618,14 @@
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"author": "Filip Graliński",
|
||||
"email": "filipg@amu.edu.pl",
|
||||
"kernelspec": {
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"lang": "pl",
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
@ -1633,10 +1634,7 @@
|
||||
"pygments_lexer": "Haskell",
|
||||
"version": "8.10.4"
|
||||
},
|
||||
"author": "Filip Grali\u0144ski",
|
||||
"email": "filipg@amu.edu.pl",
|
||||
"lang": "pl",
|
||||
"subtitle": "5.G\u0119ste reprezentacje wektorowe[wyk\u0142ad]",
|
||||
"subtitle": "5.Gęste reprezentacje wektorowe[wykład]",
|
||||
"title": "Ekstrakcja informacji",
|
||||
"year": "2021"
|
||||
},
|
||||
|
@ -24,7 +24,7 @@
|
||||
"\n",
|
||||
"Zakładamy, że mamy dwie klasy: $c$ i jej dopełnienie ($\\bar{c}$).\n",
|
||||
"\n",
|
||||
"Typowym przykładem jest zadanie klasyfikacji mejla, czy należy do spamu, czy nie (_spam_ vs _ham_), czyli innymi słowy filtr antyspamowy."
|
||||
"Typowym przykładem jest zadanie klasyfikacji mejla, czy należy do spamu, czy nie (_spam_ vs _ham_), czyli, innymi słowy, filtr antyspamowy."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -78,9 +78,9 @@
|
||||
"\n",
|
||||
"W klasyfikacji (i w ogóle w uczeniu nadzorowanym) można wskazać dwa podejścia:\n",
|
||||
"\n",
|
||||
"* generatywne - wymyślamy pewną \"historyjkę\", w jaki sposób powstaje tekst, \"historyjka\" powinna mieć miejsca do wypełnienia (parametry), np. częstości wyrazów, na podstawie zbioru uczącego dobieramy wartości parametrów (przez rachunki wprost); \"historyjka\" nie musi być prawdziwa, wystarczy, że jakoś przybliża rzeczywistość\n",
|
||||
"* generatywne — wymyślamy pewną „historyjkę”, w jaki sposób powstaje tekst, „historyjka” powinna mieć miejsca do wypełnienia (parametry), np. częstości wyrazów, na podstawie zbioru uczącego dobieramy wartości parametrów (przez rachunki wprost); „historyjka” nie musi być prawdziwa, wystarczy, że jakoś przybliża rzeczywistość\n",
|
||||
"\n",
|
||||
"* dyskryminatywne - nie zastanawiamy się, w jaki sposób powstają teksty, po prostu \"na siłę\" dobieramy wartości parametrów (wag) modelu, tak aby uzyskać jak najmniejszą wartość funkcji kosztu na zbiorze uczącym; zwykle odbywa się to w iteracyjnym procesie (tak jak przedstawiono na schemacie na poprzednim wykładzie).\n",
|
||||
"* dyskryminatywne — nie zastanawiamy się, w jaki sposób powstają teksty, po prostu „na siłę” dobieramy wartości parametrów (wag) modelu, tak aby uzyskać jak najmniejszą wartość funkcji kosztu na zbiorze uczącym; zwykle odbywa się to w iteracyjnym procesie (tak jak przedstawiono na schemacie na poprzednim wykładzie).\n",
|
||||
"\n",
|
||||
"**Pytanie**: Jakie są wady i zalety obu podejść?"
|
||||
]
|
||||
@ -146,11 +146,11 @@
|
||||
"source": [
|
||||
"## Naiwny klasyfikator bayesowski\n",
|
||||
"\n",
|
||||
"* _naiwny_ - niekoniecznie oznacza, że to \"głupi\", bezużyteczny klasyfikator\n",
|
||||
"* _naiwny_— niekoniecznie oznacza, że to „głupi”, bezużyteczny klasyfikator\n",
|
||||
"* _klasyfikator_ \n",
|
||||
"* _bayesowski_ - będzie odwoływać się do wzoru Bayesa.\n",
|
||||
"* _bayesowski_ — będzie odwoływać się do wzoru Bayesa.\n",
|
||||
"\n",
|
||||
"Naiwny klasyfikator bayesowski raczej nie powinien być stosowany \"produkcyjnie\" (są lepsze metody). Natomiast jest to metoda bardzo prosta w implementacji dająca przyzwoity _baseline_.\n",
|
||||
"Naiwny klasyfikator bayesowski raczej nie powinien być stosowany „produkcyjnie” (są lepsze metody). Natomiast jest to metoda bardzo prosta w implementacji dająca przyzwoity _baseline_.\n",
|
||||
"\n",
|
||||
"Naiwny klasyfikator bayesowski ma dwie odmiany:\n",
|
||||
"\n",
|
||||
@ -221,14 +221,14 @@
|
||||
"source": [
|
||||
"#### Prawdopodobieństwo _a priori_\n",
|
||||
"\n",
|
||||
"$P(c)$ - prawdopodobieństwo a priori klasy $c$\n",
|
||||
"$P(c)$ — prawdopodobieństwo a priori klasy $c$\n",
|
||||
"\n",
|
||||
"$\\hat{P}(c) = \\frac{N_c}{N}$\n",
|
||||
"\n",
|
||||
"gdzie\n",
|
||||
"\n",
|
||||
"* N - liczba wszystkich dokumentów w zbiorze uczącym\n",
|
||||
"* N_c - liczba dokumentow w zbiorze uczącym z klasą $c$\n",
|
||||
"* N — liczba wszystkich dokumentów w zbiorze uczącym\n",
|
||||
"* N_c — liczba dokumentow w zbiorze uczącym z klasą $c$\n",
|
||||
"\n",
|
||||
"$\\hat{P}(c) = 0,75$\n",
|
||||
"\n",
|
||||
@ -256,11 +256,11 @@
|
||||
"source": [
|
||||
"$P(d|c) = P(t_1\\dots t_n|c)$\n",
|
||||
"\n",
|
||||
"Żeby pójść dalej musimy doszczegółowić nasz model generatywny. Przyjmijmy bardzo naiwny i niezgodny z rzeczywistością model spamera (i nie-spamera): spamer wyciąga wyrazy z worka i wrzuca je z powrotem (losowanie ze zwracaniem). Jedyne co odróżnia spamera i nie-spamera, to **prawdopodobieństwo wylosowania wyrazu** (np. spamer wylosuje słowo _Viagra_ z dość dużym prawdopodobieństwem, nie-spamer - z bardzo niskim).\n",
|
||||
"Aby pójść dalej, musimy doszczegółowić nasz model generatywny. Przyjmijmy bardzo naiwny i niezgodny z rzeczywistością model spamera (i nie-spamera): spamer wyciąga wyrazy z worka i wrzuca je z powrotem (losowanie ze zwracaniem). Jedyne co odróżnia spamera i nie-spamera, to **prawdopodobieństwo wylosowania wyrazu** (np. spamer wylosuje słowo _Viagra_ z dość dużym prawdopodobieństwem, nie-spamer — z bardzo niskim).\n",
|
||||
"\n",
|
||||
"**Pytanie:** Ile może wynosić $P(\\mathit{Viagra}|c)$?\n",
|
||||
"\n",
|
||||
"Po przyjęciu takich \"naiwnych założeń\":\n",
|
||||
"Po przyjęciu takich „naiwnych założeń”:\n",
|
||||
"\n",
|
||||
"$$P(d|c) = P(t_1\\dots t_n|c) \\approx P(t_1|c)\\dots P(t_n|c) = \\prod_i^n P(t_i|c)$$"
|
||||
]
|
||||
@ -306,7 +306,7 @@
|
||||
"\n",
|
||||
"$$f(m, k, T) = \\frac{k+1}{T+m}$$\n",
|
||||
"\n",
|
||||
"Jest to wygładzanie +1, albo wygładzanie Laplace'a.\n",
|
||||
"Jest to wygładzanie +1, inaczej wygładzanie Laplace'a.\n",
|
||||
"\n",
|
||||
"**Pytanie:** Wymyślić jakiś inny przykład funkcji, która będzie spełniała aksjomaty.\n",
|
||||
"\n",
|
||||
|
@ -144,7 +144,10 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "freelance-controversy",
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"jp-MarkdownHeadingCollapsed": true,
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Uczenie\n",
|
||||
"\n",
|
||||
@ -154,13 +157,11 @@
|
||||
"\n",
|
||||
"### Metoda gradientu prostego\n",
|
||||
"\n",
|
||||
"![Morskie Oko - Krzysztof Dudzik](08_files/morskieoko.jpg)\n",
|
||||
"\n",
|
||||
"(Źródło: https://pl.wikipedia.org/wiki/Morskie_Oko#/media/Plik:Morskie_Oko_ze_szlaku_przez_%C5%9Awist%C3%B3wk%C4%99.jpg, licencja CC BY 3.0)\n",
|
||||
"![Morskie oko; Autor:Krzysztof Dudzik; Źródło: [https://pl.wikipedia.org/wiki/Morskie_Oko#/media/Plik:Morskie_Oko_ze_szlaku_przez_%C5%9Awist%C3%B3wk%C4%99.jpg](https://pl.wikipedia.org/wiki/Morskie_Oko#/media/Plik:Morskie_Oko_ze_szlaku_przez_%C5%9Awist%C3%B3wk%C4%99.jpg); Licencja: CC-BY 3.0](08_files/morskieoko.jpg)\n",
|
||||
"\n",
|
||||
"Schodź wzdłuż lokalnego spadku funkcji błędu.\n",
|
||||
"\n",
|
||||
"Tak więc w praktyce zamiast podstawiać do wzoru lepiej się uczyć iteracyjnie -\n",
|
||||
"Tak więc w praktyce zamiast podstawiać do wzoru lepiej się uczyć iteracyjnie —\n",
|
||||
" metodą **gradientu prostego** (ang. _gradient descent_).\n",
|
||||
"\n",
|
||||
"1. Zacznij od byle jakich wag $w_i$ (np. wylosuj)\n",
|
||||
@ -209,7 +210,7 @@
|
||||
"\n",
|
||||
"Czym jest wektor $\\vec{x} = (x_1,\\dots,x_n)$? Wiemy, np. reprezentacja tf-idf (być z trikiem z haszowaniem, Word2vec etc.).\n",
|
||||
"\n",
|
||||
"![schemat regresji liniowej](08_files/regresja-liniowa-tekst.png)\n"
|
||||
"![Schemat regresji liniowej tekstu](08_files/regresja-liniowa-tekst.png)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Kilka uwag dotyczących wektorów\n",
|
||||
"## Kilka uwag dotyczących wektorów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -78,7 +78,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Funkcja sigmoidalna\n",
|
||||
"## Funkcja sigmoidalna\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -86,7 +86,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Funkcja sigmoidalna zamienia dowolną wartość („sygnał”) w wartość z przedziału $(0,1)$, czyli wartość, która może być interperetowana jako prawdopodobieństwo.\n",
|
||||
"Funkcja sigmoidalna zamienia dowolną wartość („sygnał”) w wartość z przedziału $(0,1)$, czyli wartość, która może być interpretowana jako prawdopodobieństwo.\n",
|
||||
"\n",
|
||||
"$$\\sigma(x) = \\frac{1}{1 + e^{-x}}$$\n",
|
||||
"\n"
|
||||
@ -175,7 +175,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### PyTorch\n",
|
||||
"### PyTorch\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -283,7 +283,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Wagi\n",
|
||||
"### Wagi\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -307,7 +307,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Regresja liniowa\n",
|
||||
"## Regresja liniowa\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -526,27 +526,25 @@
|
||||
"Bezpośrednio możemy zastosować do zadania regresji dla tekstu (np.\n",
|
||||
"przewidywanie roku publikacji tekstu).\n",
|
||||
"\n",
|
||||
"![img](./img-linear-regression.png)\n",
|
||||
"![Schemat regresji logistycznej dla tekstu](./img-linear-regression.png)\n",
|
||||
"\n",
|
||||
"W połączeniu z sigmoidą otrzymamy regresją logistyczną, np. dla zadania klasyfikacji tekstu:\n",
|
||||
"\n",
|
||||
"$$p(c|\\vec{x}) = \\sigma(w_0 + w_1x_1 + w_2x_2 + \\dots + w_{|V|}x_{|v})\n",
|
||||
"= \\sigma(\\Sigma_{i=0}^{|V|} w_ix_i) = \\sigma(\\vec{w}\\vec{x})$$\n",
|
||||
"\n",
|
||||
"![img](./img-logistic-regression.png)\n",
|
||||
"\n",
|
||||
"Tak sieć będzie aktywowana dla tekstu <u>aardvark in Aachen</u>:\n",
|
||||
"\n",
|
||||
"![img](./img-logistic-regression-aardvark.png)\n",
|
||||
"![Schemat regresji logistycznej dla przykładowego tekstu](./img-logistic-regression-aardvark.png)\n",
|
||||
"\n",
|
||||
"Regresje logistyczną (liniową zresztą też) dla tekstu możemy połączyć z trikiem z haszowaniem:\n",
|
||||
"Regresję logistyczną (liniową zresztą też) dla tekstu możemy połączyć z trikiem z haszowaniem:\n",
|
||||
"\n",
|
||||
"$$p(c|\\vec{x}) = \\sigma(w_0 + w_1x_1 + w_2x_2 + \\dots + w_{2^b}x_{2^b})\n",
|
||||
"= \\sigma(\\Sigma_{i=0}^{2^b} w_ix_i) = \\sigma(\\vec{w}\\vec{x})$$ \n",
|
||||
"{\\small hashing function $H : V \\rightarrow \\{1,\\dots,2^b\\}$,\n",
|
||||
" e.g. MurmurHash3}\n",
|
||||
"\n",
|
||||
"![img](./img-logistic-regression-hashing.png)\n",
|
||||
"![Schemat regresji logistycznej dla tekstu z zastosowaniem hashing trick](./img-logistic-regression-hashing.png)\n",
|
||||
"\n",
|
||||
"****Pytanie:**** Jaki tekst otrzyma na pewno taką samą klasę jak <u>aardvark in Aachen</u>?\n",
|
||||
"\n"
|
||||
@ -595,16 +593,16 @@
|
||||
"Mnożenie macierzy przez wektor można interpretować jako zrównolegloną operację mnożenie wektora przez wektor.\n",
|
||||
"\n",
|
||||
"$$\\left[\\begin{array}{ccc}\n",
|
||||
" \\alert<2>{1.0} & \\alert<2>{-2.0} & \\alert<2>{3.0} \\\\\n",
|
||||
" \\alert<3>{-2.0} & \\alert<3>{0.0} & \\alert<3>{10.0}\\end{array}\\right]\n",
|
||||
" 1.0 & -2.0 & 3.0 \\\\\n",
|
||||
" -2.0 & 0.0 & 10.0\\end{array}\\right]\n",
|
||||
" \\left[\\begin{array}{c}\n",
|
||||
" \\alert<2-3>{1.0} \\\\\n",
|
||||
" \\alert<2-3>{-0.5} \\\\\n",
|
||||
" \\alert<2-3>{2.0}\\end{array}\\right]\n",
|
||||
" 1.0 \\\\\n",
|
||||
" -0.5 \\\\\n",
|
||||
" 2.0\\end{array}\\right]\n",
|
||||
" =\n",
|
||||
" \\left[\\begin{array}{c}\n",
|
||||
" \\uncover<2->{\\alert<2>{8.0}} \\\\\n",
|
||||
" \\uncover<3->{\\alert<3>{18.0}}\\end{array}\\right]$$\n",
|
||||
" 8.0 \\\\\n",
|
||||
" 8.0\\end{array}\\right]$$\n",
|
||||
"\n",
|
||||
"Jeśli przemnożymy macierz $n \\times m$ przez wektor kolumnowy o długości\n",
|
||||
"$m$, otrzymamy wektor o rozmiarze $n$.\n",
|
||||
@ -660,7 +658,7 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Warstwa liniowa polega na przemnożeniu wejścia przez macierz. Można\n",
|
||||
"to intepretować jako zrównolegloną operację regresji liniowej (równolegle\n",
|
||||
"to interpretować jako zrównolegloną operację regresji liniowej (równolegle\n",
|
||||
"uczymy czy wykonujemy $n$ regresji liniowych).\n",
|
||||
"\n"
|
||||
]
|
||||
@ -731,7 +729,7 @@
|
||||
"\n",
|
||||
"Oto przykład prostej dwuwarstwowej sieci neuronowej do klasyfikacji binarnej.\n",
|
||||
"\n",
|
||||
"![img](./img-feed-forward.png)\n",
|
||||
"![Schemat dwuwarstwowej sieci neuronowej do klasyfikacji binarnej tekstu](./img-feed-forward.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -747,7 +745,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"W klasyfikacji wieloklasowej należy zwrócić musimy zwrócić rozkład\n",
|
||||
"W klasyfikacji wieloklasowej należy zwrócić rozkład\n",
|
||||
"prawdopodobieństwa po wszystkich klasach, w przeciwieństwie do\n",
|
||||
"klasyfikacji binarnej, gdzie wystarczy zwrócić jedną liczbę —\n",
|
||||
"prawdopodobieństwo pozytywnej klasy ($p$; prawdopodobieństwo drugiej\n",
|
||||
@ -770,7 +768,7 @@
|
||||
"$$s(z_i) = \\frac{z_i}{\\Sigma_{j=1}^k z_j}$$\n",
|
||||
"\n",
|
||||
"To rozwiązanie zadziała błędnie dla liczb ujemnych, trzeba najpierw\n",
|
||||
"użyć funkcji monotonicznej, która przekształaca $\\mathcal{R}$ na $\\mathcal{R^+}$.\n",
|
||||
"użyć funkcji monotonicznej, która przekształca $\\mathcal{R}$ na $\\mathcal{R^+}$.\n",
|
||||
"Naturalna funkcja tego rodzaju to funkcja wykładnicza $\\exp{x} = e^x$.\n",
|
||||
"Tym sposobem dochodzimy do funkcji softmax:\n",
|
||||
"\n",
|
||||
@ -815,7 +813,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![img](./softmax.png \"Softmax\")\n",
|
||||
"![Schemat funkcji Softmax](./softmax.png \"Softmax\")\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -1238,7 +1236,7 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ze względów obliczeniowych często korzysta się z funkcji **LogSoftmax**\n",
|
||||
"która zwraca logarytmy pradopodobieństw (*logproby*).\n",
|
||||
"która zwraca logarytmy prawdopodobieństw (*logproby*).\n",
|
||||
"\n",
|
||||
"$$log s(z_i) = log \\frac{e^{z_i}}{\\Sigma_{j=1}^k e^{z_j}}$$\n",
|
||||
"\n"
|
||||
@ -1776,7 +1774,7 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"W czasie inferencji mamy ustalone wagi funkcji $\\vec{v}(\\dots)$ oraz\n",
|
||||
"macierz $V$. Szukamy sekwencji $y$ która maksymalizuje prawdopodobieństwo estymowane przez model:\n",
|
||||
"macierz $V$. Szukamy sekwencji $y$, która maksymalizuje prawdopodobieństwo estymowane przez model:\n",
|
||||
"\n",
|
||||
"$$y = \\underset{l}{\\operatorname{argmax}} \\hat{p}(l|t^1,\\dots,t^K)$$\n",
|
||||
"\n",
|
||||
@ -1819,7 +1817,7 @@
|
||||
"\n",
|
||||
"$$y^i = b[i, y^{i+1}]$$\n",
|
||||
"\n",
|
||||
"![img](./crf-viterbi.png)\n",
|
||||
"![CRF - Algorytm Viterbiego](./crf-viterbi.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
|
@ -34,7 +34,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Regresja liniowa/logistyczna lub klasyfikacja wieloklasowa na całym tekście\n",
|
||||
"### Regresja liniowa/logistyczna lub klasyfikacja wieloklasowa na całym tekście\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -179,7 +179,7 @@
|
||||
"\n",
|
||||
"Taką sieć RNN można przedstawić schematycznie w następujący sposób:\n",
|
||||
"\n",
|
||||
"![img](./img-rnn.png)\n",
|
||||
"![Pojedynczy krok sieci rekurencyjnej](./img-rnn.png)\n",
|
||||
"\n",
|
||||
"Zauważmy, że zamiast macierzy $W$ działającej na konkatenacji wektorów można wprowadzić dwie\n",
|
||||
"macierze $U$ i $V$ i tak zapisać wzór:\n",
|
||||
@ -188,12 +188,12 @@
|
||||
"\n",
|
||||
"Jeszcze inne spojrzenie na sieć RNN:\n",
|
||||
"\n",
|
||||
"![img](./rnn.png)\n",
|
||||
"![Pojedynczy krok sieci rekurencyjnej II](./rnn.png)\n",
|
||||
"\n",
|
||||
"Powyższy rysunek przedstawia pojedynczy krok sieci RNN. Dla całego\n",
|
||||
"wejścia (powiedzmy, 3-wyrazowego) możemy sieć rozwinąć (*unroll*):\n",
|
||||
"\n",
|
||||
"![img](./rnn-seq.png)\n",
|
||||
"![Rozwinięta sieć rekurencyjna](./rnn-seq.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -202,7 +202,8 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Zastosowanie sieci RNN do etykietowania sekwencji\n",
|
||||
"\n"
|
||||
"\n",
|
||||
"Sieć RNN może w prosty sposób być użyta do etykietowania sekwencji (w każdym kroku zwracamy etykietę)."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -228,7 +229,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Sieci RNN z bramkami\n",
|
||||
"## Sieci RNN z bramkami\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
|
@ -507,7 +507,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### BPE\n",
|
||||
"## BPE\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -532,7 +532,7 @@
|
||||
"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",
|
||||
"![Sekwencja kroków algorytmu BPE dla przykładowego zdania](./bpe.png)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
|
@ -36,11 +36,11 @@
|
||||
"source": [
|
||||
"Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje.\n",
|
||||
"\n",
|
||||
"![img](./ie-seqlab.png)\n",
|
||||
"![Ekstrakcja informacji jako etykietowanie sekwencji, schemat](./ie-seqlab.png)\n",
|
||||
"\n",
|
||||
"Możliwe jest inne podeście, **generatywne**, w którym podchodzimy do problemu ekstrakcji informacji jak do swego rodzaju **tłumaczenia maszynowego** — „tłumaczymy” tekst (wraz z pytaniem lub etykietą) na informację.\n",
|
||||
"\n",
|
||||
"![img](./ie-gener.png)\n",
|
||||
"![Ekstrakcja informacji w podejściu generatywnym](./ie-gener.png)\n",
|
||||
"\n",
|
||||
"To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n",
|
||||
"\n",
|
||||
@ -56,7 +56,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Atencja\n",
|
||||
"## Atencja\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
|
@ -2,15 +2,13 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"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> Ekstrakcja informacji </h1>\n",
|
||||
"<h2> 14. <i>Pretrenowane modele j\u0119zyka</i> [wyk\u0142ad]</h2> \n",
|
||||
"<h3> Filip Grali\u0144ski (2021)</h3>\n",
|
||||
"<h2> 14. <i>Pretrenowane modele języka</i> [wykład]</h2> \n",
|
||||
"<h3> Filip Graliński (2021)</h3>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
|
||||
@ -28,27 +26,27 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"System AlphaZero uczy si\u0119 graj\u0105c sam ze sob\u0105 \u2014 wystarczy 24 godziny,\n",
|
||||
"by system nauczy\u0142 si\u0119 gra\u0107 w szachy lub go na nadludzkim poziomie.\n",
|
||||
"System AlphaZero uczy się grając sam ze sobą — wystarczy 24 godziny,\n",
|
||||
"by system nauczył się grać w szachy lub go na nadludzkim poziomie.\n",
|
||||
"\n",
|
||||
"**Pytanie**: Dlaczego granie samemu ze sob\u0105 nie jest dobrym sposobem\n",
|
||||
" nauczenia si\u0119 grania w szachy dla cz\u0142owieka, a dla maszyny jest?\n",
|
||||
"**Pytanie**: Dlaczego granie samemu ze sobą nie jest dobrym sposobem\n",
|
||||
" nauczenia się grania w szachy dla człowieka, a dla maszyny jest?\n",
|
||||
"\n",
|
||||
"Co jest odpowiednikiem grania samemu ze sob\u0105 w \u015bwiecie przetwarzania tekstu?\n",
|
||||
"Tzn. **pretrenowanie** (*pretraining*) na du\u017cym korpusie tekstu. (Tekst jest tani!)\n",
|
||||
"Co jest odpowiednikiem grania samemu ze sobą w świecie przetwarzania tekstu?\n",
|
||||
"Tzn. **pretrenowanie** (*pretraining*) na dużym korpusie tekstu. (Tekst jest tani!)\n",
|
||||
"\n",
|
||||
"Jest kilka sposob\u00f3w na pretrenowanie modelu, w ka\u017cdym razie sprowadza\n",
|
||||
"si\u0119 do odgadywania nast\u0119pnego b\u0105d\u017a zamaskowanego s\u0142owa.\n",
|
||||
"W ka\u017cdym razie zawsze stosujemy softmax (by\u0107 mo\u017ce ze \u201esztuczkami\u201d takimi jak\n",
|
||||
"negatywne pr\u00f3bkowanie albo hierarchiczny softmax) na pewnej **reprezentacji kontekstowej**:\n",
|
||||
"Jest kilka sposobów na pretrenowanie modelu, w każdym razie sprowadza\n",
|
||||
"się do odgadywania następnego bądź zamaskowanego słowa.\n",
|
||||
"W każdym razie zawsze stosujemy softmax (być może ze „sztuczkami” takimi jak\n",
|
||||
"negatywne próbkowanie albo hierarchiczny softmax) na pewnej **reprezentacji kontekstowej**:\n",
|
||||
"\n",
|
||||
"$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n",
|
||||
"\n",
|
||||
"Model jest karany u\u017cywaj\u0105c funkcji log loss:\n",
|
||||
"Model jest karany przy użyciu funkcji log loss:\n",
|
||||
"\n",
|
||||
"$$-\\log(p_j),$$\n",
|
||||
"\n",
|
||||
"gdzie $w_j$ jest wyrazem, kt\u00f3ry pojawi\u0142 si\u0119 rzeczywi\u015bcie w korpusie.\n",
|
||||
"gdzie $w_j$ jest wyrazem, który pojawił się rzeczywiście w korpusie.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -56,7 +54,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Przewidywanie s\u0142owa (GPT-2)\n",
|
||||
"## Przewidywanie słowa (GPT-2)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -64,10 +62,10 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Jeden ze sposob\u00f3w pretrenowania modelu to po prostu przewidywanie\n",
|
||||
"nast\u0119pnego s\u0142owa.\n",
|
||||
"Jeden ze sposobów pretrenowania modelu to po prostu przewidywanie\n",
|
||||
"następnego słowa.\n",
|
||||
"\n",
|
||||
"Zainstalujmy najpierw bibliotek\u0119 transformers.\n",
|
||||
"Zainstalujmy najpierw bibliotekę transformers.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -95,36 +93,36 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[('\u00c2\u0142', 0.6182783842086792),\n",
|
||||
" ('\u00c8', 0.1154019758105278),\n",
|
||||
" ('\u00d1\u0123', 0.026960616931319237),\n",
|
||||
"[('Âł', 0.6182783842086792),\n",
|
||||
" ('È', 0.1154019758105278),\n",
|
||||
" ('Ñģ', 0.026960616931319237),\n",
|
||||
" ('_____', 0.024418892338871956),\n",
|
||||
" ('________', 0.014962316490709782),\n",
|
||||
" ('\u00c3\u0124', 0.010653386823832989),\n",
|
||||
" ('\u00e4\u00b8\u0143', 0.008340531960129738),\n",
|
||||
" ('\u00d1', 0.007557711564004421),\n",
|
||||
" ('\u00ca', 0.007046067621558905),\n",
|
||||
" ('\u00e3\u0122', 0.006875576451420784),\n",
|
||||
" ('ÃĤ', 0.010653386823832989),\n",
|
||||
" ('ä¸Ń', 0.008340531960129738),\n",
|
||||
" ('Ñ', 0.007557711564004421),\n",
|
||||
" ('Ê', 0.007046067621558905),\n",
|
||||
" ('ãĢ', 0.006875576451420784),\n",
|
||||
" ('ile', 0.006685272324830294),\n",
|
||||
" ('____', 0.006307446397840977),\n",
|
||||
" ('\u00e2\u0122\u012d', 0.006306538358330727),\n",
|
||||
" ('\u00d1\u0122', 0.006197483278810978),\n",
|
||||
" ('\u0120Belarus', 0.006108700763434172),\n",
|
||||
" ('\u00c6', 0.005720408633351326),\n",
|
||||
" ('\u0120Poland', 0.0053678699769079685),\n",
|
||||
" ('\u00e1\u00b9', 0.004606408067047596),\n",
|
||||
" ('\u00ee\u0122', 0.004161055199801922),\n",
|
||||
" ('âĢĭ', 0.006306538358330727),\n",
|
||||
" ('ÑĢ', 0.006197483278810978),\n",
|
||||
" ('ĠBelarus', 0.006108700763434172),\n",
|
||||
" ('Æ', 0.005720408633351326),\n",
|
||||
" ('ĠPoland', 0.0053678699769079685),\n",
|
||||
" ('á¹', 0.004606408067047596),\n",
|
||||
" ('îĢ', 0.004161055199801922),\n",
|
||||
" ('????', 0.004056799225509167),\n",
|
||||
" ('_______', 0.0038176667876541615),\n",
|
||||
" ('\u00e4\u00b8', 0.0036082742735743523),\n",
|
||||
" ('\u00cc', 0.003221835708245635),\n",
|
||||
" ('ä¸', 0.0036082742735743523),\n",
|
||||
" ('Ì', 0.003221835708245635),\n",
|
||||
" ('urs', 0.003080119378864765),\n",
|
||||
" ('________________', 0.0027312245219945908),\n",
|
||||
" ('\u0120Lithuania', 0.0023860156070441008),\n",
|
||||
" ('ĠLithuania', 0.0023860156070441008),\n",
|
||||
" ('ich', 0.0021211160346865654),\n",
|
||||
" ('iz', 0.002069818088784814),\n",
|
||||
" ('vern', 0.002001357264816761),\n",
|
||||
" ('\u00c5\u0124', 0.001717406208626926)]"
|
||||
" ('ÅĤ', 0.001717406208626926)]"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
@ -161,22 +159,22 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zalety tego podej\u015bcia:\n",
|
||||
"Zalety tego podejścia:\n",
|
||||
"\n",
|
||||
"- prostota,\n",
|
||||
"- dobra podstawa do strojenia system\u00f3w generowania tekstu zw\u0142aszcza\n",
|
||||
" \u201eotwartego\u201d (systemy dialogowe, generowanie (fake) news\u00f3w, streszczanie tekstu),\n",
|
||||
" ale niekoniecznie t\u0142umaczenia maszynowego,\n",
|
||||
"- zaskakuj\u0105ca skuteczno\u015b\u0107 przy uczeniu *few-shot* i *zero-shot*.\n",
|
||||
"- dobra podstawa do strojenia systemów generowania tekstu zwłaszcza\n",
|
||||
" „otwartego” (systemy dialogowe, generowanie (fake) newsów, streszczanie tekstu),\n",
|
||||
" ale niekoniecznie tłumaczenia maszynowego,\n",
|
||||
"- zaskakująca skuteczność przy uczeniu *few-shot* i *zero-shot*.\n",
|
||||
"\n",
|
||||
"Wady:\n",
|
||||
"\n",
|
||||
"- asymetryczno\u015b\u0107, przetwarzanie tylko z lewej do prawej, preferencja\n",
|
||||
"- asymetryczność, przetwarzanie tylko z lewej do prawej, preferencja\n",
|
||||
" dla lewego kontekstu,\n",
|
||||
"- mniejsza skuteczno\u015b\u0107 przy dostrajaniu do zada\u0144 klasyfikacji i innych zada\u0144\n",
|
||||
" niepolegaj\u0105cych na prostym generowaniu.\n",
|
||||
"- mniejsza skuteczność przy dostrajaniu do zadań klasyfikacji i innych zadań\n",
|
||||
" niepolegających na prostym generowaniu.\n",
|
||||
"\n",
|
||||
"Przyk\u0142ady modeli: GPT, GPT-2, GPT-3, DialoGPT.\n",
|
||||
"Przykłady modeli: GPT, GPT-2, GPT-3, DialoGPT.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -184,7 +182,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Maskowanie s\u0142\u00f3w (BERT)\n",
|
||||
"## Maskowanie słów (BERT)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -192,18 +190,18 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Inn\u0105 metod\u0105 jest maskowanie s\u0142\u00f3w (*Masked Language Modeling*, *MLM*).\n",
|
||||
"Inną metodą jest maskowanie słów (*Masked Language Modeling*, *MLM*).\n",
|
||||
"\n",
|
||||
"W tym podej\u015bciu losowe wybrane zast\u0119pujemy losowe s\u0142owa specjalnym\n",
|
||||
"tokenem (`[MASK]`) i ka\u017cemy modelowi odgadywa\u0107 w ten spos\u00f3b\n",
|
||||
"zamaskowane s\u0142owa (z uwzgl\u0119dnieniem r\u00f3wnie\u017c prawego kontekstu!).\n",
|
||||
"W tym podejściu losowe wybrane zastępujemy losowe słowa specjalnym\n",
|
||||
"tokenem (`[MASK]`) i każemy modelowi odgadywać w ten sposób\n",
|
||||
"zamaskowane słowa (z uwzględnieniem również prawego kontekstu!).\n",
|
||||
"\n",
|
||||
"M\u00f3ci\u0105c \u015bci\u015ble, w jednym z pierwszych modeli tego typu (BERT)\n",
|
||||
"zastosowano schemat, w kt\u00f3rym r\u00f3wnie\u017c niezamaskowane s\u0142owa s\u0105 odgadywane (!):\n",
|
||||
"Móciąc ściśle, w jednym z pierwszych modeli tego typu (BERT)\n",
|
||||
"zastosowano schemat, w którym również niezamaskowane słowa są odgadywane (!):\n",
|
||||
"\n",
|
||||
"- wybieramy losowe 15% wyraz\u00f3w do odgadni\u0119cia\n",
|
||||
"- 80% z nich zast\u0119pujemy tokenem `[MASK]`,\n",
|
||||
"- 10% zast\u0119pujemy innym losowym wyrazem,\n",
|
||||
"- wybieramy losowe 15% wyrazów do odgadnięcia\n",
|
||||
"- 80% z nich zastępujemy tokenem `[MASK]`,\n",
|
||||
"- 10% zastępujemy innym losowym wyrazem,\n",
|
||||
"- 10% pozostawiamy bez zmian.\n",
|
||||
"\n"
|
||||
]
|
||||
@ -225,16 +223,16 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W USA. (score: 0.16715531051158905)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W India. (score: 0.09912960231304169)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Indian. (score: 0.039642028510570526)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Nepal. (score: 0.027137665078043938)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Pakistan. (score: 0.027065709233283997)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Polsce. (score: 0.023737527430057526)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W .... (score: 0.02306722290813923)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Bangladesh. (score: 0.022106658667325974)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W .... (score: 0.01628892682492733)\n",
|
||||
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Niemczech. (score: 0.014501162804663181)\n"
|
||||
"W którym państwie leży Bombaj? W USA. (score: 0.16715531051158905)\n",
|
||||
"W którym państwie leży Bombaj? W India. (score: 0.09912960231304169)\n",
|
||||
"W którym państwie leży Bombaj? W Indian. (score: 0.039642028510570526)\n",
|
||||
"W którym państwie leży Bombaj? W Nepal. (score: 0.027137665078043938)\n",
|
||||
"W którym państwie leży Bombaj? W Pakistan. (score: 0.027065709233283997)\n",
|
||||
"W którym państwie leży Bombaj? W Polsce. (score: 0.023737527430057526)\n",
|
||||
"W którym państwie leży Bombaj? W .... (score: 0.02306722290813923)\n",
|
||||
"W którym państwie leży Bombaj? W Bangladesh. (score: 0.022106658667325974)\n",
|
||||
"W którym państwie leży Bombaj? W .... (score: 0.01628892682492733)\n",
|
||||
"W którym państwie leży Bombaj? W Niemczech. (score: 0.014501162804663181)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -245,7 +243,7 @@
|
||||
"tokenizer = AutoTokenizer.from_pretrained(\"xlm-roberta-large\")\n",
|
||||
"model = AutoModelWithLMHead.from_pretrained(\"xlm-roberta-large\")\n",
|
||||
"\n",
|
||||
"sequence = f'W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W {tokenizer.mask_token}.'\n",
|
||||
"sequence = f'W którym państwie leży Bombaj? W {tokenizer.mask_token}.'\n",
|
||||
"\n",
|
||||
"input_ids = tokenizer.encode(sequence, return_tensors=\"pt\")\n",
|
||||
"mask_token_index = torch.where(input_ids == tokenizer.mask_token_id)[1]\n",
|
||||
@ -265,7 +263,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Przyk\u0142ady: BERT, RoBERTa (r\u00f3wnie\u017c Polish RoBERTa).\n",
|
||||
"Przykłady: BERT, RoBERTa (również Polish RoBERTa).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -273,7 +271,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Podej\u015bcie generatywne (koder-dekoder).\n",
|
||||
"## Podejście generatywne (koder-dekoder).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -281,8 +279,8 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"System ma wygenerowa\u0107 odpowied\u017a na r\u00f3\u017cne pytania (r\u00f3wnie\u017c\n",
|
||||
"odpowiadaj\u0105ce zadaniu MLM), np.:\n",
|
||||
"System ma wygenerować odpowiedź na różne pytania (również\n",
|
||||
"odpowiadające zadaniu MLM), np.:\n",
|
||||
"\n",
|
||||
"- \"translate English to German: That is good.\" => \"Das ist gut.\"\n",
|
||||
"- \"cola sentence: The course is jumping well.\" => \"not acceptable\"\n",
|
||||
@ -355,17 +353,20 @@
|
||||
"source": [
|
||||
"(Zob. [https://arxiv.org/pdf/1910.10683.pdf](https://arxiv.org/pdf/1910.10683.pdf))\n",
|
||||
"\n",
|
||||
"Przyk\u0142ad: T5, mT5\n",
|
||||
"Przykład: T5, mT5\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"author": "Filip Graliński",
|
||||
"email": "filipg@amu.edu.pl",
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"lang": "pl",
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
@ -379,10 +380,7 @@
|
||||
"version": "3.9.6"
|
||||
},
|
||||
"org": null,
|
||||
"author": "Filip Grali\u0144ski",
|
||||
"email": "filipg@amu.edu.pl",
|
||||
"lang": "pl",
|
||||
"subtitle": "14.Pretrenowane modele j\u0119zyka[wyk\u0142ad]",
|
||||
"subtitle": "14.Pretrenowane modele języka[wykład]",
|
||||
"title": "Ekstrakcja informacji",
|
||||
"year": "2021"
|
||||
},
|
||||
|
@ -219,7 +219,10 @@
|
||||
"- $V$ = $EW^V$\n",
|
||||
"\n",
|
||||
"W kolejnych warstwach zamiast $E$ wykorzystywane jest wyjście z poprzedniej warstwy.\n",
|
||||
"\n"
|
||||
"\n",
|
||||
"## Zastosowanie w ekstrakcji informacji\n",
|
||||
"\n",
|
||||
"W prosty sposób możemy do sieci Transformer dołączyć głowicę realizującą etykietowanie sekwencji."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user