2010. július 14.

Szógyakoriság ismét (de most saját fájlból, R használatával elemezve)

Az előző technikai jellegű posztomban a Magyar Webkorpusz alapján vetettünk egy pillantást a szógyakoriságra. Most egy saját szöveges fájlból készítünk szógyakorisági témát.

Eszközök
Egy szövegfájl Keressünk egy szövegfájlt az OSZK MEK honlapján. Válaszd a html formátumot.
HTML "kitisztító" html2text, ha Ubuntu, vagy Linux alapú oprendszered van akkor a szokásos módon telepítheted. Vagy választhatod a python alatt bármikor bárhol futtatható verziót is. Házi feladat, készíts a html fájlból egy "plain text" fájlt. A program man page-e talán segít.
Egy kész szövegfájl letölthető itt, ha lusta vagy (vagy valamiért nem tudod magad megcsinálni).
R Ha még nincs fent a gépeden, akkor telepítsd fel az R statisztikai programozási nyelvet.

A feladat
Arra vagyunk kíváncsiak hogy egy adott szó hányszor fordul elő a fájlban. Gondolkozz egy kicsit milyen problémákat vet ez fel. Mi az hogy szó? Mi neked egy szó és mi a számítógépnek? Mi nagyon egyszerű definíciót adunk itt, szónak egy olyan karaktersort tekintünk amit két nem-karakter között összefüggően fordul elő. Jó mi? (Kicsit gondolkozz el azon hogy ez mennyire jó meghatározás, hogyan kellene finomítani hogy megfeleljen a szó intuitív fogalmának) Elgondolkodtál? Akkor egy kicsit még maradjunk a témánál. Nyilván így egy halandzsa, vagy félreütött karaktersor is szó (pl asAnza), felmerül a kérdés hogy a "tó" "tavak" egy vagy két szó-e (nálunk kettő, mivel technikailag nagyon nehéz lenne morfológiailag elemezni). Mi van a mondat elején nagybetűvel kezdett "Asztal" és a csupa kisbetűs "asztal" esetében? Ezt könnyű megoldani, nem okoz gondot átalakítani a karaktereket. Nyilván figyelembe kell venni ezeket a kérdéseket. De ha eltekintünk ezektől, attól még egy becslést tehetünk.

Vágjunk bele!
Indítsd el az R-t abban a könyvtárban ahol a szövegfájlod található. Először olvassuk be a fájlt hogy tudjunk vele dolgozni.

> textfile<-scan(file.choose(), what="char", sep="\n", quote="", comment.char="")
Figyelem! Mac és Windows használók a file.choose() függvényt cseréljék ki choose,files() -ra.

Alakítsuk át a fájlt csupa kisbetűs karakterek sorává. (Ugye mondtam hogy egyszerű lesz, "Asztal"-ból, "asztal" lesz így)
> textfile<-tolower(textfile)

Abban maradtunk hogy "szónak egy olyan karaktersort tekintünk amit két nem-karakter között összefüggően fordul elő" . Ez R-ben:
> words.list<-strsplit(textfile, "\\W+")

Fent semmi mást nem tettünk mint a fájl tartalmát "feldaraboltuk" a "nem szó-karakterek" mentén. Ezt a \W+ reguláris kifejezéssel értük el (szabályos kifejezéseknek is hívják őket, ha angolul keresed regular expressions).

Egy kicsit bonyolítsuk a dolgot. Tudjuk az előző posztból hogy bizonyos szavak nagyon gyakoriak. Ezeket gyakran töltelékszavaknak hívjuk, vagy angolos szakzsargonnal stop words. Ha kiszűrjük ezeket a szavakat, akkor egy kicsit jobb képet kaphatunk hogy a normális szavak milyen gyakoriak (kontentívumok maradnak, mivel a legtöbb töltelékszó funktor). Tegyük ezt akkor! Először is egy listát készítünk ezekről a faramuci szavakról:

> stop.list<-c("a", "egy", "be", "ki", "le", "fel", "meg", "el", "át", "rá", "ide", "oda", "szét", "össze", "vissza", "de", "hát", "és", "vagy", "hogy", "van", "lesz", "volt", "csak", "nem", "igen", "mint", "én", "te", "ő", "mi", "ti", "ők", "ön", "ez", "az", "ha")

Alakítsuk egy kicsit át a beolvasott szövegfájlt:
> words.vector.h<-unlist(words.list)

Most már egy adat típusba tartozik a beolvasott szöveg és a töltelékszavak listája is, ki is szűrhetjük őket.
> words.vector<-words.vector.h[!(words.vector.h %in% stop.list)]

A következő lépésekben pedig elmentjük a gyakorisági táblázatot egy kimeneti fájlba.
> freq.list<-table(words.vector)
> sorted.freq.list<-sort(freq.list, decreasing=T)
> sorted.freq.list<-sorted.freq.list[sorted.freq.list>1]
> sorted.table<-paste(names(sorted.freq.list), sorted.freq.list, sep="\t")
> cat("WORD\tFREQ", sorted.table, file=file.choose(), sep="\n")

Bónusz gnuplot bütykölés
A gyakorisági adatokat csökkenő sorrendbe tettük és a csak egyszer előforduló elemeket is kiszűrtük (hogy nagyon okos legyél olvasd el mi az a hapax legomenon, na azé' szűrjük ki!). Most hogy elmentettük, gnuplot-tal az előző posztomban leírtak szerint készíthetsz egy szép ábrát hogy lásd arányaiban hányszor fordul elő egy-egy elem. Az enyém így néz ki.




Ha összeveted az előző ábrával láthatod hogy nincsenek kiugró vonalak (hapax legomena!). Nem is kezd olyan magas értéknél, de hát kisebb is a mintánk. A lényeg hogy szebb (lehet hogy csak nekem).

Ha érdekel akkor ezt olvasd

A poszt megírásához Stefan Th. Gries Quantitative Corpus Linguistics with R könyve adott inspirációt, a kódrészleteket pedig minimális változtatással vettem át.

2010. július 11.

NooJ, az Integrált Nyelvelemző Környezet I.

VENDÉGPOSZT!

Előzetesnek szánom ezt a cikket. Bemutatni, hogy mennyi és milyen minőségű nyelvelemző programok állnak már jelenleg is a rendelkezésünkre. De előzetes abban az értelemben is, hogy az eszközökről szeretnék majd több hosszabb-rövidebb leírást is adni. És nem utolsó sorban előzetes abból a szempontból is, hogy a későbbre tervezett Natural Language Toolkit használatát fogjuk a most bemutatott NooJ eszközzel megalapozni.

A NooJ, és elődje az INTEX egy integrált nyelvelemző környezet. Egy francia nyelvész készítette, aki ráébredt arra, hogy rengeteg szakterület tudná alkalmazni, használni a saját céljaira egy nyelvelemző rendszert. A többi nyelvelemző ellen mindig az első ellenérv a kezelhetőség volt. Még a jelenleg a PTE-n fejlesztett (prolog nyelven fejlesztett) szövegelemzőről is (bár csak néhány bemutatót sikerült erről a fejlesztésről megszereznem...) első hátrányként említik, hogy nehezen kezelhető, olvasható az eredmény. Ez azért könnyedén orvosolható lenne. Mindenesetre megértem azokat, akik csak egy-egy ötletért nem hajlandóak ennyire belemerülni a témában. Pont a számukra lehet a legideálisabb eszköz a NooJ.

Szerencsére a témának van magyar honlapja. http://corpus.nytud.hu/nooj/ címen tudjátok elérni. Itt található meg hozzá továbbá a magyar modul is, amivel el tudjuk végezni az elemzéseinket. Illetve a kipróbáláshoz ajánlom mindenki figyelmébe Vajda Péter bemutatását: http://corpus.nytud.hu/manye/vp_nooj.ppt

Hogy van magyar honlapja, ez sajnos nem egyenlő azzal, hogy fejlesztik is. 2006-ban indult, és azóta csak a magyar modul került fel. De a még akkoriban tervezett grammatika nem jelent meg azóta sem.

A NooJ a morphdb.hu-t használja. Akik használták már külön, azoknak nem lesz meglepetés a szavak elemzésének eredménye vagy a típushibái, de ezeket könnyedén javíthatjuk az aktuális szövegnél. Viszont a NooJ nem csak erre képes. Lehetséges vele szógyakoriságot vizsgálni, ahogyan lehet csak simán szegmentálni. Saját nyelvtannal kiegészítve pedig határ a csillagos ég. És akkor még nem is beszültünk arról, hogy képes az elemzett szöveget xml-formátumban visszaadni, tehát az eredményen tovább dolgozhatunk például az NLTK-val... de erről majd csak később.

Egy-két javaslatot azért tennék a program használatához. A Huntoken mondatszegmentálót használja. Ezért a legjobb eredmény érdekében minden sorban csak egyetlen mondat szerepeljen! Továbbá mivel a szavak elemzéséhez a Hunmorph-ot használja, így nem számítsunk eredményre a tulajdonnevek és a szóösszetételek esetén. Ezeket nem tudja kezelni.

Továbbá álljon itt egy minta is. Példaként és a várható eredmények előrejelzése végett. Ezt a cikket elemeztettem le vele, egészen eddig a bekezdésig:

  • Összesen 26 mondat

  • 242 különböző szóalak

  • 30 olyan szó, aminek nem tudta meghatározni a szófajtát, felépítését (tulajdonnevek, formátumtípusok, webcímek és szóösszetételek)

  • 426 különböző felismert és elemzett szóalak (a kettő szám azért nem egyezik, az összes szóalak és az elemzett szóalakok száma, mert sok olyan szóalak van, ahol elképzelhető több elemzési eredmény a szövegkörnyezetnek megfelelően, de a program jelzi számunkra a lehetséges elemzéseket. Például a „szánom” két elemzési módja a következő: szánom,szán (szótő): N+nom+1+sg+pssg+ps vagy V+1+def+sg. Itt az emberi értelem meg tudja határozni, hogy az igei a helyes, de ezt csak jelentéstanilag tehetjük meg. Egy másik szövegkörnyezetben már főnévként szerepelhet.)


Szerző:

Gerő Dávid: Magyar és nyelvtechnológus hallgató, kezdő programozó és webfejlesztő, aki érdeklődik a nyelvészet és az informatika iránt. A határterületekért különösen rajongok, de sajnos mindkettőben csak kezdő, érdeklődő laikus vagyok.



2010. július 9.

Még több jazz-t az óvodákba, még több számítógépes nyelvészetet a gyerekeknek!

Ha jól mennek a dolgok, hamarosan vendég posztok jelennek meg a blogon :D  Az e-mailben jelentkező olvasók száma elérte a hármat (ez nekem nagy szám!), és remélem már gondolkodnak (vagy talán már írnak) hogy mi legyen. Mivel Google Analytics van a blogon, tudom hogy van pár visszatérő olvasó, ha akarnak nyugodtan írhatnak ők is. Gyorsan ide firkantom hogyan lehet belőled szerző:

  1. Keress egy témát ami illik a bloghoz. (azaz nyelvészet, számítógépes nyelvészet, logika, nyelvfilozófia, programozás vagy bármi)
  2. Írd meg a posztot.
  3. Csatold e-mailben (ehhez rá kell jönnöd a címemre, vagy a blog címére)
  4. Írd meg hogy milyen néven szeretnéd jegyezni írásodat. Ha egy profilt írsz, akkor az írás végére beszúrom. (Pl Jóska Pista vagyok n-edik évemet nyögöm (ill végeztem) az X egyetemen/főiskolán, itt dolgozom (ha van melód) főbb érdeklődési köröm. Legyen monnyuk egy bekezdés (6 mondat?))
  5. Vagy elfogadom prompt amit írtál, vagy indoklással megkérlek hogy módosíts rajta.
  6. Opcionális: ha akarod írj magadról pár sort. Hol tanultál/tanulsz, mit csinálsz. EZ NEM KÖTELEZŐ!
  7. Opcionális: ha fent vagy Facebook-on vagy engem, vagy a blogot vedd fel ismerősnek, könnyebb kommunikálni. EZ SEM KÖTELEZŐ!
A felkerült írással te rendelkezel, de fenntartom a jogok hogy előzetes értesítés után letöröljem azt. Ha fent van viszont bármikor kérheted a törlését, átszerkesztését, kommentjeinek cenzúrázását stb. Ez egy blog, lelkesedésből csinálom ezért tanácson kívül nem tudok másban segíteni és neved megemlítésén kívül (és az ezzel járó dicsőségről se feledkezzünk meg) mást nem adhatok!

Mit mutat a statisztika az olvasókról
A GA JavaScript kódot használ hogy nyomon kövesse kik látogatnak az oldalra ezért csak azokat számolja akik nem kapcsolják ki azt (vannak ilyenek, igaz kevesen, és ne felejtsük el a biztonság mániásokat akik NoScript plug-int használnak). Közelében sincs egy-egy népszerű blog által jelentett napi több ezres látogatottsághoz, annak ezreléke! Naponta kb 5-6 ember olvasgatja bejegyzéseimet, amennyire meg lehet állapítani 3/4 részül magyar szolgáltatótól jön. Sok címnél megyeszékhelyek vagy egyetemek láthatók még, ill a három nagy szolgáltató dominál. Hogyan kerülnek a blogra az olvasók? Direkt látogató kb a harmaduk (gondolom ők a visszatérők, talán?), 10%-uk rajtam keresztül (honlapom, Facebook ügyködésem stb), a többi keresés eredményeképpen (Google). A keresők általában a "nyelvészet" szóra keresnek legtöbbször a "számítógépes" szóval kiegészítve, de relatíve gyakoriak a következők "logika", "matematika", "programozás", "statisztika", "könyv".

Milyen visszajelzéseket kapok
Nos volt egy minősíthetetlen. Volt pár nagyon lehúzó, de egyáltalán nem leereszkedő. Komoly kritikákat kaptam, tanultam belőlük. De! Nem tudományos blogot írok. Amolyan csapongós, népszerűsítős helynek szánom a blogot, aki hiányolja a nagy elméleteket, az olvasson könyveket. A biztató szavakat nagyon köszönöm. Külön tetszik amikor kér valaki egy posztot valamiről. Ebből "rengeteg" van (21!), párat már teljesítettem, de nem hiszem hogy mindegyikre sor kerül (ugyanis nem értek mindenhez, így Zsófi kérését hogy a klasszika-filológia és a számítógépes nyelvészet kapcsolatát mutassam be, tutira nem fogom teljesíteni).

Mi lesz még

Vendég posztok! Nem csak a megkeresések (amiknek örülök), hanem felkérések is történtek. Persze a legtöbb akkor lesz realitás ha véget és a nyár. A hétvégén írtam pár barátomnak (sajnos valahogy itthon nem vagyok beágyazva, ezért külföldi barátaimnak szóltam) hogy segítsenek terjeszteni az igét. Röviden mire is lehet számítani:

  • Két korpusznyelvész (egy kedves jópofa és egy őrült evangelista) egy kicsit arról fog írni hogy mi is az a korpusznyelvészet
  • Egy számítógépes nyelvész az automatikus szövegkivonatolásról fog írni
  • Egy szintakta a nyelvevolúcióról és ha minden jól megy a nyelvtudományról (amolyan filozófiai izét)
  • Egy másik számítógépes nyelvész a munkájáról egy start up cégnél
  • Aztán egy kis pragmatika egy nagyon színes egyéniségtől
  • Terepmunka során szerzett adatok gépi feldolgozása (egy egy távoli egzotikus nyelvről van szó!)
  • Indián nyelvek megmentése és számítógépes nyelvészet
  • Ubiquity projekt
Köszönöm hogy olvastok (el sem tudjátok képzelni mit jelent ez nekem). Várom észrevételeiteket, kommenteljetek, írjatok, lájkoljatok stb. És ha akartok, vendégposztoljatok!

2010. július 4.

Szógyakoriság

Egyik kedvenc tanárom mesélte mindig hogy angolos hallgató korában a kiadott olvasmányokból szószedetet kellett készíteniük és amolyan röpdoli-szerűen számon kérték rajtuk a szavakat. Az én tanárom persze rögtön azon gondolkodott el hogy meddig kell elolvasnia egy adott könyvet hogy nagy valószínűséggel meglegyen neki a legtöbb szó. Egyszer amikor ezt mesélte hozzátette; mennyi szót kell ismernie egy helyesírás elemzőnek hogy jól működjön? Érdemes-e még több szót "belepakolni" hogy nagyon jól működjön? Most ezt a kérdés próbáljuk meg eldönteni, amolyan ránézésre!

Kellékek
gnuplot, Magyar Webkorpusz
Figyelem! Ha te is szeretnéd végig csinálni az "elemzést" akkor előbb telepítened kell a gnuplot-ot és le kell töltened a szövegfájlt!

Grafikus adatfelfedezés
Gyakran a legjobb megoldás egy problémára ha látod magad előtt. Ha olvasol újságot (amit nagyon remélek), biztos megnézed a grafikonokat. Pl ha a GDP eloszlásáról olvasol egy cikket az gyakran lehet száraz, de ha egy szép grafikon mutatja, akkor jobban értheted (és láthatod). Az Excell vagy az OpenOffice Calc csomagok laikusok számára is könnyen kezelhető vizualizációs eszközöket adnak a kezünkbe. Különösebb matematikai ismeretek nélkül is lehet szép grafikonokat alkotni hogy jobban megértsük adatainkat. Az ingyenesen elérhető, nyílt forráskódú gnuplot ebben segít. Mivel "programozható" nem köt minket az Excell vagy az OO előre megadott kerete. Interaktív, azaz kiadott parancsainkat hatását rögtön láthatjuk. Ezen tulajdonságok pedig lehetővé teszik hogy iteratív módon, kis lépésekben fedezzük fel és a számunkra legértelmesebb módon ábrázoljuk adatainkat.

A Magyar Webkorpusz

A magyar nyelvű web feltérképezését tűzte ki céljául a Magyar Webkorpusz. Minket ebből a szógyakorisági vizsgálat fájlja érdekel. Ez tartalmazza a 10000 leggyakoribb szót az első oszlopban. A második oszlopban az adott szavak előfordulása található. Az egyes elemek gyakoriságuk sorrendjében vannak sorba rendezve.

gnuplot
A gnuplot remekül illeszkedik a Unix rendszerek filozófiájába. Egy dolgot tud, de azt remekül! Ez pedig nem más mint az adatok megjelenítése, Ehhez szimpla szöveges fájlokra van szükségünk (a legtöbb táblázatkezelő tud sima fájlba menteni, ez különösen jó dolog ám). Ezt kihasználva sok más program, pl python vagy R is épít a gnuplot-ra, így nem árt legalább az alapjaival megismerkedned.

Gyors és egyszerű grafikon készítés
Arra vagyunk kíváncsiak hogy egy egy szó milyen gyakran fordul elő. Ez benne van a fájlban, de nagyon nehéz kibogarászni hogy egymáshoz viszonyítva mennyire gyakran fordul elő pl a 50,000. és a 70,000. elem. Próbáljuk meg ábrázolni s második oszlop (darabszámra hányszor fordultak elő az egyes szavak). Ehhez indítsd el a gnuplot-ot, majd gépeld be a következő parancsot:

> plot "web2.2-fre-sorted.top100k.txt" using ($2) with linespoints

Nem sok értelme van annak amit látunk. Miért? Mert nagy számokkal dolgozunk, amik ilyen léptékkel összeérnek ábrázoláskor. Erre jó a logaritmus. Vegyük az y tengelyt, az előfordulási számokat, logaritmikusra a következő paranccsal:

> set logscale y
és adjuk ki az első parancsot megint. Ez még mindíg nem az igazi, vegyük az x tengelyt is logaritmikusra

> set logscale x

és adjuk ki a következő parancsot.

> plot "web2.2-fre-sorted.top100k.txt" using ($2) with lines

Itt már nem a pontokat és az azokat összekötő vonalakat (with linespoints), hanem csak a vonalakat (lines) rajzoljuk ki. Ez már szebb, de még egy kicsit tegyük szebbé a "kilógó" és egyedi adatok kizárásával (és adjunk nevet a ).

> plot "web2.2-fre-sorted.top100k.txt" using ($2) title "Szogyakorisag" smooth unique with lines

Ha minden jól ment, akkor a következő ábrát kaptad te is.


Mit látunk?
Az y tengelyen azt láthatjuk hogy hányszor fordul elő egy adott szó, az x-en pedig hogy hanyadik a szó a listánkban. Hogy jobban láthassuk az eredményt, minden tengelyen logaritmust alkalmaztunk, így egy lépéssel nem egyet haladunk előre hanem 10-szeres nagyságrendet. Azt látjuk hogy az első tíz elem gyakorisága 10 a nyolcadikon és 10 a hetediken között van valahol, az első száz elemé pedig 10 a hatodikon körül van. Az első ezer elem után már csak 100,000-nél kevesebb előfordulást látunk, még a lista vége felé drasztikusan esik a gyakoriság.

Tudom hogy nem találtuk fel a spanyolviaszt, de könnyen és egyszerűen elemeztünk egy adathalmazt. Egy kis transzformációval még egyszerűbben értelmezhetővé tettük, így kvázi magáért beszél. Ja és a válasz! Rengeteg szót kellene a helyesírás ellenőrzőhöz adni hogy hiper-szuper legyen, nem éri meg, hiszen igen kis javuláshoz is rengeteg szót kell "belepakolnunk".
Ha bővebben érdekel a dolog
A Magyar Webkorpusz oldala (sajnos csak angolul találtam meg, ha megvan neked magyarul, kérlek írj).
Gnuplot in Action (Egy remek könyv erről az egyszerű, de csodálatos programról)