Úvod
Člověk má přirozenou schopnost porozumět tomu, co říkají ostatní lidé, a co na to říci. Tato schopnost je rozvíjena důslednou interakcí s ostatními lidmi a společností po mnoho let. Jazyk hraje v interakci mezi lidmi velmi důležitou roli. Jazyky, které lidé používají k interakci, se nazývají přirozené jazyky.
Pravidla různých přirozených jazyků se liší. Jedno však mají přirozené jazyky společné: flexibilitu a vývoj.
Přirozené jazyky jsou vysoce velmi flexibilní. Předpokládejme, že jedete autem a váš přítel řekne jeden z těchto tří výroků: „Zastav“, „Zastav auto“, „Stůj“. Okamžitě pochopíte, že vás žádá, abyste zastavili auto. Je to proto, že přirozené jazyky jsou nesmírně flexibilní. Existuje více způsobů, jak říci jednu věc.
Dalším důležitým aspektem přirozených jazyků je skutečnost, že se neustále vyvíjejí. Například před několika lety neexistoval výraz jako „Google it“, který označuje vyhledávání něčeho ve vyhledávači Google. Přirozené jazyky neustále procházejí vývojem.
Počítačové jazyky se naopak řídí přísnou syntaxí. Pokud chcete počítači říci, aby něco vytiskl na obrazovku, existuje pro to speciální příkaz. Úkolem zpracování přirozeného jazyka je přimět počítače, aby rozuměly lidskému jazyku a vytvářely jej podobně jako lidé.
Je to obrovský úkol a je s ním spojeno mnoho překážek. Tato videopřednáška z Michiganské univerzity obsahuje velmi dobré vysvětlení, proč je NLP tak obtížné.
V tomto článku budeme implementovat techniku Word2Vec word embedding používanou pro vytváření slovních vektorů pomocí knihovny Gensim v jazyce Python. Než se však vrhneme přímo na část věnovanou kódování, nejprve si stručně projdeme některé nejčastěji používané techniky vkládání slov spolu s jejich výhodami a nevýhodami.
Přístupy k vkládání slov
Jedním z důvodů, proč je zpracování přirozeného jazyka obtížně řešitelný problém, je skutečnost, že na rozdíl od člověka počítače rozumí pouze číslům. Musíme tedy reprezentovat slova v číselném formátu, který je pro počítače srozumitelný. Vkládání slov se týká číselné reprezentace slov.
V současné době existuje několik přístupů k vkládání slov a všechny mají svá pro a proti. Zde se budeme zabývat třemi z nich:
- Svazek slov
- Schéma TF-IDF
- Slovo2Vec
Svazek slov
Přístup svazku slov je jedním z nejjednodušších přístupů k vkládání slov. Následují kroky pro generování vkládání slov pomocí přístupu bag of words.
Na příkladu si ukážeme vkládání slov generované pomocí přístupu bag of words. Předpokládejme, že máme korpus se třemi větami.
- S1 = I love rain
- S2 = rain rain go away
- S3 = I am away
Chceme-li výše uvedené věty převést na odpovídající reprezentace slovních vložek pomocí přístupu bag of words, musíme provést následující kroky:
Všimněte si, že u S2 jsme na místo slova „déšť“ ve slovníku přidali 2; to proto, že S2 obsahuje slovo „déšť“ dvakrát.
Pro a proti přístupu Bag of Words
Přístup Bag of Words má výhody i nevýhody. Hlavní výhodou přístupu bag of words je, že k získání dobrých výsledků nepotřebujete příliš velký korpus slov. Můžete vidět, že jsme sestavili velmi základní model pytle slov se třemi větami. Výpočetně není model sáčku slov příliš složitý.
Hlavní nevýhodou přístupu sáčku slov je skutečnost, že musíme vytvořit obrovské vektory s prázdnými místy, abychom reprezentovali číslo (řídká matice), což spotřebovává paměť a místo. V předchozím příkladu jsme měli pouze 3 věty. Přesto můžete v každém vektoru vidět tři nuly.
Představte si korpus s tisíci články. V takovém případě může být počet unikátních slov ve slovníku tisíce. Pokud jeden dokument obsahuje 10 % unikátních slov, odpovídající vektor osazení bude stále obsahovat 90 % nul.
Dalším závažným problémem přístupu založeného na pytli slov je skutečnost, že nezachovává žádné kontextové informace. Nezajímá se o pořadí, v jakém se slova ve větě vyskytují. Například zachází stejně s větami „Láhev je v autě“ a „Auto je v láhvi“, což jsou zcela odlišné věty.
Druh přístupu založeného na pytli slov, známý jako n-gramy, může pomoci zachovat vztahy mezi slovy. N-gram označuje souvislou posloupnost n slov. Například 2-gramy pro větu „Nejsi šťastný“ jsou „jsi“, „nejsi“ a „nejsi šťastný“. Ačkoli je přístup založený na n-gramech schopen zachytit vztahy mezi slovy, velikost množiny příznaků roste exponenciálně s příliš velkým počtem n-gramů.
Schéma TF-IDF
Schéma TF-IDF je typem přístupu založeného na pytli slov, kde se místo přidávání nul a jedniček do vektoru vložení přidávají plovoucí čísla, která obsahují více užitečných informací než nuly a jedničky. Myšlenkou schématu TF-IDF je skutečnost, že slova, která mají vysokou frekvenci výskytu v jednom dokumentu a nižší frekvenci výskytu ve všech ostatních dokumentech, jsou pro klasifikaci rozhodující.
TF-IDF je součin dvou hodnot:
Frekvence termínů (TF) a inverzní frekvence dokumentů (IDF).
Frekvence termínů se vztahuje k počtu výskytů slova v dokumentu a lze ji vypočítat jako:
Term frequence = (Number of Occurences of a word)/(Total words in the document)
Podíváme-li se například na větu S1 z předchozí části, tj. „Miluji déšť“, každé slovo se ve větě vyskytuje jednou, a proto má frekvenci 1. Naopak pro větu S2, tj. „rain rain go away“, je frekvence slova „rain“ dvě, zatímco u ostatních slov je 1.
IDF označuje logaritmus celkového počtu dokumentů dělený počtem dokumentů, v nichž se slovo vyskytuje, a lze jej vypočítat jako:
IDF(word) = Log((Total number of documents)/(Number of documents containing the word))
Například hodnota IDF pro slovo „rain“ je 0,1760, protože celkový počet dokumentů je 3 a rain se vyskytuje ve 2 z nich, proto log(3/2)
je 0,1760. Na druhou stranu, pokud se podíváte na slovo „láska“ v první větě, objevuje se v jednom ze tří dokumentů, a proto je jeho hodnota IDF log(3)
, což je 0,4771.
Pro a proti TF-IDF
Přestože je TF-IDF lepší než jednoduchý přístup založený na pytli slov a poskytuje lepší výsledky pro běžné úlohy NLP, celkové výhody a nevýhody zůstávají stejné. Stále musíme vytvořit obrovskou řídkou matici, což také vyžaduje mnohem více výpočtů než jednoduchý přístup založený na pytli slov.
Word2Vec
Za nejmodernější se považuje <a target=“_blank rel=“nofollow““ href=“https://en.wikipedia.org/wiki/Word2vec“>Přístup založený na vkládání slov, který vyvinul Tomáš Mikolov. Přístup Word2Vec využívá techniky založené na hlubokém učení a neuronových sítích k převodu slov na odpovídající vektory tak, aby si byly sémanticky podobné vektory blízké v N-rozměrném prostoru, kde N odkazuje na rozměry vektoru.
Přístup Word2Vec vrací některé překvapivé výsledky. Schopnost Word2Vec zachovat sémantickou souvislost se projevuje na klasickém příkladu, kdy pokud máte vektor pro slovo „Král“ a odeberete z něj vektor reprezentovaný slovem „Muž“ a přidáte k němu „Ženy“, získáte vektor, který je blízký vektoru „Královna“. Tento vztah se běžně reprezentuje jako:
King - Man + Women = Queen
Model Word2Vec existuje ve dvou variantách: V modelu Skip Gram a v modelu Continuous Bag of Words (CBOW).
V modelu Skip Gram se kontextová slova předpovídají pomocí základního slova. Například při zadání věty „Rád tančím v dešti“ model Skip Gram předpoví „láska“ a „tanec“, pokud je na vstupu slovo „to“.
Model CBOW naopak předpoví „to“, pokud jsou na vstupu do modelu zadána kontextová slova „láska“ a „tanec“. Model se tyto vztahy učí pomocí hlubokých neuronových sítí.
Pros a proti Word2Vec
Word2Vec má oproti pytli slov a schématu IF-IDF několik výhod. Word2Vec zachovává sémantický význam různých slov v dokumentu. Neztrácí se kontextové informace. Další velkou výhodou přístupu Word2Vec je, že velikost vkládaného vektoru je velmi malá. Každá dimenze ve vkládacím vektoru obsahuje informace o jednom aspektu slova. Na rozdíl od přístupů typu bag of words a TF-IDF nepotřebujeme obrovské řídké vektory.
Poznámka: Matematické podrobnosti o tom, jak Word2Vec funguje, zahrnují vysvětlení neuronových sítí a softmaxové pravděpodobnosti, což je nad rámec tohoto článku. Pokud chcete pochopit matematické základy Word2Vec, přečtěte si tento článek: https://arxiv.org/abs/1301.3781
Word2Vec v Pythonu s knihovnou Gensim
V této části budeme implementovat model Word2Vec pomocí knihovny Gensim v Pythonu. Postupujte podle následujících kroků:
Vytvoření korpusu
Již dříve jsme si řekli, že k vytvoření modelu Word2Vec potřebujeme korpus. V reálných aplikacích se modely Word2Vec vytvářejí pomocí miliard dokumentů. Například model Word2Vec společnosti Google je natrénován pomocí 3 milionů slov a frází. Pro zjednodušení však vytvoříme model Word2Vec pomocí jediného článku Wikipedie. Náš model nebude tak dobrý jako model společnosti Google. I když je dostatečně dobrý na to, abychom vysvětlili, jak lze model Word2Vec implementovat pomocí knihovny Gensim.
Než budeme moci shrnout články Wikipedie, musíme je načíst. K tomu použijeme několik knihoven. První knihovnou, kterou si musíme stáhnout, je knihovna Beautiful Soup, což je velmi užitečný nástroj jazyka Python pro škrábání webových stránek. Spusťte následující příkaz v příkazovém řádku a stáhněte nástroj Beautiful Soup.
$ pip install beautifulsoup4
Další důležitou knihovnou, kterou potřebujeme k analýze XML a HTML, je knihovna lxml. Spusťte následující příkaz na příkazovém řádku a stáhněte knihovnu lxml:
$ pip install lxml
Článek, který se chystáme vyškrábat, je článek na Wikipedii o umělé inteligenci. Napišme skript Python, který článek z Wikipedie seškrábe:
V uvedeném skriptu nejprve stáhneme článek Wikipedie pomocí metody urlopen
třídy request
knihovny urllib
. Poté načteme obsah článku a analyzujeme jej pomocí objektu třídy BeautifulSoup
. Wikipedie ukládá textový obsah článku uvnitř značek p
. Pomocí funkce find_all
objektu BeautifulSoup
načteme veškerý obsah ze značek odstavců článku.
Nakonec spojíme všechny odstavce dohromady a uložíme seškrábaný článek do proměnné article_text
pro pozdější použití.
Předzpracování
V tomto okamžiku jsme již importovali článek. Dalším krokem je předzpracování obsahu pro model Word2Vec. Následující skript předzpracuje text:
V uvedeném skriptu převedeme veškerý text na malá písmena a poté z textu odstraníme všechny číslice, speciální znaky a mezery navíc. Po předzpracování nám zůstanou pouze slova.
Model Word2Vec je natrénován na kolekci slov. Nejprve musíme náš článek převést na věty. K převodu našeho článku na věty použijeme nástroj nltk.sent_tokenize
. Pro převod vět na slova použijeme nástroj nltk.word_tokenize
. Jako poslední krok předzpracování odstraníme z textu všechna stop slova.
Po dokončení provádění skriptu obsahuje objekt all_words
seznam všech slov v článku. Tento seznam použijeme k vytvoření našeho modelu Word2Vec pomocí knihovny Gensim.
Vytvoření modelu Word2Vec
Pomocí knihovny Gensim je vytvoření modelu Word2Vec velmi jednoduché. Seznam slov se předává třídě Word2Vec
balíčku gensim.models
. Musíme zadat hodnotu parametru min_count
. Hodnota 2 pro min_count
určuje, že do modelu Word2Vec budou zahrnuta pouze ta slova, která se v korpusu vyskytují alespoň dvakrát. Následující skript vytvoří model Word2Vec na základě článku z Wikipedie, který jsme vyškrábali.
from gensim.models import Word2Vecword2vec = Word2Vec(all_words, min_count=2)
Chcete-li zobrazit slovník unikátních slov, která se v korpusu vyskytují alespoň dvakrát, spusťte následující skript:
vocabulary = word2vec.wv.vocabprint(vocabulary)
Po spuštění výše uvedeného skriptu se zobrazí seznam všech unikátních slov vyskytujících se alespoň dvakrát.
Analýza modelu
V minulé části jsme úspěšně vytvořili náš model Word2Vec. Nyní je čas prozkoumat, co jsme vytvořili.
Vyhledání vektorů pro slovo
Víme, že model Word2Vec převádí slova na jim odpovídající vektory. Podívejme se, jak můžeme zobrazit vektorovou reprezentaci libovolného konkrétního slova.
v1 = word2vec.wv
Vektor v1
obsahuje vektorovou reprezentaci pro slovo „umělý“. Ve výchozím nastavení vytvoří Gensim Word2Vec stodimenzionální vektor. Jedná se o mnohem, mnohem menší vektor ve srovnání s tím, co by vytvořil bag of words. Pokud pro vložení článku použijeme přístup bag of words, bude délka vektoru pro každé z nich 1206, protože existuje 1206 jedinečných slov s minimální frekvencí výskytu 2. Pokud je minimální frekvence výskytu nastavena na 1, velikost vektoru bag of words se dále zvětší. Na druhou stranu vektory vytvořené pomocí metody Word2Vec nejsou velikostí slovníku ovlivněny.
Vyhledávání podobných slov
Předtím jsme uvedli, že při použití metody Word2Vec nedochází ke ztrátě kontextových informací o slovech. To si můžeme ověřit nalezením všech slov podobných slovu „inteligence“.
Podívejte se na následující skript:
sim_words = word2vec.wv.most_similar('intelligence')
Pokud vypíšete proměnnou sim_words
do konzoly, uvidíte slova nejvíce podobná slovu „inteligence“, jak je uvedeno níže:
Z výstupu vidíte slova podobná slovu „inteligence“ spolu s jejich indexem podobnosti. Slovo „ai“ je podle modelu nejvíce podobné slovu „inteligence“, což vlastně dává smysl. Podobně se slovem „inteligence“ často koexistují slova jako „lidský“ a „umělý“. Náš model tyto vztahy úspěšně zachytil na základě pouhého jednoho článku ve Wikipedii.
Závěr
V tomto článku jsme implementovali model vkládání slov Word2Vec pomocí knihovny Gensim v jazyce Python. Udělali jsme to tak, že jsme vyškrábali článek z Wikipedie a vytvořili náš model Word2Vec s použitím článku jako korpusu. Stručně jsme také zhodnotili nejčastěji používané přístupy k vkládání slov spolu s jejich výhodami a nevýhodami jako srovnání s modelem Word2Vec.
Rad bych vám doporučil, abyste si vytvořili vlastní model Word2Vec s pomocí libovolného textového korpusu a zjistili, zda můžete dosáhnout lepších výsledků ve srovnání s přístupem bag of words.