Skip to content

Instantly share code, notes, and snippets.

@mjlassila
Created November 1, 2012 12:32
Show Gist options
  • Save mjlassila/3993384 to your computer and use it in GitHub Desktop.
Save mjlassila/3993384 to your computer and use it in GitHub Desktop.
ITIA41 - Viikkoharjoitukset 08
## Työskentely-ympäristön valmistelut ##
# Otetaan käyttöön Pythonin lokitustyökalu, että myöhemmin dokumentteja indeksoidessamme
# voimme pysymme selvillä, mitä komentojen suorittamisen aikana tapahtuu.
# Jos pidät taukoa tehtävien tekemisessä ja aloitat myöhemmin uudelleen,
# muista ottaa lokitus uudelleen käyttöön lokitus työskentelysi alussa.
# Samalla voidaan ottaa käyttöön pprint -moduuli, joknka avulla saadaan
# tulostettua muuttujien sisältöä tavallista tulostuskomentoa
# helppolukuisemmassa muodossa.
import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
import pprint
## Dokumenttien esikäsittely - Tehtävä 1 ##
# Kurssihakomistossa osoitteessa /home/courses/itima41 on viisi UTF-8 merkistöllä
# tallennettua dokumenttia (D1.txt, D2.txt, D3.txt, D4.txt ja D5.txt).
# Ladataan aluksi dokumentit työskentely-ympäristöön ja esikäsitellään ne
# hakujärjestelmään indeksoimista varten.
# Ladataan dokumentit ja tehdään esikäsittely.
import nltk
from nltk.tokenize import *
import codecs
documents = []
for i in range(1,6):
filename = '/home/courses/itima41/D'+ str(i) +'.txt'
document = codecs.open(filename, encoding='utf8').read()
documents.append(document)
punct = [',','.','!']
stopwords = nltk.corpus.stopwords.words('english')
stopword_or_punct = punct + stopwords
tokenized_documents = []
for document in documents:
tokenized_document = word_tokenize(document)
clean_document = [word.lower() for word in tokenized_document if word not in stopword_or_punct]
tokenized_documents.append(clean_document)
### Tehtävä 1 ###
# Tulosta dokumenttien sisältö listaksi, jossa rivin aloittaa
# dokumentin ID (aloitetaan laskenta nollasta). Kopioi tuloste tekstieditoriin
# (Notepad tai muu vastaava) sekä tallenna se myöhempää käyttöä varten.
# Palauta vastauksena tulostamasi lista.
## Sanakirjatiedoston muodostaminen - Tehtävä 2 ##
# Luodaan seuraavaksi hakujärjestelmän sanakirjatiedosto. Sanakirjatiedostoon
# tallennetaan dokumenttien sanoista esikäsittelyssä muodostetut indeksiavaimet,
# niiden tunnistenumerot sekä kunkin indeksiavaimen esiintymien yhteismäärä koko
# dokumenttikokoelmassa.
# Luodaan sanakirjatiedosto ja tutkitaan sitä.
import gensim
from gensim import corpora
dictionary = corpora.Dictionary(tokenized_documents)
# Kirjoitetaan sanakirjatiedosto kotihakemistoon tekstitiedostoon taulukoksi,
# jonka ensimmäisessä sarakkeessa on indeksiavaimen numero, toisessa indeksiavain
# merkkijonona ja kolmannessa indeksiavainten esiintymien lukumäärä koko
# dokumenttikokoelmassa.
dictionary.save_as_text('dictionary.txt')
# Kirjoitetaan lisäksi sanakirjatiedosto kotihakemistoon pakatussa muodossa.
# Tätä tiedostoa tarvitaan myöhemmissä tehtävissä.
dictionary.save('dictionary.dict')
### Tehtävä 2 ###
# Tutki levylle tekstitiedostoon tallennetun sanakirjatiedoston (dictionary.txt)
# sisältöä cat -komennolla ja kopioi tiedosto tekstieditoriin myöhempää käyttöä
# varten. Palauta vastauksena tekstitiedoston sisältö.
# Documenttivektorit - Tehtävä 3 #
# Tutustutaan seuraavaksi dokumenttien esittämiseen dokumenttivektoreina.
# Sanakirja tiedostoon tallennettuja indeksiavain-indeksiavaimen numero -pareihin
# perustuen voidaan ilmaista mikä tahansa muu sanakirjan sisältämiä sanoja sisältävä
# merkkijono vektorimuodossa.
# Katsotaan, miltä uusi sanakirjan sanoja sisältävä dokumentti näyttää
# vektorimuodossa. Tässä komento dictionary.doc2bow() muuttaa dokumentin
# niinsanottuun "Bag-of- words" -mallin mukaiseksi. Bag-of-Words mallin mukaan
# esitettynä dokumentti esitetään järjestämättömänä sanojen joukkona, toisin
# sanoen fraasit: "Hupu, Lupu ja Tupu" ja "Tupu, Hupu ja Lupu" ovat Bag-of-Words
# -mallissa esitettynä identtiset.
document_to_vectorize = "Tropical Freshwater Aquarium Fish And Saltwater Fish"
vectorized_document = dictionary.doc2bow(document_to_vectorize.lower().split())
>>> vectorized_document
[(2, 2), (4, 1), (9, 1), (19, 1), (22, 1)]
# Vektoroidaan dokumentit
vectorized_documents = []
for document_to_vectorize in tokenized_documents:
vectorized_document = dictionary.doc2bow(document_to_vectorize)
vectorized_documents.append(vectorized_document)
# Tallennetaan vektoroidut dokumentit levylle myöhempää käyttöä varten
from gensim import corpora
corpora.MmCorpus.serialize('corpus.mm', vectorized_documents)
### Tehtävä 3 ###
# Luo muuttuja another_document_to_vectorize ja tallenna siihen merkkijono
# "Keeping tropical fish and exotic spiders as pets"
# Muuta another_document_to_vectorize-muuttujan sisältö vektorimuotoon ja vertaa
# vektoriesitystä aiemmin luotuun vectorized_document -muuttujan sisältöön.
# Mitä eroja huomaat? Mistä erot johtuvat? Palauta vastauksena pohdintasi.
# TFIDF - Tehvävä 4
# Seuraavaksi laskemme dokumenttikokoelmamme sanoista muodostetuille
# indeksiavaimille painot sen mukaan, kuinka yleisiä/harvinaisia indeksiavaimet
# ovat dokumenttikokoelmassa. Luentokalvoissa 28 (Indeksointi) ja
# 29 (Avainten painot) kerrotaan laskennan suoritustavasta.
# Jollet ollut paikalla luennolla, osoitteessa
# http://www.youtube.com/watch?v=PhunzHqhKoQ oleva video on hyvä esitys aiheesta.
# Ladataan käyttöön työkalut hakemistojen ja sanakirjatiedostojen käsittelyä
# varten
from gensim import corpora, models, similarities
# Ladataan sanakirjatiedosto ja vektorimuodossa olevat dokumentit levyltä.
dictionary = corpora.Dictionary.load('dictionary.dict')
corpus = corpora.MmCorpus('corpus.mm')
# Lasketaan dokumenttikokoelmalle IDF-arvot.
tfidf = models.TfidfModel(corpus)
# Katsotaan dokumenttifrekvenssejä
pprint.pprint(tfidf.dfs)
# Katsotaan käänteisiä dokumenttifrekvenssejä
pprint.pprint(tfidf.idfs)
### Tehtävä 4 ###
# Ota Notepadiin tai muuhun vastaavaan editoriin talteen pprint-komentojen antamat
# tulostukset. Palauta vastauksena tulostukset.
## Dokumenttien painotetut ja painottamattomat vektorimuotoiset esitykset (Tehtävä 5) ##
# Edellisten työvaiheden jälkeen corpus-muuttujassa on dokumenttikokoelman
# vektorimuotoinen esitys. Katsotaan aluksi, miltä dokumentit näyttävät vektoreina:
for document in corpus:
pprint.pprint(document)
# Ota talteen tulostus kopioimalla se esimerkiksi Notepadiin tai
# vastaavaan tekstieditoriin.
# Tehdään seuraavaksi dokumenttien indeksiavaimille TF-IDF-painotus. Edellisten
# työvaiheiden jälkeen tfidf-muuttujaan on tallettennuta indeksiavainten dokumentti-
# frekvessit ja käänteiset dokumenttifrekvenssit. Nyt näitä käytetään laskettaessa
# indeksiavainten paino kussakin dokumentissa.
tfidf_corpus = tfidf[corpus]
for document in tfidf_corpus:
pprint.pprint(document)
# Ota talteen tulostus kopioimalla se esimerkiksi Notepadiin tai vastaavaan tekstieditoriin.
### Tehtävä 5 ###
# Palauta vastauksena indeksiavaimella 3 olevan dokumentin painottamaton ja
# painotettu vektorimuotoinen esitys.
## Käänteishakemisto - Tehtävä 6 ##
# Tutustu luentokalvoihin 10 - 14, alkaen kohdasta 5.2 Käänteistiedostot.
# Luodaan työskentely-ympäristöön muistissa oleva käänteishakemisto.
# num_features-parametrilla kerrotaan, että käyttämässämme sanakirjatiedostossa
# on 34 indeksiavainta.
search_index = similarities.SparseMatrixSimilarity(tfidf_corpus, num_features = 34)
# Tarkastellaan käänteishakemistoa. Python-työskentely-ympäristö esittää käänteis
# hakemiston selväkielisessä muodossa. Tietokoneen muistissa käänteistiedosto on
# esitettynä hakutehokkaana tietorakenteena, jonka yksityiskohdat voimme tällä
# kurssilla sivuuttaa.
>>> print search_index.index
# Esimerkkinä katkelma tulostuksesta indeksiavaimella 1 olevan dokumentin kohdalta
(1, 9) 0.134902
(1, 10) 0.0674512
(1, 12) 0.325037
(1, 13) 0.325037
(1, 14) 0.325037
(1, 15) 0.162518
(1, 16) 0.325037
(1, 17) 0.325037
(1, 18) 0.325037
(1, 19) 0.325037
(1, 20) 0.325037
(1, 21) 0.325037
# Tässä indeksitietue noudattaa rakennetta (osoitin, avain) paino. Osoittimet
# osoittavat tällä kertaa dokumentteihin erotukesena viidensien viikkoharjoitusten
# harjoitustehtävään, jossa käänteistiedostoon vietiin sanaosoitteet.
### Tehtävä 6 ###
# Palauta vastauksena katkelma käänteishakemistosta indeksinumerolla 3 olevan
# dokumentin kohdalta.
## Kyselyiden laatiminen - Tehtävä 7 ##
# Nyt kun dokumentit ovat hakujärjestelmämme indeksissa, voimme kokeilla joitain testihakuja. #
plain_text_query = "tropical freshwater aquarium fish"
# Muunnetaan kysely vektorimuotoon
vectorized_query = dictionary.doc2bow(plain_text_query.split())
vectorized_query
[(2, 1), (4, 1), (9, 1), (22, 1)]
query_results = search_index[vectorized_query]
# Katsotaan silmämääräisesti dokumenttien saamia arvoja
>>> list(enumerate(query_results))
[(0, 0.16471453), (1, 0.067451201), (2, 0.28326276), (3, 0.095919557), (4, 0.59116459)]
# Huomaa, että tulos ei ole palautettu dokumenttien relevanssijärjestyksesä.
# Mikä palautetuista dokumenteista on relevantein? Katso, mitä tässä
# dokumentissa lukee.
### Tehtävä 7 ###
# Palauta kyselyn palauttaman tulosjoukon relevanteimman dokumentin sisältö alkuperäismuodossaan.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment