Skoči na vsebino

Analiza besedil

Uporabo ukaznega jezika lupine pri reševanju problemov s pomočjo superračunalnika bomo prikazali na enem izmed postopkov, ki se pogosto uporablja pri rudarjenju besedil oziroma procesiranju naravnega jezika. Lotili se bomo problema štetja besed: odkriti želimo, kolikokrat se posamezna beseda pojavi v dani zbirki besedil. Pri tem se ne bomo spuščali v podrobnosti, omenimo le, da se tako zgrajena statistika neke zbirke besedil lahko kasneje uporabi pri generiranju naravnega jezika, analizi sentimenta, uvrščanju besedil, filtriranju neželene pošte in podobno.

Uporabili bomo preprost program, ki zna besedila obdelovati le enega za drugim. S pomočjo ukazne lupine bomo problem razdelili na podprobleme in jih obdelali vzporedno na gruči, brez sprememb v samem programu.

Podatki

Za vhodne podatke bomo uporabili podatkovno bazo uporabniških recenzij filmov na IMDb. Baza ima imeniško strukturo

aclImdb
├── README
├── test
│   ├── neg
│   │   ├── 0_2.txt
│   │   │   …
│   │   └── 9999_1.txt
│   └── pos
│       ├── 0_10.txt
│       │   …
│       └── 9999_10.txt
└── train
    ├── neg
    └── pos

Vsaka datoteka X_Y.txt vsebuje eno recenzijo; X predstavlja zaporedno številko recenzije, Y pa oceno, ki jo je recenzent namenil filmu. Recenzije so razdeljene v mape, ki predstavljajo testno test in učno množico train ter med negativne neg in pozitivne recenzije pos. Vsaka od teh map vsebuje 12.500 recenzij. Vsebino posamezne datoteke lahko izpišemo s programom cat:

$ cat aclImdb/test/neg/4435_1.txt
Legend has it that at the gala Hollywood premiere screening of 2001: A Space Odyssey, about 20 minutes into the film Rock Hudson yelled out "Would somebody please tell me what the hell this movie is about?" […]
cat aclImdb/test/neg/4435_1.txt

Program za štetje besed

Za štetje besed bomo vzeli preprost program count-words.py v Pythonu.

Koda programa count-words.py

1

Izvorna datoteka: count-words.py

Podrobnosti delovanja programa nas tu ne zanimajo. V splošnem niti ni nujno, da imamo dostop do izvorne kode programov, ki jih uporabljamo za obdelavo naših podatkov, ali pa je ta preveč kompleksna. Zato bomo tudi program count-words obravnavali kot nespremenljivo črno škatlo, ki jo bomo s pomočjo ukazne lupine poskušali uporabiti na način, ki ga pisec programa ni predvidel.

Kot večina programov tudi count-words ni popolnoma samostojen, temveč se naslanja na obstoječe programe in knjižnice. Kot skripta seveda potrebuje Python za izvajanje. Poleg tega za razčlenjevanje besedila in lematizacijo posameznih besed uporablja uveljavljeno knjižnico za delo z naravnim jezikom NLTK.

Okolje

V kasnejših poglavjih si bomo ogledali bolj robustno metodo za distribucijo programske opreme: vsebnike. V tem poglavju pa bomo uporabili kar standardno različico tolmača za Python, ki je v večini sistemov – tudi na gruči – že nameščen. Najprej naložimo modul Python:

$ module load Python
module load Python

Poleg samega tolmača moramo namestiti še modul NLTK, kar lahko naredimo na dva načina.

1. način: pip

Python ima svojo uradno zbirko dodatnih modulov Python Package Index. Paket nltk namestimo z ukazom

$ pip install --user nltk
Collecting nltk
[…]
Installing collected packages: tqdm, nltk
Successfully installed nltk-3.8.1 tqdm-4.65.0
pip install --user nltk

Vidimo, da pip poleg NLTK samodejno namesti še nekaj drugih paketov, ki jih ta potrebuje za delovanje. Zastavica --user poskrbi, da pip namesti module v naš domači imenik. Brez nje bi jih poskusil namestiti v sistemski imenik za vse uporabnike, kar mu brez skrbniškega dostopa ne bi uspelo. Tako nameščeni moduli se nahajajo v imeniku ~/.local/lib/pythonX.Y/site-packages/1.

Nameščeni moduli so na voljo tako na prijavnem kot na računskih vozliščih. NLTK za delo poleg programske kode, ki smo jo pravkar namestili, potrebuje še nekaj zbirk podatkov, ki jih prenesemo s pomočjo modula nltk.downloader:

$ python -m nltk.downloader averaged_perceptron_tagger omw-1.4 punkt wordnet
[nltk_data] Downloading package averaged_perceptron_tagger to
[nltk_data]     $HOME/nltk_data...
[nltk_data]   Unzipping taggers/averaged_perceptron_tagger.zip.
[…]
python -m nltk.downloader averaged_perceptron_tagger omw-1.4 punkt wordnet

Podatki se prenesejo v ~/nltk_data/.

2. način: conda

Namesto pip lahko za nameščanje knjižnic uporabimo tudi distribucijo conda, ki je del priljubljenega okolja za znanstveno delo Anaconda in poleg Pythona podpira tudi druge jezike. Na gruči privzeto ni nameščena, a je na voljo kot okoljski modul. Za začetek ga naložimo z

$ module load Anaconda3
module load Anaconda3

Ker conda ni nameščena sistemsko, temveč le za našega uporabnika, moramo pred uporabo sami nastaviti okolje z ukazom

$ source $(conda info --base)/etc/profile.d/conda.sh
source $(conda info --base)/etc/profile.d/conda.sh

Namig

Ta ukaz moramo pognati vsakič, ko se prijavimo v gručo. Alternativno ga lahko zapišemo na konec datoteke ~/.bashrc z echo source $(conda info --base)/etc/profile.d/conda.sh >> ~/.bashrc.

Nato ustvarimo in aktiviramo nov projekt conda kot običajno:

$ conda create --name moj-projekt nltk
$ conda activate moj-projekt
conda create --name moj-projekt nltk
conda activate moj-projekt

Kot pri prvi možnosti bo s tem NLTK na voljo tako na prijavnem kot na računskih vozliščih. Če še nismo, zdaj prenesemo še potrebne podatke z modulom nltk.downloader tako kot zgoraj.

Moduli ostanejo naloženi, dokler se ne odjavimo, zato jih moramo ob vsaki prijavi vnovič naložiti. Namesto tega lahko namestitev opravimo kar znotraj našega posla tako, da na začetek skripte za sbatch dodamo vrstice

module load Anaconda3
source $(conda info --base)/etc/profile.d/conda.sh
conda activate moj-projekt

Tako zagotovimo, da je ustrezno okolje vzpostavljeno vsakič, ko poženemo posel. Pred tem moramo moj-projekt ustvariti z ukazom conda create, kot zgoraj.

Preveri svoje znanje

Vaja

Vaja 01: pripravi podatke in okolje po navodilih.


  1. Znak ~ označuje domači imenik trenutnega uporabnika.