# IN1140 - gruppe 1 & 2 - annikaol # Eksempel: bigrams, trigrams import nltk nltk.download('inaugural') from nltk.corpus import inaugural from collections import Counter, defaultdict import numpy as np from nltk import bigrams, trigrams #print(inaugural.fileids()) print() # Henter ut hele "2017-Trump.txt" som en lang streng trump_raw = inaugural.raw("2017-Trump.txt") print(trump_raw) # Henter ut en liste av alle ord fra "2017-Trump.txt" trump_words = inaugural.words("2017-Trump.txt") # Henter ut en liste av alle setninger fra "2017-Trump.txt" trump_sents = inaugural.sents("2017-Trump.txt") # Finne antall ord total_words = len(trump_words) print("Nr. of words", total_words) # Finne antall unike ord (f.eks. "Eple" og "eple" telles bare 1 gang) distinct_words = [] for w in trump_words: distinct_words.append(w.lower()) total_distinct_words = len(set(distinct_words)) print("Nr. of types", total_distinct_words) print() # Oppretter en Counter som gir oss tellinger for hvert ord. fd_trump_words = Counter(trump_words) # Vi kan telle forekomster av ord med Counteren slik: print("10 mest vanlige ord: ", fd_trump_words.most_common(10)) print() print("Forekomster av 'peace': ", fd_trump_words["peace"]) print("Forekomster av 'great': ", fd_trump_words["great"]) print("Forekomster av 'the': ", fd_trump_words["the"]) print() # Lager en unigram-modell der vi ser p? frekvensen til hvert enkelt ord # Legger til sannsynlighetene for hvert ord i en ordbok, slik at: # - N?kkelen: ordet # - Verdien som h?rer til en n?kkel: sannsynligheten til ordet probabilities = {} for word, count in fd_trump_words.items(): probabilities[word] = count/total_words # Beregn sannsynligheten til hvert ord. #Summen av alle sannsynligheter er 1 - sjekk dette: print("Summen av alle sannsynligheter skal bli ca. 1: ",sum(probabilities.values())) print() # Genererer ny tekst basert p? unigram-modellen text = np.random.choice(list(probabilities.keys()), 20, p=list(probabilities.values())) print(" ".join(text)) print() # Beregner sannsynligheten for den genererte teksten - versjon 1 word_probabilities = [] for w in text: word_probabilities.append(probabilities[w]) # multipliser alle sannsynlighetene sammen print("Sannsynligheten for den genererte teksten, v1:", np.prod(word_probabilities)) # Beregner sannsynligheten for den genererte teksten - versjon 2 w_prob = 1 for w in text: w_prob *= probabilities[w] print("Sannsynligheten for den genererte teksten, v2:", w_prob) print() # Lage trigram-modell # F? setningene fra teksten - vi trenger konteksten for ? beregne sekvenser trump_sents = inaugural.sents("2017-Trump.txt") first_sentence = trump_sents[0] print(first_sentence) print() # Bigrammer = sekvenser p? 2 ord; trigramer = sekvenser p? 3 ord # Printer bigrammene til f?rste setning print("Bigram gir oss et generator-objekt: ", bigrams(first_sentence)) print() print("Bigram for f?rste setning: ", list(bigrams(first_sentence))) print("Trigram for f?rste setning: ", list(trigrams(first_sentence))) print() # Husk ? ha med mark?rer for start og slutt p? setningene! Det gj?res med pad_left og pad_right, slik: print("Bigram med og : ", list(bigrams(first_sentence, pad_left=True, pad_right=True))) print("Trigram med og : ", list(trigrams(first_sentence, pad_left=True, pad_right=True))) # Initialiserer frekvens dictionary og sannsynlighet dictionary # OBS: en defaultdict er en ordbok der vi gir en verdi (her 0), som er den verdien # hver nye n?kkel har innledningsvis(det vil si at hvis vi ikke har gitt en n?kkel # en verdi enn?, s? har den her verdien 0 eller 0.0). trigram_counts = defaultdict(lambda: defaultdict(lambda: 0)) # Denne teller trigrammene trigram_model = defaultdict(lambda: defaultdict(lambda: 0.0)) # Dette er den faktiske modellen v?r, med alle sannsynlighetene # Itererer gjennom trigrammene ved ? se p? hvert element i trigrammet samtidig for sentence in trump_sents: for w1, w2, w3 in trigrams(sentence, pad_right= True, pad_left = True): trigram_counts[(w1, w2)][w3] += 1 # Eksempler print() print("trigrams_counts[('God', 'bless')]['America'] =", trigram_counts[("God", "bless")]["America"]) print("trigrams_counts[('My', 'fellow')]['nonexisting'] =",trigram_counts[("My", "fellow")]["nonexisting"]) print() # Bruker sannsynlighetsregler for ? beregne sannsynligheten p? hver trigramsekvens # w1 er f?rste ord i trigrammet, w2 er andre, og w3 er tredje, # w1_w2 er dermed sekvensen av w1 og w2, disse behandler vi her som en enhet. for w1_w2 in trigram_counts: # Her finner vi totalt antall forekomster for bigrammet w1_w2. Denne bruker vi nedenfor # n?r vi skal inne sannsynligheten for trigrammet w1_w2_w3. total_trigramcounts = sum(trigram_counts[w1_w2].values()) for w3 in trigram_counts[w1_w2]: if total_trigramcounts: # Her oppdaterer vi verdiene i modellen trigram_model[w1_w2][w3] = trigram_counts[w1_w2][w3]/total_trigramcounts # Eksempler print("trigram_model[('God', 'bless')]['America'] =", trigram_model[("God", "bless")]["America"]) print('trigram_model[("My", "fellow")]["nonexisting"] =', trigram_model[("My", "fellow")]["nonexisting"]) # Generer tekst- initialiserer teksten med [None, None], som fungerer som startmark?rer. # Vi bruker 2 None fordi vi jobber med trigrammer(kun 1 n?r vi jobber med bigrammer). text = [None, None] sentence_is_finished = False while not sentence_is_finished: # Henter neste key: sekvens p? de f?rste 2 ordene i trigrammet key = tuple(text[-2:]) # Lager en liste av mulige ord words = list(trigram_model[key].keys()) # Henter sannsynlighetene til trigrammet probs = list(trigram_model[key].values()) # Legger til ett og ett ord text.append(np.random.choice(words, p = probs)) # Vi avslutter n?r de siste 2 ordene som ble generert er None (fungerer som sluttmark?rer) if text[-2:] == [None, None]: sentence_is_finished = True print() # Slik ser den genererte teksten ut (liste) f?r vi har gjort den om til en streng. print("Text as list: \n", text) print() # Lager en streng fra listen og tar vekk None elementene, slik at det ser ut som en # faktisk tekst. :) print("Text as string:") print(' '.join([t for t in text if t]))