Språkteknologi
Laboration 3
Statistisk Lexikal Semantik: Random Indexing
Magnus Rosell
- Syfte
-
Syftet med laborationen är se att man kan utvinna oklassificerade semantiska relationer ur fritextdata.
- Uppgift
-
Din/er uppgift är att försöka lösa en del av "synonymtestet" ORD som ingår som en del i
Högskoleprovet. Grupper om upp till tre personer tillåts och tävling om vem som kan få flest rätt uppmuntras.
Först
Ögna igenom hela labbpeket innan du börjar,
i synnerhet det sista avsnittet, "Redovising".
Bakgrund
Random Indexing (RI) är ett sätt att utvinna relaterade ord ur fritext.
Varje ord associeras med en
Random Label,
en mångdimensionell vektor (tex 1800 dimensioner) med några få
slumpvis utvalda nollskilda element, tex fyra -1:or och fyra 1:or.
Metoden skapar sedan en
kontextvektor för varje ord
genom att gå igenom en textmängd ord för ord (
indexering).
Kring varje ord upprätthåller metoden ett
kontextfönster
på tex fyra ord före och fyra ord efter.
Då ett ord befinner sig i fokus (med kontextfönstret runt omkring sig)
adderar man till dess kontextvektor de omkringliggande ordens slumpvektorer (Random Label).
Man använder ett
viktningsschema för att vikta orden olika beroende tex avstånd till fokusordet eller någon annan egenskap hos kontextordet (oftast vill man att de ord som står närmast fokusordet ska bidra mest till
dess kontextvektor.)
Två ord som förekommer i liknande kontexter, dvs tillsammans med liknande ord,
kommer härigenom att få liknande kontextvektorer.
Man avgör deras likhet genom att jämföra kontextvektorerna med ett
avstånds- eller likhetsmått,
tex det kartesiska avståndet mellan dem.
För mer information om RI se
An Introduction to Random Indexing (pdf) och övriga texter på sidan för föreläsningen om
statistisk lexikal semantik.
I denna labb ska vi använda RI för att svara på frågor ur ORD-delen på
högskoleprovet (ett synonymtest). Varje fråga består av ett
ord och fyra närbesläktade ord. Testdeltagaren ska ange vilket ord som
är närmast i betydelse (det som är mest synonymt).
Javaprogrammet OrdHP.java tränar ett RI på en textmängd (träningsmängd)
och provar dess förmåga att gissa rätt på orden i en fil med frågor
(testmängd).
För att komma igång
Börja med att kopiera Random Indexing-paketet till din hemkatalog:
cp -r /info/sprakt08/ri/randomindexing/ .
Gå sedan in i Random Indexing-katalogen i din hemkatalog:
cd randomindexing/
Kör nu programmet OrdHP med träningsmängd ri_dataset1/
och testfilen test1.dat
:
java -Xmx1000m -cp lib:RI:OrdHP OrdHP /info/sprakt08/ri/ri_dataset1/ test1.dat
eller om du gör labben i Windowsmiljö (tex hemma, förutsatt att du kopierat även textmängderna):
java -Xmx1000m -cp lib;RI;OrdHP OrdHP ../ri_dataset1/ test1.dat
Hur många rätt fick du?
Hur många hade du fått om du chansat?
I katalogen results/
ligger nu en fil
i vilken resultatet finns att läsa.
Varje gång du kör OrdHP generaras en ny unik sådan fil. De är bra att ha
kvar när du ska jämföra resultatet för olika inställningar (se nedan).
Öppna filen och bekanta dig med resultatet.
Överst i filen finns information om
hur träningen gick till (mer om det senare). Sedan följer resultaten.
Först antal rätt och fel och sedan vilka ord som blev rätt och fel.
Med "Correct" menas de ord som programmet gett rätt svar på,
med "Missed" menas de som det inte gjorde rätt på och
med "Insufficient" menas de ord som träningsmängden inte gav tillräckligt
med information om.
Orden presenteras så här:
konstituera => inrätta [inrätta(0.205) avgöra(0.105) bekräfta(0.089) kritisera(0.071) slutföra(0.065)]
,
först ordet man söker synonym till, sedan den rätta synonymen
och därefter inom hakparenteser hur lika programmet tyckte att alternativen
var frågeordet (i fallande ordning). I det här exemplet har programmet alltså rätt!
Nu är det dags att du bekantar dig med test- och träningsmängderna.
Testmängd
De frågor du ska jobba med finns i filerna
test1.dat
och
test2.dat
.
Titta gärna i dem om du vill. Första ordet är frågeordet.
Siffran sist på varje rad anger vilket alternativ som är det rätta
(vi börjar räkna på 0).
Att det finns två olika tester beror på att de är anpassade till
de två träningsmängderna.
Träningsmängder
För att träningen ska ge någonting måste textmängden innehålla orden i testet.
Därför har vi laddat ned sidor från nätet som Google svarat att de ska innehålla dem.
I
/info/sprakt08/ri/ri_dataset1/
finns snippetar (de korta textsnuttar som Google
ger under varje länk) för orden. För att prova vissa saker som tar tid
har vi också gjort
ri_dataset0/
som bara innehåller några få filer.
I ri_dataset2/
finns hela texter som också hämtats med Google.
ri_dataset3/
innehåller länkar till båda textmängderna
och kan därför användas som en ännu större mängd.
Vi har också lemmatiserat
alla ord för att de olika formerna inte ska anses vara olika ord.
Titta på några av texterna i ri_dataset1/
och ri_dataset2/
.
Som du kan se har vi inte
tagit bort all engelsk text och alla adresser,
men det borde inte spela någon större roll.
För att få riktigt bra resultat måste man ha bra och stora träningsmängder.
Då tar emellertid indexeringen för lång tid för att det ska vara rimligt
att prova några olika faktorer under ett laborationspass.
Parametrar
Den första provkörning du gjorde ovan under "För att komma igång"
hade specifika inställningar.
Dessa är angivna i filen
TrainHP.properties
.
Det du ska göra är att ändra dessa och se om du kan få bättre resultat.
De parametrar i TrainHP.properties
som du kan ändra på är:
dimensionality = 1800
Dimensionen på vektorerna som representerar ordet (både Random Labels
och kontextvektorer har denna dimension).
random_degree = 8
Antalet 1:or och -1:or i en Random Label.
seed = 710225
Slumpfrö. Eftersom RI slumpar fram Random Labels
kan slumpen påverka resultatet.
left_window_size = 4
Antalet ord till vänster om fokusordet som används för att uppdatera
kontextvektorn.
right_window_size = 4
Antalet ord till höger om fokusordet som används för att uppdatera
kontextvektorn.
weighting_scheme = moj.ri.weighting.MangesWS
Viktningsschema. Mer om det i Extrauppgiften nedan.
stoplist = False
Om stopplista ska användas eller inte (se nedan).
stoplist_name = Stoplist.txt
Namnet på en eventuell stopplista.
shortest_word = 3
Kortare ord än det angivna värdet används inte vid indexeringen.
longest_word = 25
Längre ord än det angivna värdet används inte vid indexeringen.
minimum_words_per_file = 2
Lägsta antalet ord en fil måste innehålla för att indexeras.
Uppgifter
Gör följande två uppgifter.
-
Stopplista
Ändra från "False" till "True" för parametern stoplist
i TrainHP.properties
och kör igen på ri_dataset1/
.
Orden i stopplistan kommer nu inte att tas med i indexeringen.
Vad ger detta för resultat? Varför tror du?
-
Ändra parametrar
På vilket sätt tror du att de olika parametrarna kan påverka resultatet?
(Du behöver inte resonera om alla.)
Välj minst två parametrar att prova (stoplist
räknas inte).
Prova minst ett annat värde än
det som var från början. Får du bättre resultat?
På vilket sätt tror du att de olika parametrarna spelar olika roll
beroende på vilken textmängd man använder?
(Om du har tid: prova om du kan hitta någon parameter
som verkar ha olika inverkan då du kör på
ri_dataset1/
respektive ri_dataset2/
.)
Gör
minst en av följande uppgifter (den andra är svårare).
Gärna båda om du hinner.
-
Egna synonymer
Gör ett eget synonymtest i en fil som följer formatet i
testfilerna (du kan ha hur många synonymförslag som helst
till varje fråga). Prova tex om programmet tycker
att grammatiska ord (som tex "och" och "men") är mer lika varandra än
de som finns i någon av de ursprunglia testfilerna.
Då kan du behålla några av dessa i din nya fil.
Kom ihåg att bara använda ord i grundform (lemma)!
Tänk efter så att inställningarna inte gör det omöjligt för programmet att
lyckas (om du vill prova ordet "du" måste du tex ha
shortest_word = 2
).
Dessutom kan det vara så att andra inställningar är bättre för att lösa
just ditt synonymtest, men det hinner du nog inte undersöka så noga.
Var också medveten om att det finns en möjlighet
att de ord du är intresserad av inte finns med i träningsmängderna.
De är ju framtagna för det ursprungliga testet.
Det är alltså en fördel om du väljer rätt vanligt förekommande ord
som har en rimlig chans att förekomma i träningsmänderna.
-
Eget viktningsschema (kräver viss Java-vana.)
Det viktningsschema som använts hittills i labben (MangesWS.java)
finns tillsammans med ett par andra exempelklasser
(MartinsWS.java och RosellsWS.java) i katalogen
RI/moj/ri/weighting/
.
Gör ett eget viktningsschema genom att kopiera någon av exempelklasserna
och döpa om dem. Modifera sedan viktningsmetoderna
applyLeftWeighting()
och applyRightWeighting()
.
De beskriver hur ett av orden i kontextfönstret adderas till kontextvektorn
för fokusordet.
focusLabel
är fokusordets representation
focusContext
är fokusordets kontextvektor
distance
är avståndet till det ord vars Random Label ska adderas
xyzContextLabel
är representationen för det ord som ska
adderas till fokusordet (där xyz är left
eller right
)
negs
och poss
tilldelas arrayer med positioner
för de nollskilda elementen i Random Label för ordet som ska adderas.
Läs i dokumentationen för RI-paketet (javadoc-format)
som finns i doc-katalogen i labbpaketet.
Där kan du se vad som är möjligt att göra.
Naturligtvis finns det information om viktningsschemana där också.
Kom ihåg att kompilera ditt viktningsschema efter det att du
skapat det. Om du står i katalogen
randomindexing/RI/moj/ri/weighting/
när du kompilerar kan det t.ex. ske på följande vis:
javac -classpath ../../../ DittAlldelesEgnaWS.java
För att använda ditt viktningsschema måste du också ändra
parametern för weighting_scheme
i
TrainHP.properties
. Sedan kan du köra som vanligt.
En bra ide är att prova att det funkar på en liten träningsmängd
först, innan man ger på någon av de större.
Kan du få fler rätt med ditt viktningsschema än
med något av de vi redan skrivit?
Redovisning
Redovisa gör man för någon av assistenterna under labbpasset genom att
muntligen svara på de frågor som ställts i detta labbpek och
redogöra för de försök man genomfört (gärna genom att visa resultatfilerna).
Frågorna är till största delen av resonerande karaktär och
egentligen omöjliga att svara på genom att prova sig fram på så kort tid,
men vi vill ändå höra ett ärligt försök. Spekulera!
Ju fortare man redovisar desto mer förväntas man ha gjort.
OBS!
Om du under labben får felmeddelandet:
java: Command not found.
eller motsvarande, så är du tvungen att lägga till Java med kommandot:
module add jdk