diff --git a/run.py b/run.py index c3c2c00..4de8cda 100644 --- a/run.py +++ b/run.py @@ -52,6 +52,8 @@ def load_train(): def predict(search_for_words): trigrams_complete = {} # Tablica trigramów szukanych słów które wystąpiły w tekście z dokładnie tymi samymi szukanymi słowami w tej samej kolejności bigrams_complete = {} # Tablica bigramów szukanych słów które wystąpiły w tekście z dokładnie tymi samymi szukanymi słowami w tej samej kolejności + bigrams_not_complete = {} + trigrams_not_complete = {} # search_for_words_complete = [] # Tablica szukanych słów które wystąpiły w tekście z dokładnie tymi samymi szukanymi słowami w tej samej kolejności # Szukanie bigramów i trigramów które zawierają szukaną lukę dla słowa z tablicy search_for_words. # Jeżeli kolejność słów się zgadza liczona jest ilość wystąpień takich bigramów i trigramów z tymi słowami. @@ -71,6 +73,8 @@ def predict(search_for_words): search_for_word_s = search_for_word.split("_") if search_for_word_s[0] == word_bi_last and search_for_word_s[1] == word: # Jeżeli szukane słowa tworzą bigram występujący w tekście trenującym to zwiększamy liczbę jego wystąpień set_bigram_count(word_bi_last, word, bigrams_complete) + elif search_for_word_s[0] == word_bi_last: + set_bigram_count(word_bi_last, word, bigrams_not_complete) if i_ == 1: # If potrzebny aby zbuforować min 3 wyrazy dla trigramu w początkowej fazie przebiegu pętli. words[0]=word_bi_last words[1]=word @@ -80,6 +84,8 @@ def predict(search_for_words): search_for_word = search_for_word.split("_") if search_for_word[0] == words[1] and search_for_word[1] == words[2]: # Jeżeli szukane słowa należą do przedostatniego i ostatniego słowa trigramu to jest zwiększana liczba wystąpień tego trigramu. set_trigram_count(words[0], words[1], words[2], trigrams_complete) + elif search_for_word[0] == words[1]: + set_trigram_count(words[0], words[1], words[2], trigrams_not_complete) elif i_ > 2: # Jest to już ponad 2 przebieg pętli więc możemy rotować wyrazy jak w kolecje. Dla trigramów. words[0]=words[1] words[1]=words[2] @@ -87,52 +93,51 @@ def predict(search_for_words): for search_for_word in search_for_words: search_for_word = search_for_word.split("_") if search_for_word[0] == words[1] and search_for_word[1] == words[2]: - set_trigram_count(words[0], words[1], words[2], trigrams_complete) + set_trigram_count(words[0], words[1], words[2], trigrams_complete) + elif search_for_word[0] == words[1]: + set_trigram_count(words[0], words[1], words[2], trigrams_not_complete) word_bi_last = word if i_ == 500000: break - print (len(bigrams_complete)) - print (len(trigrams_complete)) - # Szukanie trigramu który najczęściej wystąpił dla każdych szukanych danych dwóch słów z tablicy serch_for_word. - # Z razcji z tego, że są to dokładnie te dwa słowa szukane mogę użyć słownika znalezionych bigramów - for trigram in trigrams_complete: - if trigram[0] == "_": - print(trigram) + print(len(search_for_words)) + print(len(bigrams_complete), len(bigrams_not_complete), len(bigrams_complete)+len(bigrams_not_complete)) + print(len(trigrams_complete), len(trigrams_not_complete), len(trigrams_complete)+len(trigrams_not_complete)) + # Szukanie trigramu który najczęściej wystąpił dla każdych dokadnie tych samych co szukanych danych dwóch słów z tablicy serch_for_word. + # Dotyczy dkoładnie pasujących bigramów z szukanymi słowami left_context_search_for_word = {} for bigram_complete in bigrams_complete: max_count = 0 for trigram in trigrams_complete: - if bigram_complete in '_'.join(trigram.split("_")[1:3]) and trigrams_complete[trigram] > max_count: + if bigram_complete == '_'.join(trigram.split("_")[1:3]) and trigrams_complete[trigram] > max_count: max_count = trigrams_complete[trigram] left_context = trigram.split("_")[0] left_context_search_for_word[bigram_complete] = left_context + + # Szukanie trigramu który najczęściej wystąpił dla pierwszego szukanego słowa z szukanych słów z tablicy serch_for_word. + # To w przypadku gdyby szukane słowa w ogóle nie znalazły swojego dopasowania w zbiorze train to wtedy dostaną jakieś tam prawdopodobieństwo dla tego pierwszego słow z szukanych słów. + left_context_search_for_word_not_complete = {} + for bigram_not_complete in bigrams_not_complete: + max_count = 0 + for trigram in trigrams_not_complete: + if bigram_not_complete == '_'.join(trigram.split("_")[1:3]) and trigrams_not_complete[trigram] > max_count: + max_count = trigrams_not_complete[trigram] + left_context = trigram.split("_")[0] + left_context_search_for_word_not_complete[bigram_not_complete] = left_context + for search_for_word in search_for_words: if search_for_word in left_context_search_for_word: left_context = left_context_search_for_word[search_for_word] print(f"{left_context} {' '.join(search_for_word.split('_'))} {trigrams_complete['_'.join([left_context, search_for_word])]/bigrams_complete[search_for_word]}") + elif search_for_word in left_context_search_for_word_not_complete: + print(f"{left_context} {' '.join(search_for_word.split('_'))} {trigrams_not_complete['_'.join([left_context, search_for_word])]/bigrams_not_complete[search_for_word]}") else: print(f"??? {' '.join(search_for_word.split('_'))}") - # max_count_t = 0 - # max_bi_key = "" - # max_count_b = 0 - # for key in bigrams: - # for key_t in trigrams: - # if key in key_t: - # if bigrams[key]>max_count_b: - # if key[0] != "_": - # max_count_b = bigrams[key] - # max_bi_key = key - # if trigrams[key_t]>max_count_t: - # if key_t[0] != "_": - # max_count_t = trigrams[key_t] - # max_key = key_t - # print(max_bi_key) - # print(max_key) - def load_dev(): + # Ładowanie zbioru testującego + # Luka została oznaczona jako znak tabulacji (\t) search_for_words = [] with lzma.open('dev-0/in.tsv.xz', mode='rt') as file: index = 0 @@ -141,21 +146,25 @@ def load_dev(): was_tab = False word_index_watch = 0 for line in file: + # Wczytanie linijiki i dzielenie jej na słowa, w przypadku napotkania luki (znaku \t) dodanie spacji aby oznaczyć jako słowo. Czyszczenie słów z różnych dziwnych znaków. for word in line.replace("\\n"," ").replace("\n","").translate(str.maketrans('','', string.punctuation)).replace("\t", " \t ").split(" "): word = word.lower() + if not word: # omijamy pusty znak wynikający z podziału przez spacje, dokońca nie wiem dlaczego się pojawia raczej nie powienien. + continue + # Napotkał lukę czyli kolejne dwa wyrazy będą brane jako bigramy i na tych bigramach (zmienna search_for_words) będzie dokonywana predykcja. if word == '\t': was_tab = True word_index_watch = 0 second_word = "" third_word = "" - elif was_tab: - if not second_word: - second_word = word - elif word_index_watch == 1: + elif was_tab: # Wystąpiła wcześniej luka (szukane pierwsze słowo) czyli zapisujemy słowo jako drugie słowo z bigramu, przeskakujemy iterację i potem zapisujemy trzecie słowo jeżeli w między czasie nie wystąpi jakaś luka inaczej zaczynamy proces od nowa. + if not second_word: # Sprawdzamy czy już drugie słowo nie zostało zbuforowane, jeżeli tak to oznacza, że teraz czekamy na trzecie słowo + second_word = word # Buforujemy drugie słowo + elif word_index_watch == 1: # Kolejna iteracja czyli jest to trzecie słowo z bigramu to zapisujemy szukany bigram third_word = word search_for_words.append(f"{second_word}_{third_word}") - was_tab = False - else: + was_tab = False # Oznaczamy, że dla tej luki mamy już bigram + else: # Jeżeli przekroczymy indeks słów to szkuamy kolejnej luki i resetujemy zmienne. W sumie do końca nie wiem czy to jest potrzebne was_tab = False second_word = "" third_word = ""