- Bevezetés
- Szóbeágyazási megközelítések
- Szavak zsákja
- A szózsákos megközelítés előnyei és hátrányai
- TF-IDF séma
- A TF-IDF előnyei és hátrányai
- Word2Vec
- A Word2Vec előnyei és hátrányai
- Word2Vec Pythonban a Gensim könyvtárral
- Korpusz létrehozása
- Előfeldolgozás
- A Word2Vec modell létrehozása
- Modellelemzés
- Vektorok keresése egy szóhoz
- A hasonló szavak megtalálása
- Következtetés
Bevezetés
Az embereknek természetes képessége, hogy megértsék, mit mondanak mások, és mit kell válaszul mondaniuk. Ezt a képességet a más emberekkel és a társadalommal való következetes, hosszú évekig tartó interakció során fejlesztik ki. A nyelv nagyon fontos szerepet játszik abban, hogy az emberek hogyan érintkeznek egymással. Az emberek által az interakcióhoz használt nyelveket természetes nyelveknek nevezzük.
A különböző természetes nyelvek szabályai eltérőek. Egy dolog azonban közös a természetes nyelvekben: a rugalmasság és az evolúció.
A természetes nyelvek rendkívül rugalmasak. Tegyük fel, hogy autót vezetsz, és a barátod a következő három kijelentés egyikét mondja: “Húzódj félre”, “Állítsd meg az autót”, “Állj”. Azonnal megérted, hogy arra kér téged, hogy állítsd meg az autót. Ez azért van, mert a természetes nyelvek rendkívül rugalmasak. Egy dolgot többféleképpen is ki lehet mondani.
A természetes nyelvek másik fontos aspektusa, hogy folyamatosan fejlődnek. Néhány évvel ezelőtt például még nem létezett olyan kifejezés, mint a “Google it”, ami arra utal, hogy a Google keresőmotoron keresünk valamit. A természetes nyelvek folyamatosan fejlődnek.
A számítógépes nyelvek ezzel szemben szigorú szintaxist követnek. Ha azt akarjuk mondani a számítógépnek, hogy nyomtasson ki valamit a képernyőre, akkor erre külön parancs van. A természetes nyelvfeldolgozás feladata, hogy a számítógépek az emberi nyelvet az emberhez hasonló módon értsék meg és generálják.
Ez hatalmas feladat, és sok akadályba ütközik. Ez a Michigani Egyetem videóelőadása nagyon jó magyarázatot tartalmaz arra, hogy miért olyan nehéz az NLP.
Ebben a cikkben a szóvektorok létrehozására használt Word2Vec szóbeágyazási technikát fogjuk implementálni a Python Gensim könyvtárával. Mielőtt azonban rögtön a kódolási részre ugranánk, először röviden áttekintjük a leggyakrabban használt szóbeágyazási technikákat, valamint azok előnyeit és hátrányait.
Szóbeágyazási megközelítések
Az egyik oka annak, hogy a természetes nyelvi feldolgozás nehezen megoldható probléma, az, hogy az emberrel ellentétben a számítógépek csak számokat értenek. A szavakat olyan számformátumban kell ábrázolnunk, amely a számítógépek számára érthető. A szóbeágyazás a szavak numerikus reprezentációjára utal.
A szóbeágyazás többféle megközelítése létezik jelenleg, és mindegyiknek megvannak az előnyei és hátrányai. Ezek közül hármat fogunk itt tárgyalni:
- Szavak zsákja
- TF-IDF séma
- Word2Vec
Szavak zsákja
A szavak zsákja megközelítés az egyik legegyszerűbb szóbeágyazási megközelítés. A következőkben a bag of words megközelítéssel történő szóbeágyazások generálásának lépéseit mutatjuk be.
A bag of words megközelítéssel generált szóbeágyazásokat egy példa segítségével nézzük meg. Tegyük fel, hogy van egy korpuszunk három mondattal.
- S1 = I love rain
- S2 = rain rain rain go away
- S3 = I am away
Ahhoz, hogy a fenti mondatokat a bag of words megközelítéssel a megfelelő szóbeágyazási reprezentációkba konvertáljuk, a következő lépéseket kell elvégeznünk:
Figyeljük meg, hogy az S2 esetében a szótárban az “eső” helyett 2-vel egészítettük ki; ez azért van, mert az S2 kétszer tartalmazza az “eső” szót.
A szózsákos megközelítés előnyei és hátrányai
A szózsákos megközelítésnek vannak előnyei és hátrányai is. A bag of words megközelítés fő előnye, hogy nincs szükség nagyon nagy szókorpuszra ahhoz, hogy jó eredményeket kapjunk. Láthatjuk, hogy egy nagyon egyszerű bag of words modellt építünk három mondatból. Számítási szempontból egy bag of words modell nem túl bonyolult.
A bag of words megközelítés legfőbb hátránya, hogy egy szám ábrázolásához hatalmas, üres helyeket tartalmazó vektorokat kell létrehoznunk (sparse mátrix), ami memória- és helyigényes. Az előző példában csak 3 mondatunk volt. Mégis minden vektorban három nullát láthatunk.
Képzeljünk el egy több ezer cikket tartalmazó korpuszt. Ilyen esetben az egyedi szavak száma a szótárban több ezer lehet. Ha egy dokumentum az egyedi szavak 10%-át tartalmazza, a megfelelő beágyazási vektor még mindig 90%-ban nullákat fog tartalmazni.
A másik nagy probléma a bag of words megközelítéssel az, hogy nem tart fenn semmilyen kontextusinformációt. Nem törődik azzal, hogy a szavak milyen sorrendben jelennek meg egy mondatban. Például egyformán kezeli a “Bottle is in the car” és a “Car is in the bottle” mondatokat, amelyek teljesen különböző mondatok.
A bag of words megközelítés egy típusa, az úgynevezett n-grammok segíthetnek a szavak közötti kapcsolat fenntartásában. Az n-gramm n szó összefüggő sorozatára utal. Például a “Nem vagy boldog” mondat 2grammjai a következők: “Nem vagy boldog”, “nem vagy” és “nem boldog”. Bár az n-grammok megközelítése alkalmas a szavak közötti kapcsolatok megragadására, a jellemzőkészlet mérete exponenciálisan nő a túl sok n-gramm esetén.
TF-IDF séma
A TF-IDF séma egyfajta zsákszavas megközelítés, ahol a beágyazási vektorban a nullák és egyesek helyett lebegő számokat adunk hozzá, amelyek a nullákhoz és egyesekhez képest több hasznos információt tartalmaznak. A TF-IDF séma lényege, hogy azok a szavak, amelyek nagy gyakorisággal fordulnak elő egy dokumentumban, és kisebb gyakorisággal fordulnak elő az összes többi dokumentumban, döntőbbek az osztályozás szempontjából.
A TF-IDF két érték szorzata:
A kifejezés gyakorisága azt jelenti, hogy egy szó hányszor fordul elő a dokumentumban, és a következőképpen számítható ki:
Term frequence = (Number of Occurences of a word)/(Total words in the document)
Például, ha az előző szakasz S1 mondatát nézzük, azaz “Szeretem az esőt”, akkor a mondatban minden szó egyszer fordul elő, ezért gyakorisága 1. Ezzel szemben az S2 mondat esetében, azaz “rain rain rain go away”, az “rain” szó gyakorisága kettő, míg a többi szóé 1.
Az IDF a dokumentumok teljes számának logaritmusát jelenti, osztva azon dokumentumok számával, amelyekben a szó előfordul, és a következőképpen számítható ki:
IDF(word) = Log((Total number of documents)/(Number of documents containing the word))
Például az IDF értéke az “rain” szóra 0,1760, mivel a dokumentumok teljes száma 3, és az eső 2 dokumentumban fordul elő, ezért log(3/2)
0,1760. Másrészt, ha megnézzük a “szerelem” szót az első mondatban, az a három dokumentum közül egyben szerepel, ezért az IDF-értéke log(3)
, ami 0,4771.
A TF-IDF előnyei és hátrányai
A TF-IDF ugyan előrelépést jelent az egyszerű bag of words megközelítéshez képest, és jobb eredményeket ad a gyakori NLP feladatokban, de az általános előnyök és hátrányok változatlanok maradnak. Továbbra is hatalmas ritkamátrixot kell létrehoznunk, ami szintén sokkal több számítást igényel, mint az egyszerű szózsákos megközelítés.
Word2Vec
A Tomas Mikolov által kifejlesztett <a target=”_blank rel=”nofollow”” href=”https://en.wikipedia.org/wiki/Word2vec”>Word2Vec beágyazási megközelítés tekinthető a technika jelenlegi állásának. A Word2Vec megközelítés mélytanuláson és neurális hálózatokon alapuló technikákat használ a szavak megfelelő vektorokká alakítására oly módon, hogy a szemantikailag hasonló vektorok közel legyenek egymáshoz az N-dimenziós térben, ahol N a vektor dimenzióira utal.
A Word2Vec meghökkentő eredményeket ad vissza. A Word2Vec szemantikus kapcsolat fenntartásának képességét egy klasszikus példa mutatja, ahol ha van egy vektorunk a “Király” szóhoz, és a “Király” szóból kivesszük a “Férfi” szó által reprezentált vektort, és hozzáadjuk a “Nők” szót, akkor olyan vektort kapunk, amely közel áll a “Királynő” vektorhoz. Ezt a kapcsolatot általában így ábrázolják:
King - Man + Women = Queen
A szó2Vec modell kétféleképpen létezik: Skip Gram modell és Continuous Bag of Words Model (CBOW).
A Skip Gram modellben a kontextusszavak előrejelzése az alapszó segítségével történik. Például egy “I love to dance in the rain” mondat esetén a skip gram modell a “love” és a “dance” szavakat fogja megjósolni, ha a “to” szót adjuk meg bemenetként.
A CBOW modell ezzel szemben a “to” szót fogja megjósolni, ha a “love” és a “dance” kontextusszavakat adjuk meg bemenetként a modellnek. A modell ezeket az összefüggéseket mély neurális hálózatok segítségével tanulja meg.
A Word2Vec előnyei és hátrányai
A Word2Vec számos előnnyel rendelkezik a bag of words és az IF-IDF sémával szemben. A Word2Vec megőrzi a dokumentumban lévő különböző szavak szemantikai jelentését. A szövegkörnyezeti információ nem vész el. A Word2Vec megközelítés másik nagy előnye, hogy a beágyazási vektor mérete nagyon kicsi. A beágyazási vektor minden dimenziója a szó egy-egy aspektusára vonatkozó információt tartalmaz. Nincs szükségünk hatalmas, ritka vektorokra, ellentétben a bag of words és a TF-IDF megközelítéssel.
Megjegyzés: A Word2Vec működésének matematikai részletei a neurális hálózatok és a softmax valószínűség magyarázatát foglalják magukban, ami meghaladja e cikk kereteit. Ha szeretné megérteni a Word2Vec matematikai alapjait, kérjük, olvassa el ezt a cikket: https://arxiv.org/abs/1301.3781
Word2Vec Pythonban a Gensim könyvtárral
Ebben a részben a Word2Vec modellt a Python Gensim könyvtár segítségével fogjuk megvalósítani. Kövessük az alábbi lépéseket:
Korpusz létrehozása
Korábban tárgyaltuk, hogy a Word2Vec modell létrehozásához szükségünk van egy korpuszra. A valós alkalmazásokban a Word2Vec modelleket több milliárd dokumentum felhasználásával hozzák létre. A Google Word2Vec modelljét például 3 millió szó és kifejezés felhasználásával képzik ki. Az egyszerűség kedvéért azonban a Word2Vec modellt egyetlen Wikipédia-szócikk felhasználásával fogjuk létrehozni. A mi modellünk nem lesz olyan jó, mint a Google modellje. Bár elég jó ahhoz, hogy elmagyarázzuk, hogyan lehet a Word2Vec modellt a Gensim könyvtár segítségével megvalósítani.
Mielőtt összefoglalhatnánk a Wikipedia cikkeket, le kell hívnunk őket. Ehhez néhány könyvtárat fogunk használni. Az első könyvtár, amit le kell töltenünk, a Beautiful Soup könyvtár, ami egy nagyon hasznos Python segédprogram a webkaparáshoz. A Beautiful Soup segédprogram letöltéséhez hajtsa végre az alábbi parancsot a parancssorban.
$ pip install beautifulsoup4
A másik fontos könyvtár, amelyre az XML és HTML elemzésére van szükségünk, az lxml könyvtár. Az lxml letöltéséhez hajtsa végre a parancssorban a következő parancsot:
$ pip install lxml
A cikk, amit le fogunk kaparni, a Wikipedia mesterséges intelligenciáról szóló cikke. Írjunk egy Python scriptet a cikk Wikipédiából való lekaparásához:
A fenti scriptben először letöltjük a Wikipedia cikket a urllib
könyvtár request
osztályának urlopen
metódusával. Ezután beolvassuk a cikk tartalmát és elemezzük azt a BeautifulSoup
osztály egy objektumával. A Wikipedia a cikk szöveges tartalmát p
címkéken belül tárolja. A BeautifulSoup
objektum find_all
függvényét használjuk a cikk összes tartalmának lekérdezésére a cikk bekezdéscímkékből.
Végül egyesítjük az összes bekezdést, és a lekapart cikket a article_text
változóban tároljuk későbbi felhasználásra.
Előfeldolgozás
Ezzel a ponttal már importáltuk a cikket. A következő lépés a tartalom előfeldolgozása a Word2Vec modellhez. A következő szkript előfeldolgozza a szöveget:
A fenti szkriptben az összes szöveget kisbetűvé alakítjuk, majd eltávolítjuk a szövegből az összes számjegyet, speciális karaktert és extra szóközt. Az előfeldolgozás után csak a szavak maradnak.
A Word2Vec modellt a szavak gyűjteményén képezzük ki. Először is át kell alakítanunk a cikkünket mondatokká. A nltk.sent_tokenize
segédprogramot használjuk a cikkünk mondatokká alakításához. A mondatok szavakká alakításához a nltk.word_tokenize
segédprogramot használjuk. Utolsó előfeldolgozási lépésként eltávolítjuk a szövegből a stop szavakat.
A szkript végrehajtása után a all_words
objektum tartalmazza a cikk összes szavának listáját. Ezt a listát fogjuk felhasználni a Word2Vec modellünk létrehozásához a Gensim könyvtár segítségével.
A Word2Vec modell létrehozása
A Gensim segítségével rendkívül egyszerű a Word2Vec modell létrehozása. A szólistát átadjuk a gensim.models
csomag Word2Vec
osztályának. Meg kell adnunk a min_count
paraméter értékét. A min_count
2 értéke azt adja meg, hogy a Word2Vec modellbe csak azokat a szavakat vegyük fel, amelyek legalább kétszer szerepelnek a korpuszban. A következő szkript létrehozza a Word2Vec modellt az általunk lekapart Wikipédia-szócikk felhasználásával.
from gensim.models import Word2Vecword2vec = Word2Vec(all_words, min_count=2)
Hogy megnézzük a korpuszban legalább kétszer előforduló egyedi szavak szótárát, futtassuk a következő szkriptet:
vocabulary = word2vec.wv.vocabprint(vocabulary)
A fenti szkript végrehajtása után megjelenik a legalább kétszer előforduló egyedi szavak listája.
Modellelemzés
Az előző részben sikeresen létrehoztuk a Word2Vec modellünket. Most itt az ideje, hogy megvizsgáljuk, mit hoztunk létre.
Vektorok keresése egy szóhoz
Tudjuk, hogy a Word2Vec modell a szavakat a megfelelő vektorokká alakítja át. Lássuk, hogyan tekinthetjük meg bármelyik konkrét szó vektorreprezentációját.
v1 = word2vec.wv
A v1
vektor a “mesterséges” szó vektorreprezentációját tartalmazza. Alapértelmezés szerint egy százdimenziós vektort hoz létre a Gensim Word2Vec. Ez egy sokkal, de sokkal kisebb vektor ahhoz képest, amit a szavak zsákja (bag of words) állítana elő. Ha a bag of words megközelítést használjuk a cikk beágyazásához, a vektor hossza 1206 lesz, mivel 1206 egyedi szó van, amelyek minimális előfordulási gyakorisága 2. Ha a minimális előfordulási gyakoriságot 1-re állítjuk, a bag of words vektor mérete tovább nő. Másrészt a Word2Vec segítségével generált vektorokat nem befolyásolja a szókincs mérete.
A hasonló szavak megtalálása
Az előbb azt mondtuk, hogy a szavak kontextuális információi nem vesznek el a Word2Vec megközelítéssel. Ezt ellenőrizhetjük az “intelligencia” szóhoz hasonló szavak megkeresésével.
Vessünk egy pillantást a következő szkriptre:
sim_words = word2vec.wv.most_similar('intelligence')
Ha a sim_words
változót kiírjuk a konzolra, az alábbiakban látható módon láthatjuk az “intelligencia” szóhoz leginkább hasonló szavakat:
A kimenetből láthatjuk az “intelligencia” szóhoz hasonló szavakat a hasonlósági indexükkel együtt. A modell szerint az “ai” szó a leghasonlóbb szó az “intelligencia” szóhoz, aminek tulajdonképpen van értelme. Hasonlóképpen az olyan szavak, mint az “emberi” és a “mesterséges” gyakran előfordulnak együtt az “intelligencia” szóval. Modellünk sikeresen megragadta ezeket a kapcsolatokat egyetlen Wikipédia-szócikk felhasználásával.
Következtetés
Ezzel a cikkel egy Word2Vec szóbeágyazási modellt implementáltunk a Python Gensim könyvtárával. Ehhez egy Wikipédia-szócikket kapartunk le, és a Word2Vec modellünket a szócikket korpuszként használva építettük fel. Röviden áttekintettük a leggyakrabban használt szóbeágyazási megközelítéseket is, valamint azok előnyeit és hátrányait a Word2Vec-hez képest.
Azt javaslom, hogy hozzon létre egy saját Word2Vec modellt bármilyen szövegkorpusz segítségével, és nézze meg, hogy a bag of words megközelítéshez képest jobb eredményeket kap-e.