Analiza rymów w Panu Tadeuszu - Jakub Wysocki (319126), Sebastian Sikorski (319096)

Podstawy Reprezentacji i Analizy Danych 2022Z Prowadzący: prof. Marcin Iwanowski

Projekt ma na celu analizę Pana tadeusza pod względem rymów Pierwszym krokiem jest wczytanie pliku tekstowego z treścią poematu "Pan Tadeusz", źródło to https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt. Potem następuje tokenizacja tekst tak byśmy mogli odczytać ostatnie słowo każdego wersu.

In [1]:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# zmiana sposobu wyświetlania danych typu float
pd.options.display.float_format = "{:.3f}".format 
pantadeusz = []
ograniczniki = ["\\n", "'"]
with open('dane/pan Tadeusz.txt', encoding='utf-8') as f:
    for line in f:
        linijka = repr(line)
        for znak in ograniczniki:
            linijka = linijka.replace(znak,"")
        if not(linijka == ""):
            pantadeusz.append(linijka)
ksiegi = []
for linijka in pantadeusz:
    slowa_linijki = linijka.split()
    if (len(slowa_linijki)==2): # dwuwyrazowe linijki 
        if (slowa_linijki[0] == 'Księga'): # pierwszy wyraz powinien brzmieć 'księga'
            ksiegi.append(slowa_linijki[1])


# Tokenizacja
PanTadeusz = []
niepotrzebne_znaki = ["!",",", ".","    ",":",";","?","(",")","— ","*","»","…","«","—","-","/"] 
rodzaj_tekstu = "inny"
mamKsiege = False
mamTytul = False
tekstKsiegi = False
for linijka in pantadeusz:
    if rodzaj_tekstu == "streszczenie":
        rodzaj_tekstu = "tresc"
    elif rodzaj_tekstu == "tytul":
        rodzaj_tekstu = "streszczenie"
        ksiega["streszczenie"] = linijka
    elif rodzaj_tekstu == "naglowek":
        rodzaj_tekstu = "tytul"
        ksiega["tytul"] = linijka   
    slowa_linijki = linijka.split()
    if (len(slowa_linijki) in [1,2]): 
        if slowa_linijki[0] == 'Księga':
            if rodzaj_tekstu == "tresc": 
                ksiega["wersy"] = tresc
                PanTadeusz.append(ksiega) # zapisz poprzednią księgę
            rodzaj_tekstu = "naglowek"
            tresc = []
            ksiega = {"numer":slowa_linijki[1],
                      "tytul":"",
                      "streszczenie":"",
                      "wersy":[]}
        elif slowa_linijki[0] == 'Epilog':
            ksiega["wersy"] = tresc
            PanTadeusz.append(ksiega) # zapisz dwunastą księgę
            rodzaj_tekstu = "streszczenie" 
            tresc = []
            ksiega = {"numer":"epilog",
                      "tytul":"Epilog",
                      "streszczenie":"",
                      "wersy":[]}   
        elif slowa_linijki[0] == '-----':
            ksiega["wersy"] = tresc
            PanTadeusz.append(ksiega) # zapisz epilog
            rodzaj_tekstu = "inne" 
    if rodzaj_tekstu == "tresc":
        for znak in niepotrzebne_znaki:
            linijka = linijka.replace(znak,"").lower()
        tresc.append(linijka.split())

Definiowanie niezbędnych funkcji

In [2]:
# rozkładanie słowa na sylaby, każda sylaba musi mieć w sobie samogłoskę,
# co jest elementem decydującym w funkcji
def ilosc_sylab_w_slowie(str):
    samogloski = ["ę","e","é","y","u","i","a","ą","o","ó"]
    sam = False
    syl = 0
    for i in range(0,len(str)):
        if sam:
            if str[i] in samogloski:
                pass
            else:
                sam = False
        else:
            if str[i] in samogloski:
                syl += 1
                sam = True
    return syl    

# analogicznie liczymy sylaby w końcówce słowa
def ilosc_sylab_w_koncowce(str):
    samogloski = ["ę","e","é","y","u","i","a","ą","o","ó"]
    sam = False
    sol = True
    syl = 0
    for i in range(0,len(str)):
        if sam:
            if str[i] in samogloski:
                pass
            else:
                sam = False
                sol = False
        else:
            if str[i] in samogloski:
                syl += 1
                sam = True
            else:
                sol = False
    if sol:
        return 0
    return syl 

# funkcja zwracająca wspólną końcówkę dwóch słów
def rymy_koncowe(str1, str2):
    i1 = len(str1) - 1
    i2 = len(str2) - 1
    i1m = i1
    i2m = i2
    flag = True
    while(i1 > -1 and i2 > -1):
        if str1[i1] != str2[i2]:
            flag = True
            for x in litery:
                wynik = x(str1,str2,i1,i2,i1m,i2m)
                if wynik[0]:
                    flag = False
                    i1 -= wynik[1]
                    i2 -= wynik[2]
                    break
            if flag:
                break
        i1 -= 1
        i2 -= 1
    if i1 == len(str1) - 1 or i2 == len(str2) - 1:
        return("","")
    return(str1[i1+1:], str2[i2+1:])

# funkcja sprawdzająca, czy sylaby się rymują
def rymuje_sie(koncowki):
    s1 = ilosc_sylab_w_koncowce(koncowki[0])
    if  s1 < 1:
        return False
    s2 = ilosc_sylab_w_koncowce(koncowki[1])
    if s1 == s2 or (s1 >1 and s2 >1):
        return True
    return False   

# funkcja zwracająca długość wspólnej końcówki dwóch słów
def dlugosc(str1, str2):
    return len(rymy_koncowe(str1, str2)[0])

# rozkład rymów na monorymy, rymy krzywe, okalające i na wyrazy nie rymujące się
def okresl_rymy(PanT,OkW):
    zbr = []
    for ksiega in PanT:
        zbr.append({"monorymy" : {2:[], 3:[], 4:[]}, "krzywe" : [], "okalajance" : [], "inne" : []})
    for i in range(0,len(PanT)):
        lista_wersow = PanTadeusz[i]["wersy"]
        stan = 0
        drugi = lista_wersow[0][-1]
        czwarty = drugi
        trzeci = drugi
        koncowki = ()
        kolor = 1
        for wers_i in range(1,len(lista_wersow )):
            pierwszy = lista_wersow[wers_i][-1]
            #print(pierwszy+" "+drugi+" "+trzeci+" "+czwarty+" "+str(stan)+" "+str(wers_i))
            if stan == 0:
                koncowki = rymy_koncowe(pierwszy,drugi)
                if rymuje_sie(koncowki):
                    stan = 5
                else:
                    stan = 1
            elif stan == -1:
                stan = 0
            elif stan == 1:
                if rymuje_sie(rymy_koncowe(pierwszy,trzeci)):
                    stan = 2
                elif rymuje_sie(rymy_koncowe(drugi,pierwszy)):
                    stan = 3
                else:
                    stan = 0
                    if rymuje_sie(rymy_koncowe(trzeci,drugi)):
                        OkW[i][wers_i - 2]["kolor"] = kolor
                        OkW[i][wers_i - 2]["typ"] = "P"
                        OkW[i][wers_i - 1]["kolor"] = kolor
                        OkW[i][wers_i - 1]["typ"] = "P"
                        kolor += 1
                        zbr[i]["monorymy"][2].append(rymy_koncowe(trzeci,drugi))
                    else:
                        OkW[i][wers_i - 2]["kolor"] = 0
                        OkW[i][wers_i - 2]["typ"] = "I"
                        OkW[i][wers_i - 1]["kolor"] = 0
                        OkW[i][wers_i - 1]["typ"] = "I"
                        zbr[i]["inne"].append(trzeci + " " + drugi)
            elif stan == 2:
                if rymuje_sie(rymy_koncowe(pierwszy,trzeci)):
                    zbr[i]["krzywe"].append( pierwszy+" "+drugi + " " +drugi+" "+czwarty)
                    koncowki = rymy_koncowe(pierwszy,trzeci)
                    OkW[i][wers_i]["kolor"] = kolor
                    OkW[i][wers_i]["typ"] = "K"
                    OkW[i][wers_i]["ile"] = len(koncowki[0])
                    OkW[i][wers_i - 2]["kolor"] = kolor + 1
                    OkW[i][wers_i - 2]["typ"] = "K"
                    OkW[i][wers_i - 2]["ile"] = len(koncowki[1])
                    koncowki = rymy_koncowe(drugi,czwarty)
                    OkW[i][wers_i - 3]["kolor"] = kolor
                    OkW[i][wers_i - 3]["typ"] = "K"
                    OkW[i][wers_i - 3]["ile"] = len(koncowki[1])
                    OkW[i][wers_i - 1]["kolor"] = kolor + 1
                    OkW[i][wers_i - 1]["typ"] = "K"
                    OkW[i][wers_i - 1]["ile"] = len(koncowki[0])
                    stan = -1
                else:
                    zbr[i]["inne"].append(drugi + " " + trzeci + " " + czwarty)
                    stan = 0
            elif stan == 3:
                if rymuje_sie(rymy_koncowe(pierwszy,czwarty)):
                    zbr[i]["okalajance"].append(pierwszy+" "+drugi + " " + trzeci+" "+czwarty)
                    koncowki = rymy_koncowe(pierwszy,czwarty)
                    OkW[i][wers_i - 3]["kolor"] = kolor
                    OkW[i][wers_i - 3]["typ"] = "O"
                    OkW[i][wers_i - 3]["ile"] = len(koncowki[1])
                    OkW[i][wers_i]["kolor"] = kolor
                    OkW[i][wers_i]["typ"] = "O"
                    OkW[i][wers_i]["ile"] = len(koncowki[0])
                    koncowki = rymy_koncowe(drugi,trzeci)
                    OkW[i][wers_i - 2]["kolor"] = kolor + 1
                    OkW[i][wers_i - 2]["typ"] = "O"
                    OkW[i][wers_i - 2]["ile"] = len(koncowki[1])
                    OkW[i][wers_i - 1]["kolor"] = kolor + 1
                    OkW[i][wers_i - 1]["typ"] = "O"
                    OkW[i][wers_i - 1]["ile"] = len(koncowki[0])
                    kolor += 2
                    stan = -1

                else:
                    zbr[i]["monorymy"][2].append(rymy_koncowe(drugi,trzeci))
                    OkW[i][wers_i - 2]["kolor"] = kolor
                    OkW[i][wers_i - 2]["typ"] = "P"
                    OkW[i][wers_i - 1]["kolor"] = kolor
                    OkW[i][wers_i - 1]["typ"] = "P"
                    kolor += 1
                    zbr[i]["inne"].append(czwarty)
                    stan = 0
            elif stan > 4:
                if rymuje_sie((rymy_koncowe(pierwszy,drugi)[1],koncowki[1])):
                    stan += 1
                else:
                    if stan > 5:
                        if ilosc_sylab_w_koncowce(rymy_koncowe(pierwszy,drugi)[0]) > ilosc_sylab_w_koncowce(koncowki[0]):
                            zbr[i]["monorymy"][stan - 4].append(koncowki)
                            stan = -5
                            koncowki = rymy_koncowe(pierwszy,drugi)
                        else:
                            for ik in range(stan-3):
                                OkW[i][wers_i - 1 - ik]["kolor"] = kolor
                                OkW[i][wers_i - 1 - ik]["typ"] = "M"
                                OkW[i][wers_i - 1 - ik]["ile"] = len(koncowki[0])
                            kolor += 1
                            zbr[i]["monorymy"][stan - 3].append((drugi,trzeci,czwarty))
                    else:
                        OkW[i][wers_i - 2]["kolor"] = kolor
                        OkW[i][wers_i - 2]["typ"] = "P"
                        OkW[i][wers_i - 2]["ile"] = len(koncowki[0])
                        OkW[i][wers_i - 1]["kolor"] = kolor
                        OkW[i][wers_i - 1]["typ"] = "P"
                        OkW[i][wers_i - 1]["ile"] = len(koncowki[1])
                        kolor += 1
                        zbr[i]["monorymy"][2].append(koncowki)
                    if stan== -5:
                        stan = 5
                    else:
                        stan = 0
            czwarty = trzeci
            trzeci = drugi
            drugi = pierwszy
        if stan == 0:
            zbr[i]["inne"].append(pierwszy)
        elif stan == 1:
            zbr[i]["inne"].append(trzeci + " " + pierwszy)
        elif stan == 2:
            zbr[i]["inne"].append(trzeci + " " + czwarty + " " + pierwszy)
        elif stan == 3:
            zbr[i]["inne"].append(trzeci + " " + czwarty + " " + pierwszy)
        elif stan > 4:
            if stan > 5:
                zbr[i]["monorymy"][stan - 3].append(rymy_koncowe(rymy_koncowe(drugi,trzeci)[0],czwarty))
                for ik in range(stan-3):
                    OkW[i][wers_i - ik]["kolor"] = kolor
                    OkW[i][wers_i - ik]["typ"] = "M"
                    OkW[i][wers_i - ik]["ile"] = len(koncowki[0])
            else:
                zbr[i]["monorymy"][stan - 3].append(rymy_koncowe(pierwszy,drugi))
                OkW[i][wers_i - 1]["kolor"] = kolor
                OkW[i][wers_i - 1]["typ"] = "P"
                OkW[i][wers_i - 1]["ile"] = len(koncowki[0])
                OkW[i][wers_i]["kolor"] = kolor
                OkW[i][wers_i]["typ"] = "P"
                OkW[i][wers_i]["ile"] = len(koncowki[1])
    return zbr

# funkcja wypisująca rozkład rymów w poszczególnych księgach z
# uwzględnieniem podziału na monorymy (2,3,4-członowe, rymy krzywe itd.)
def stastyki(zbr):
    nazwy = ["Księga " + i["numer"] for i in PanTadeusz]
    nazwy[-1] = PanTadeusz[-1]["numer"]
    df = pd.DataFrame({'Parzyste': pd.Series(len(zbr[i]['monorymy'][2]) for i in list(range(len(PanTadeusz)))),'Monorymy 3': pd.Series(len(zbr[i]['monorymy'][3])for i in list(range(len(PanTadeusz)))),'Monorymy 4': pd.Series(len(zbr[i]['monorymy'][4])for i in list(range(len(PanTadeusz)))),'Krzywe': pd.Series(len(zbr[i]['krzywe'])for i in list(range(len(PanTadeusz)))),'Okalajance': pd.Series(len(zbr[i]['okalajance'])for i in list(range(len(PanTadeusz)))),'Inne': pd.Series(len(zbr[i]['inne'])for i in list(range(len(PanTadeusz))))})
    df.index = nazwy
    return df

# funkcja rysująca wykresu statystyki rymów dla poszczególnych ksiąg
def Wykresy_rymow(df):
    nazwy = ["Księga " + i["numer"] for i in PanTadeusz]
    nazwy[-1] = PanTadeusz[-1]["numer"]
    plt.figure(figsize=(10,65))
    for i in range(13):
        plt.subplot(7,2,i+1)
        df.iloc[i].plot(kind='bar',title=(nazwy[i]),grid=True)
        
# wypisanie najczęstszych rymów w zbiorze powyżej pewnego progu
def pokaz_czeste(slownik,prog):
    for klucz,wartosc in slownik.items():
        if wartosc>prog:
            print(klucz,":",wartosc)
            
# utworzenie słownika rymów
def utworz_slownik(lista_slow):
    slownik = {}
    for slowo in sorted(lista_slow):
        if slowo in slownik.keys():
            slownik[slowo] = slownik[slowo] + 1
        else:
            slownik[slowo] = 1
    return slownik

# wypisanie słownika
def pokaz_slownik(slownik,zakres):
    dlugosc = len(slownik)
    if zakres[0]<0: zakres[0]=0
    if zakres[1]>dlugosc: zakres[1]=dlugosc
    if zakres[1]>zakres[0]:
        i = 0
        for klucz,wartosc in slownik.items():
            if i>=zakres[0] and i<zakres[1]:
                print(klucz,":",wartosc)
            i = i+1
            
# utworzenie macierzy dla ksiąg - ile razy dany rym wystąpił w konkretnej księdze 
def tdmPT(slownik,prog_czestosci): 
    nazwy_czesci = "K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 Epilog".split()
    tdm = pd.DataFrame(columns=nazwy_czesci)
    for slowo,ile_razy in slownik.items():
        if ile_razy > prog_czestosci:
            licznik = [0]*13
            for i in range(0,13):
                for token in tokeny_rymy[i]:
                    if slowo == token:
                        licznik[i] = licznik[i] + 1   
            element = pd.DataFrame([licznik], columns=nazwy_czesci, index = [slowo])
            tdm = tdm.append(element)
    return tdm

# tworzenie macierzy TFIDF - jedna z metod obliczania wagi słów w oparciu o liczbę ich wystąpień
def policz_tfidf(tdm):
    ile_slow = tdm.count(0)[0]
    tf = np.empty((ile_slow,13))
    for i in range(0,13):
        tf[:,i] = np.array(tdm.iloc[:,i]/tdm.sum()[i])
    idf = np.log(13/np.array((tdm>0)*1).sum(axis=1))
    tfidf = pd.DataFrame((tf*np.array([idf,]*13).T*100), columns=tdm.columns, index = tdm.index)
    tfidf["w_ilu"] = (np.array((tdm>0)*1).sum(axis=1)).T
    tfidf["idf"] = idf.T
    return tfidf

# obliczanie odległości między rymami
def odleglosc(x, y, typ = 'kosinusowa'):
    if typ == 'kosinusowa':
        return np.dot(x, y) / (np.sqrt(np.dot(x, x)) * np.sqrt(np.dot(y, y)))
    elif typ == 'Euklidesowa':
        return np.sqrt(np.sum((x - y) ** 2))
    else: # miejska
        return np.sum(np.abs(x - y))
    
# Przedstawienie graficzne klasyfikacji poszczególnych wersów
def wypisz_wersy(OkW,Ksiega,star,koniec):
    if koniec == -1:
        koniec = len(OkW[Ksiega])
    kolory =["\033[0;31m","\033[0;32m","\033[0;33m","\033[0;34m","\033[0;35m","\033[0;36m","\033[0;37m"]
    lk = len(kolory)
    end = "\033[0m"
    for i in range(star,koniec):
        ok = OkW[Ksiega][i]["kolor"]
        for slowo in OkW[Ksiega][i]["tekst"][0:-1]:
            print(slowo , end=" "),
        if ok == 0:
            print(OkW[Ksiega][i]["tekst"][-1]+ " "+ OkW[Ksiega][i]["typ"])
        else:
            print(OkW[Ksiega][i]["tekst"][-1][:-OkW[Ksiega][i]["ile"]]+ f"{kolory[ ok % lk ] }" +OkW[Ksiega][i]["tekst"][-1][-OkW[Ksiega][i]["ile"]:]+ " "+ OkW[Ksiega][i]["typ"] + f"{end}")
        
In [3]:
# usunięcie linijek które są rozdzielone w pliku 
flag = True
for z in PanTadeusz[0:-1]:
    dous = []
    for i in range(len(z["wersy"])): 
        suma = 0
        for wy in z["wersy"][i]:
            suma += ilosc_sylab_w_slowie(wy)
        if flag and suma < 11:
            dous.append(i)
            flag = False
        else:
            flag = True
    for j in dous[::-1]:
        z["wersy"].pop(j)

Teraz następuje pierwsza próba znajdowania rumów na razie żeby dwie końcówki zostały uznane za rymy muszą być one takie same oraz ta wspólna część musi mieć co najmniej jedną sylabę. Ilość sylab wyznaczana jest poprzez liczbę zgrupowań samogłosek (może być jedna) rozdzielonych przez spółgłoski.

In [4]:
# Tablica na końcówki sklasyfikowanych rymów.
litery = []
# Tworzenie tablicy do wizualizacji klasyfikacji.
OkresloneWersy = []
for i in range(len(PanTadeusz)):
    OkresloneWersy.append([])
    for wer in PanTadeusz[i]["wersy"]:
        OkresloneWersy[i].append({"tekst" : [], "kolor" : 0 , "typ": "I","ile":3})
        OkresloneWersy[i][-1]["tekst"] = wer
        

zbr = okresl_rymy(PanTadeusz,OkresloneWersy)
In [5]:
df = stastyki(zbr)
df
Out[5]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 451 4 0 0 0 36
Księga druga 394 1 0 0 0 31
Księga trzecia 362 1 0 0 0 31
Księga czwarta 460 2 0 0 0 38
Księga piąta 408 1 1 0 0 42
Księga szósta 277 6 0 0 0 22
Księga siódma 242 10 0 0 1 20
Księga ósma 365 6 0 0 0 28
Księga dziewiąta 345 9 0 0 0 23
Księga dziesiąta 396 5 1 0 0 35
Księga jedenasta 300 6 0 0 0 34
Księga dwunasta 384 10 0 0 0 34
epilog 49 6 0 0 1 8

Macierz powyżej przedstawia wynik pierwszej klasyfikacji. Rymy parzyste to rymy gdzie rymują się dwa kolejny wersy, monorymy 3 i 4 oznacza że rymują się odpowiednio trzy i cztery kolejne wersy, krzywe to typu ABAB, okalające to typ ABBA, inne to te które nie udało się sklasyfikować. Widać że znaczna większość stanowi rymy parzyste oraz że nie udało się sklasyfikować średnio 30 rymów na księgę. Poniżej są przedstawione te dane na wykresach słupkowych.

In [6]:
Wykresy_rymow(df)

Teraz następuje proces dodawania kolejnych warunków w których różne litery możemy potraktować jako takie które sobie odpowiadają. Po dodaniu tych warunków wyświetlana jest nowa macierz która reprezentuje obecny wynik klasyfikacji, a pod nią przedstawiane są zmiany jakie zaszły w porównaniu z poprzednią wersją.

In [7]:
# Dodając polskie odpowiadające sobie litery

# rz - ż (każe gospodarze)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'z' and str2[i2] == "ż" and str1[i1-1] == 'r',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="ż" and str2[i2] == "z" and str2[i2-1] == 'r',0,1))

# u - ó 
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["u", "ó"] and str2[i2] in ["ó", "u"],0,0))
In [8]:
zbr = okresl_rymy(PanTadeusz,OkresloneWersy)
df2 = stastyki(zbr)
df2
Out[8]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 456 4 0 0 0 31
Księga druga 397 1 0 0 0 28
Księga trzecia 364 1 0 0 0 29
Księga czwarta 462 2 0 0 0 36
Księga piąta 415 1 1 0 0 35
Księga szósta 278 6 0 0 0 21
Księga siódma 242 10 0 0 1 20
Księga ósma 369 7 0 0 0 23
Księga dziewiąta 348 9 0 0 0 20
Księga dziesiąta 400 5 0 0 0 33
Księga jedenasta 302 7 0 0 0 30
Księga dwunasta 388 10 0 0 0 30
epilog 51 6 0 0 1 6
In [9]:
df2 - df
Out[9]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 5 0 0 0 0 -5
Księga druga 3 0 0 0 0 -3
Księga trzecia 2 0 0 0 0 -2
Księga czwarta 2 0 0 0 0 -2
Księga piąta 7 0 0 0 0 -7
Księga szósta 1 0 0 0 0 -1
Księga siódma 0 0 0 0 0 0
Księga ósma 4 1 0 0 0 -5
Księga dziewiąta 3 0 0 0 0 -3
Księga dziesiąta 4 0 -1 0 0 -2
Księga jedenasta 2 1 0 0 0 -4
Księga dwunasta 4 0 0 0 0 -4
epilog 2 0 0 0 0 -2
In [10]:
#samogłoski nosową ą - ę
# en - ę (ręce sukience)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'n' and str2[i2] == "ę" and str1[i1-1] == 'e',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] == "ę" and str2[i2] == "n" and str2[i2-1] == 'e',0,1))

# e - ę (krzyknęli spółobywateli)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["e", "ę"] and str2[i2] in ["e", "ę"],0,0))

 # on - ą (kabłąki dzwonki)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'n' and str2[i2] == "ą" and str1[i1-1] == 'o',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] == "ą" and str2[i2] == "n" and str2[i2-1] == 'o',0,1))

#wymiana ą - a / ą - o / o - a (łono utęsknioną)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 == i1m and str1[i1] in ["ą","o", "a"] and str2[i2] in ["a","o", "ą"],0,0))

litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1m == i1 and str1[i1] in ["e", "ę"] and str2[i2] in ["e", "ę"],0,0))

# en - eń (sukience wieńce)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 1 and i2 > 1 and str1[i1] == 'n' and str2[i2] == "ń" and str1[i1-1] == 'e' and str2[i2-1] == 'e',1,1))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and i1 > 1 and i2 > 1 and str1[i1] == "ń" and str2[i2] == "n" and str2[i2-1] == 'e' and str1[i1-1] == 'e',1,1))

# ę  - eń (maleńka klęka) 
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'ń' and str2[i2] == "ę" and str1[i1-1] == 'e',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] == "ę" and str2[i2] == "ń" and str2[i2-1] == 'e',0,1))
In [11]:
zbr = okresl_rymy(PanTadeusz,OkresloneWersy)
df3 = stastyki(zbr)
df3
Out[11]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 480 5 0 0 0 5
Księga druga 420 1 0 0 0 5
Księga trzecia 384 1 0 0 0 9
Księga czwarta 487 2 0 0 0 11
Księga piąta 441 2 2 0 0 5
Księga szósta 298 6 0 0 0 1
Księga siódma 251 11 2 0 0 6
Księga ósma 388 7 0 0 0 4
Księga dziewiąta 362 9 0 0 0 6
Księga dziesiąta 421 5 1 0 0 10
Księga jedenasta 323 8 0 0 0 8
Księga dwunasta 406 10 1 0 0 10
epilog 51 7 0 0 1 4
In [12]:
df3 - df2
Out[12]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 24 1 0 0 0 -26
Księga druga 23 0 0 0 0 -23
Księga trzecia 20 0 0 0 0 -20
Księga czwarta 25 0 0 0 0 -25
Księga piąta 26 1 1 0 0 -30
Księga szósta 20 0 0 0 0 -20
Księga siódma 9 1 2 0 -1 -14
Księga ósma 19 0 0 0 0 -19
Księga dziewiąta 14 0 0 0 0 -14
Księga dziesiąta 21 0 1 0 0 -23
Księga jedenasta 21 1 0 0 0 -22
Księga dwunasta 18 0 1 0 0 -20
epilog 0 1 0 0 0 -2
In [13]:
#kombinacje i - j

# ij  - i (myśli wyślij)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'j' and str2[i2] == "i" and str1[i1-1] == 'i',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] == "i" and str2[i2] == "j" and str2[i2-1] == 'e',0,1))
In [14]:
zbr = okresl_rymy(PanTadeusz,OkresloneWersy)
df4 = stastyki(zbr)
df4
Out[14]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 480 5 0 0 0 5
Księga druga 420 1 0 0 0 5
Księga trzecia 385 1 0 0 0 8
Księga czwarta 487 2 0 0 0 11
Księga piąta 441 2 2 0 0 5
Księga szósta 298 6 0 0 0 1
Księga siódma 249 11 3 0 0 6
Księga ósma 388 7 0 0 0 4
Księga dziewiąta 362 9 0 0 0 6
Księga dziesiąta 421 5 1 0 0 10
Księga jedenasta 323 8 0 0 0 8
Księga dwunasta 406 10 1 0 0 10
epilog 51 7 0 0 1 4
In [15]:
df4 - df3
Out[15]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 0 0 0 0 0 0
Księga druga 0 0 0 0 0 0
Księga trzecia 1 0 0 0 0 -1
Księga czwarta 0 0 0 0 0 0
Księga piąta 0 0 0 0 0 0
Księga szósta 0 0 0 0 0 0
Księga siódma -2 0 1 0 0 0
Księga ósma 0 0 0 0 0 0
Księga dziewiąta 0 0 0 0 0 0
Księga dziesiąta 0 0 0 0 0 0
Księga jedenasta 0 0 0 0 0 0
Księga dwunasta 0 0 0 0 0 0
epilog 0 0 0 0 0 0
In [16]:
# z gwary 
#iéj - i do ropatrzenia
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 1 and str1[i1] == 'j' and str2[i2] == "i" and str1[i1-1] == 'é' and str1[i1-2] == 'i',2,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 1 and str2[i2] == 'j' and str1[i1] == "i" and str2[i2-1] == 'é' and str2[i2-2] == 'i',0,2))


# éj - y (bliżéj chyży) - GWARA (BLIZŻYJ- CHYŻYj)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'j' and str2[i2] == "y" and str1[i1-1] == 'é',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="y" and str2[i2] == "j" and str2[i2-1] == 'é',0,1))


 # ej - y (pijany wygranej)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'j' and str2[i2] == "y" and str1[i1-1] == 'e',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="y" and str2[i2] == "j" and str2[i2-1] == 'e',0,1))


# éj - i (daléj kichali) - GWARA (DALLi - KICHALI)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'j' and str2[i2] == "i" and str1[i1-1] == 'é',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="i" and str2[i2] == "j" and str2[i2-1] == 'é',0,1))


 # ié - i (lice świéce) - GWARA (LICE - ŚWICE)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'é' and str2[i2] == "i" and str1[i1-1] == 'i',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="i" and str2[i2] == "é" and str2[i2-1] == 'i',0,1))

# é - y (przewietrzyć przetrzéć)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["é", "y"] and str2[i2] in ["é", "y"],0,0))


# e - y (ogonem szalonym)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["e", "y"] and str2[i2] in ["e", "y"],0,0))
In [17]:
zbr = okresl_rymy(PanTadeusz,OkresloneWersy)
df5 = stastyki(zbr)
df5
Out[17]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 485 5 0 0 0 0
Księga druga 425 1 0 0 0 0
Księga trzecia 391 1 0 0 0 2
Księga czwarta 496 2 0 0 0 2
Księga piąta 443 2 2 0 0 3
Księga szósta 299 6 0 0 0 0
Księga siódma 251 11 3 0 0 4
Księga ósma 390 7 0 0 0 2
Księga dziewiąta 366 9 0 0 0 2
Księga dziesiąta 424 5 1 0 0 7
Księga jedenasta 324 9 0 0 0 5
Księga dwunasta 410 11 1 0 0 3
epilog 51 7 0 0 1 4
In [18]:
df5 - df4
Out[18]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 5 0 0 0 0 -5
Księga druga 5 0 0 0 0 -5
Księga trzecia 6 0 0 0 0 -6
Księga czwarta 9 0 0 0 0 -9
Księga piąta 2 0 0 0 0 -2
Księga szósta 1 0 0 0 0 -1
Księga siódma 2 0 0 0 0 -2
Księga ósma 2 0 0 0 0 -2
Księga dziewiąta 4 0 0 0 0 -4
Księga dziesiąta 3 0 0 0 0 -3
Księga jedenasta 1 1 0 0 0 -3
Księga dwunasta 4 1 0 0 0 -7
epilog 0 0 0 0 0 0
In [19]:
# y - i (dobrzyna rodzina)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 != i1m and str1[i1] in ["y", "i"] and str2[i2] in ["y", "i"],0,0))

# ź - ś (groźby prośby)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["ź", "ś"] and str2[i2] in ["ź", "ś"],0,0))

 
 # z - s (wózku francusku)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["z", "s"] and str2[i2] in ["z", "s"],0,0))


# o - ó (odmówi starcowi)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["o", "ó"] and str2[i2] in ["o", "ó"],0,0))


# z - ż (francuza duża)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(str1[i1] in ["z", "ż"] and str2[i2] in ["z", "ż"],0,0))

 # lt - l (kolei - amaltei)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 't' and str2[i2] == "l" and str1[i1-1] == 'l',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="l" and str2[i2] == "t" and str2[i2-1] == 'l',0,1))

 # dz - n (nadziei - kniei)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 > 0 and str1[i1] == 'z' and str2[i2] == "n" and str1[i1-1] == 'd',1,0))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 > 0 and str1[i1] =="n" and str2[i2] == "z" and str2[i2-1] == 'd',0,1))

 # łł - ł (zdziwił - radziwiłł)
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i1 != i1m and str1[i1] == 'ł' and str2[i2 + 1] == "ł" and str1[i1 +1] == 'ł',0,-1))
litery.append(lambda str1,str2,i1,i2,i1m,i2m :(i2 != i2m and str1[i1] =="ł" and str2[i2 +1] == "ł" and str2[i2 + 1] == 'ł',-1,0))
In [20]:
zbr = okresl_rymy(PanTadeusz,OkresloneWersy)
df6 = stastyki(zbr)
df6
Out[20]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 485 5 0 0 0 0
Księga druga 423 1 1 0 0 0
Księga trzecia 390 1 1 0 0 1
Księga czwarta 497 2 0 0 0 1
Księga piąta 443 2 2 0 0 3
Księga szósta 299 6 0 0 0 0
Księga siódma 251 12 3 0 0 2
Księga ósma 391 7 0 0 0 1
Księga dziewiąta 365 10 0 0 0 1
Księga dziesiąta 425 5 1 0 0 6
Księga jedenasta 322 12 0 0 0 1
Księga dwunasta 410 11 1 0 0 3
epilog 51 7 0 0 1 4
In [21]:
df6-df5
Out[21]:
Parzyste Monorymy 3 Monorymy 4 Krzywe Okalajance Inne
Księga pierwsza 0 0 0 0 0 0
Księga druga -2 0 1 0 0 0
Księga trzecia -1 0 1 0 0 -1
Księga czwarta 1 0 0 0 0 -1
Księga piąta 0 0 0 0 0 0
Księga szósta 0 0 0 0 0 0
Księga siódma 0 1 0 0 0 -2
Księga ósma 1 0 0 0 0 -1
Księga dziewiąta -1 1 0 0 0 -1
Księga dziesiąta 1 0 0 0 0 -1
Księga jedenasta -2 3 0 0 0 -4
Księga dwunasta 0 0 0 0 0 0
epilog 0 0 0 0 0 0

Po dodaniu wszystkich warunków wynik jaki udało się osiągnąć ma się następująco. Niemalże wszystkie wersy udało się sklasyfikować, pozostało średnio dwa wersy na księgę nie zostały sklasyfikowane, wynika to ze specyficznej budowy "Pana Tadeusza", Adam Mickiewicz w celu utrzymania spójności rymów i formę (trzynastozgłoskowiec) rozkładał niektóre wersy na dwie linie, co było problematyczne w uchwyceniu.

In [22]:
Wykresy_rymow(stastyki(zbr))
In [23]:
#Pozostałe nie skalsywikoane rymy 
#Pojedyncze nie mają zgodności z sąsiadami 
#Podwójne nie udało się połączyć między sobą
for i in range(13):
    print(zbr[i]["inne"])
[]
[]
['szerokim obłokiem']
['bojaźni najwyraźniej']
['rozmawiali', 'uchu muchą', 'nogą trwogę']
[]
['pańskim', 'sakiem takim']
['zaciął przyjaciół']
['katy stuknie']
['scyzorykiem nikim', 'działo', 'zaczepkę', 'kraju', 'zosię', 'uzbroi moi']
['czwartą']
['stoi boi', 'zmaca', 'nadziei kolei']
['krainie', 'przebrzmiała', 'przyszłości', 'sławie']

Funkcja wypisz_wersy wypisuje odpowiednie wersy zaznaczając kolorem jaka część wyrazu się ze sobą rymuje oraz dopisuje jaki rodzaj rymu to jest. Argumenty funkcji to odpowiednio zbiór sklasyfikowanych wersów, Rozpatrywania księga indeksowana od 0, wers początkowy oraz wers kończący (-1 odpowiada ostatniemu wersowi) Rodzaje rymów są oznaczone w następujący sposób monorymy P - parzyste rymy M - monorymy o długości 3 lub 4 K - rymy krzywe O - rymy okalające I - inne nieudana klasyfikacja Poniżej są przykłady jak prezentują się poszczególne fragmenty różnych ksiąg.

In [24]:
wypisz_wersy(OkresloneWersy,6,115,125)
poznałem co za ptaszek ksiądz oczy odwrócił P
lękając się żebym go nie zaczął spowiadać P
ale to rzecz nie moja wiele o tym gadać P
on tu nie przyjdzie próżno wzywać bernardyna M
jeśli od niego wyszła ta cała nowina M
to kto wie w jakim celu bo to bies księżyna M
jeśli prócz tej nowiny nic więcej nie wiecie P
więc po coście tu przyszli i czego wy chcecie P
wojny krzyknęli jakiej spytał zawołali P
wojny z moskalem bić się hejże na moskali P
In [25]:
wypisz_wersy(OkresloneWersy,2,600,610)
prawdziwie będą z pana żartować sąsiedzi P
że mieszkając na żyznej litewskiej równinie M
malujesz tylko jakieś skały i pustynie M
przyjacielu rzekł hrabia piękne przyrodzenie M
jest formą tłem materią a duszą natchnienie M
które na wyobraźni unosi się skrzydłach P
poleruje się gustem wspiera na prawidłach P
nie dość jest przyrodzenia nie dosyć zapału P
sztukmistrz musi ulecieć w sfery ideału P
nie wszystko co jest piękne wymalować da się P
In [26]:
wypisz_wersy(OkresloneWersy,0,0,20)
litwo ojczyzno moja ty jesteś jak zdrowie P
ile cię trzeba cenić ten tylko się dowie P
kto cię stracił dziś piękność twą w całej ozdobie P
widzę i opisuję bo tęsknię po tobie P
panno święta co jasnej bronisz częstochowy P
i w ostrej świecisz bramie ty co gród zamkowy P
nowogródzki ochraniasz z jego wiernym ludem P
jak mnie dziecko do zdrowia powróciłaś cudem P
gdy od płaczącej matki pod twoją opiekę P
ofiarowany martwą podniosłem powiekę P
i zaraz mogłem pieszo do twych świątyń progu P
iść za wrócone życie podziękować bogu P
tak nas powrócisz cudem na ojczyzny łono P
tymczasem przenoś moją duszę utęsknioną P
do tych pagórków leśnych do tych łąk zielonych P
szeroko nad błękitnym niemnem rozciągnionych P
do tych pól malowanych zbożem rozmaitem P
wyzłacanych pszenicą posrebrzanych żytem P
gdzie bursztynowy świerzop gryka jak śnieg biała P
gdzie panieńskim rumieńcem dzięcielina pała P
In [27]:
wypisz_wersy(OkresloneWersy,12,55,67)
umilknie światu swobodę obwieści P
wtenczas dębowym liściem uwieńczeni P
rzuciwszy miecze siędą rozbrojeni P
rycerze nasi zechcą słuchać o przeszłości O
wtenczas zapłaczą nad ojców losami O
i wtenczas łza ta ich lica nie splami O
dziś dla nas w świecie nieproszonych gości O
w całej przeszłości i w całej przyszłości I
jedna już tylko dziś kraina taka P
w której jest trochę szczęścia dla polaka P
kraj lat dziecinnych on zawsze zostanie P
święty i czysty jak pierwsze kochanie P

Teraza jest wykonywana jest próba rozrurznienia ksiąg na podstawie rymujących się końcówek.

In [28]:
#Wyądrebnienie rymujących się końcówek z rymów
tokeny_rymy = []
for pzbr in zbr:
    lista_slow = []
    for m2 in pzbr["monorymy"][2]:
        lista_slow.append(m2[0])
        lista_slow.append(m2[1])
    for m3 in pzbr["monorymy"][3]:
        lista_slow.append(rymy_koncowe(m3[0],m3[1])[0])
        lista_slow.append(rymy_koncowe(m3[0],m3[1])[1])
        lista_slow.append(rymy_koncowe(m3[1],m3[2])[0])
    for m4 in pzbr["monorymy"][4]:
        lista_slow.append(m4[0])
        lista_slow.append(m4[0])
        lista_slow.append(m4[1])
        lista_slow.append(m4[1])
    tokeny_rymy.append(lista_slow)
In [29]:
#Łączenie tabel rymów poszczególnych ksiąg w jedną
tokeny_calosc = []
for i in tokeny_rymy:
    tokeny_calosc += i
In [30]:
#Tworzenie słownika
slownikPT = utworz_slownik(tokeny_calosc)
In [31]:
#Sortowanie słownika
slownikPT2 = dict(sorted(slownikPT.items(), key=lambda x: x[1], reverse = True))

Z końcówek został zrobiony słownik który pokazuje ile razy każda z końcówke wystapiła w tekscie.

In [32]:
pokaz_czeste(slownikPT2,30)
anie : 90
ali : 84
owy : 82
ony : 75
owie : 71
ana : 66
any : 63
awy : 62
ami : 60
ania : 58
azy : 51
ały : 50
ada : 48
ona : 48
ody : 46
oru : 44
aty : 41
ował : 41
osi : 40
ady : 38
ele : 38
ata : 37
ało : 37
enie : 37
icy : 37
aczy : 36
obie : 36
odu : 36
ole : 36
owa : 36
ica : 35
odzi : 35
okiem : 35
ury : 35
usza : 35
ary : 34
omu : 34
ości : 33
odził : 32
ogi : 32
ety : 31

Mając słownik możemy wyliczyć miary takie jak tf czy tf-idf.

In [33]:
# Miara tf (term frequency) dla końcówek w poszczególnych księgach
tdm = tdmPT(slownikPT2,30)
tdm
Out[33]:
K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 Epilog
anie 12 13 4 12 4 8 0 8 4 8 4 11 2
ali 7 16 2 7 8 2 8 1 18 4 4 7 0
owy 11 10 8 8 10 0 0 2 4 9 10 8 2
ony 4 6 14 8 4 10 8 0 6 10 3 2 0
owie 4 2 0 8 4 4 4 7 10 10 7 8 3
ana 10 8 6 0 4 4 4 8 2 10 6 4 0
any 2 4 4 6 2 4 2 2 7 4 10 16 0
awy 8 4 8 6 8 0 4 10 0 4 2 8 0
ami 6 8 0 10 2 4 12 4 2 6 4 2 0
ania 6 8 10 4 10 0 6 4 2 0 4 4 0
azy 0 4 0 4 8 0 4 2 12 6 7 4 0
ały 4 2 4 4 6 2 2 4 3 5 9 5 0
ada 4 0 2 4 12 2 8 4 8 2 0 2 0
ona 2 4 6 6 6 7 2 2 0 4 4 5 0
ody 6 2 4 2 4 4 0 4 8 2 2 6 2
oru 8 10 0 4 4 0 0 10 6 0 0 2 0
aty 10 4 6 0 0 2 0 0 2 7 8 2 0
ował 10 4 2 2 8 0 0 4 0 6 1 4 0
osi 0 0 2 4 6 2 0 6 4 4 2 10 0
ady 0 4 0 2 2 12 0 2 4 6 0 6 0
ele 2 1 0 1 3 3 2 8 8 4 0 4 2
ata 2 0 6 0 2 2 6 2 2 4 7 4 0
ało 10 2 0 13 2 3 1 0 0 4 0 1 1
enie 0 2 2 8 6 0 0 6 0 4 4 5 0
icy 0 0 6 7 6 3 2 0 1 2 6 2 2
aczy 3 6 4 2 6 4 0 2 0 6 0 3 0
obie 8 5 2 0 1 0 2 2 2 5 2 4 3
odu 0 2 4 6 0 10 0 0 8 0 4 2 0
ole 8 1 1 3 2 1 1 3 7 2 6 1 0
owa 4 4 2 4 2 2 4 0 6 0 2 6 0
ica 2 4 2 6 2 2 2 4 0 2 5 4 0
odzi 4 0 8 2 4 0 3 4 0 4 2 4 0
okiem 2 8 6 5 6 2 2 2 2 0 0 0 0
ury 2 5 2 5 5 4 2 1 3 1 2 3 0
usza 4 0 6 4 4 0 2 3 2 4 0 6 0
ary 4 4 0 6 6 0 2 2 2 4 0 4 0
omu 8 0 2 6 8 2 2 0 0 2 4 0 0
ości 8 0 3 8 6 0 0 2 0 0 2 4 0
odził 4 4 0 4 0 2 4 5 2 2 0 5 0
ogi 6 2 0 8 2 0 2 0 4 4 2 2 0
ety 4 0 2 4 6 2 2 0 7 0 2 2 0
In [34]:
# miara tf-idf gdzie idf (inverted document frequency) to odwrotność liczby dokumentów w
# których wystąpiło dane słowo do liczby wszystkich dokumentów
# tf-idf iloczyn miar tf i idf pozwalający określić unikalność słów 
tfidf = policz_tfidf(tdm)
tfidf
Out[34]:
K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 Epilog w_ilu idf
anie 0.483 0.638 0.229 0.473 0.168 0.587 0.000 0.493 0.203 0.398 0.234 0.484 0.942 12 0.080
ali 0.282 0.786 0.114 0.276 0.335 0.147 0.610 0.062 0.912 0.199 0.234 0.308 0.000 12 0.080
owy 0.923 1.025 0.955 0.658 0.875 0.000 0.000 0.257 0.423 0.934 1.219 0.734 1.965 11 0.167
ony 0.336 0.615 1.671 0.658 0.350 1.533 1.273 0.000 0.634 1.038 0.366 0.184 0.000 11 0.167
owie 0.161 0.098 0.000 0.315 0.168 0.294 0.305 0.431 0.507 0.497 0.409 0.352 1.413 12 0.080
ana 0.839 0.820 0.716 0.000 0.350 0.613 0.636 1.028 0.211 1.038 0.732 0.367 0.000 11 0.167
any 0.080 0.196 0.229 0.237 0.084 0.294 0.152 0.123 0.355 0.199 0.584 0.704 0.000 12 0.080
awy 1.055 0.644 1.499 0.775 1.099 0.000 0.999 2.018 0.000 0.652 0.383 1.153 0.000 10 0.262
ami 0.504 0.820 0.000 0.823 0.175 0.613 1.909 0.514 0.211 0.623 0.488 0.184 0.000 11 0.167
ania 0.791 1.288 1.874 0.517 1.374 0.000 1.499 0.807 0.332 0.000 0.766 0.577 0.000 10 0.262
azy 0.000 0.902 0.000 0.725 1.540 0.000 1.401 0.566 2.793 1.370 1.879 0.808 0.000 9 0.368
ały 0.161 0.098 0.229 0.158 0.251 0.147 0.152 0.246 0.152 0.249 0.526 0.220 0.000 12 0.080
ada 0.527 0.000 0.375 0.517 1.648 0.481 1.999 0.807 1.328 0.326 0.000 0.288 0.000 10 0.262
ona 0.168 0.410 0.716 0.494 0.525 1.073 0.318 0.257 0.000 0.415 0.488 0.459 0.000 11 0.167
ody 0.241 0.098 0.229 0.079 0.168 0.294 0.000 0.246 0.405 0.099 0.117 0.264 0.942 12 0.080
oru 2.489 3.798 0.000 1.220 1.296 0.000 0.000 4.762 2.351 0.000 0.000 0.680 0.000 7 0.619
aty 2.440 1.191 2.081 0.000 0.000 0.891 0.000 0.000 0.615 2.111 2.835 0.534 0.000 8 0.486
ował 1.848 0.902 0.525 0.362 1.540 0.000 0.000 1.131 0.000 1.370 0.268 0.808 0.000 9 0.368
osi 0.000 0.000 0.525 0.725 1.155 0.675 0.000 1.697 0.931 0.914 0.537 2.020 0.000 9 0.368
ady 0.000 1.191 0.000 0.478 0.508 5.345 0.000 0.747 1.229 1.809 0.000 1.601 0.000 8 0.486
ele 0.168 0.102 0.000 0.082 0.262 0.460 0.318 1.028 0.846 0.415 0.000 0.367 1.965 11 0.167
ata 0.264 0.000 1.124 0.000 0.275 0.481 1.499 0.404 0.332 0.652 1.341 0.577 0.000 10 0.262
ało 1.848 0.451 0.000 2.355 0.385 1.012 0.350 0.000 0.000 0.914 0.000 0.202 2.163 9 0.368
enie 0.000 0.596 0.694 1.913 1.525 0.000 0.000 2.241 0.000 1.206 1.418 1.334 0.000 8 0.486
icy 0.000 0.000 1.124 0.905 0.824 0.722 0.500 0.000 0.166 0.326 1.149 0.288 3.087 10 0.262
aczy 0.554 1.354 1.051 0.362 1.155 1.349 0.000 0.566 0.000 1.370 0.000 0.606 0.000 9 0.368
obie 0.672 0.512 0.239 0.000 0.087 0.000 0.318 0.257 0.211 0.519 0.244 0.367 2.948 11 0.167
odu 0.000 0.760 1.769 1.830 0.000 5.679 0.000 0.000 3.134 0.000 1.807 0.680 0.000 7 0.619
ole 0.322 0.049 0.057 0.118 0.084 0.073 0.076 0.185 0.355 0.099 0.351 0.044 0.000 12 0.080
owa 0.527 0.644 0.375 0.517 0.275 0.481 0.999 0.000 0.996 0.000 0.383 0.865 0.000 10 0.262
ica 0.168 0.410 0.239 0.494 0.175 0.307 0.318 0.514 0.000 0.208 0.610 0.367 0.000 11 0.167
odzi 0.739 0.000 2.101 0.362 0.770 0.000 1.051 1.131 0.000 0.914 0.537 0.808 0.000 9 0.368
okiem 0.370 1.805 1.576 0.906 1.155 0.675 0.700 0.566 0.465 0.000 0.000 0.000 0.000 9 0.368
ury 0.080 0.246 0.114 0.197 0.210 0.294 0.152 0.062 0.152 0.050 0.117 0.132 0.000 12 0.080
usza 0.739 0.000 1.576 0.725 0.770 0.000 0.700 0.849 0.465 0.914 0.000 1.212 0.000 9 0.368
ary 0.739 0.902 0.000 1.087 1.155 0.000 0.700 0.566 0.465 0.914 0.000 0.808 0.000 9 0.368
omu 1.952 0.000 0.694 1.435 2.034 0.891 0.925 0.000 0.000 0.603 1.418 0.000 0.000 8 0.486
ości 2.489 0.000 1.327 2.440 1.945 0.000 0.000 0.952 0.000 0.000 0.904 1.361 0.000 7 0.619
odził 0.739 0.902 0.000 0.725 0.000 0.675 1.401 1.414 0.465 0.457 0.000 1.010 0.000 9 0.368
ogi 1.109 0.451 0.000 1.449 0.385 0.000 0.700 0.000 0.931 0.914 0.537 0.404 0.000 9 0.368
ety 0.739 0.000 0.525 0.725 1.155 0.675 0.700 0.000 1.629 0.000 0.537 0.404 0.000 9 0.368

Końcówki które mają największy współczynik to "odu" i "ady" dla księgi szóstej, oraz "ości" dla epilogu

In [35]:
czestosc_odciecia = 30
tdm = tdmPT(slownikPT2,czestosc_odciecia)
tfidf = policz_tfidf(tdm)
mac_odl = np.empty([12,12])
for i in range(0,12):
    for j in range(0,12):
        mac_odl[i,j] = odleglosc(tfidf.iloc[:,i],tfidf.iloc[:,j])
hdf = pd.DataFrame(data=mac_odl,index="K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12".split(), columns="K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12".split())

plt.figure(figsize=(7,6),dpi = 100)
sns.heatmap(hdf,annot = hdf)
Out[35]:
<AxesSubplot:>

HeatMapa reprezentuje podobieństwo końcówek poszczególnych rymów w poszczególnych księgach pokazuje to że większość ksiąg ma ze sobą koleracje w przedziale 0,5 - 0,6 więć większość ksiąg jest do siebie dosyć podbne w szczegulności księga 10 i 12 mają one najwększe podobieństwo równe 0,76 natomiast księga 6 najbardzej odstaje od reszty z każdą inną księgę wartość koleracji jest poniżej 0,5 a z trzema księgami jest ponirzej 0,3

Przedstawienie każdej księgi w postaci pasków gdzie każdy kolor reprezentuje występowanie konkretnego rymu, im pasek jest dłuższy tym rym występował częściej.

In [36]:
tdm.T.plot.barh(stacked=True,colormap="nipy_spectral",figsize=(12,6))
Out[36]:
<AxesSubplot:>
In [37]:
# Przeliczenie aby paski były równej długości
ustandaryzowane = tdm.T.copy()
for i in range(13):
    suma = 0
    for k in ustandaryzowane.iloc[i]:
        suma += k
    for j in range(len(ustandaryzowane.iloc[i])):
        ustandaryzowane.iloc[i,j] = ustandaryzowane.iloc[i,j]/suma
In [38]:
ustandaryzowane.plot.barh(stacked=True,colormap="nipy_spectral",legend=False,figsize=(12,6))
Out[38]:
<AxesSubplot:>
In [39]:
ustandaryzowane.iloc[[6,0,4]].plot.barh(stacked=True,colormap="nipy_spectral",legend=False,figsize=(12,6))
Out[39]:
<AxesSubplot:>

Z macierzy podobieństwa: K1 jest najbardziej podobna do K5, a najmniej podobna do K7. Wykres potwierdza tą zależność, K1 i K5 są bardzo podobne, a w K7 brakuje ciemnych kolorów na początku (anie) i turkusów (ody, oru)w okolicach środka.

In [40]:
ustandaryzowane.iloc[[4,5]].plot.barh(stacked=True,colormap="nipy_spectral",legend=False,figsize=(12,6))
Out[40]:
<AxesSubplot:>

Z macierzy podobieństwa: K5 i K6 są również mało podobne, widać to na wykresie, zauważamy znacznie mniejszą ilość fioletu (ali, ony, owie), a także koloru jasnozielonego (ole, owa).

In [41]:
ustandaryzowane.iloc[[9,11]].plot.barh(stacked=True,colormap="nipy_spectral",legend=False,figsize=(12,6))
Out[41]:
<AxesSubplot:>

K10 oraz K12 to dwie najbardziej podobne księgi, zgodnie z macierzą korelacji, korelacja wynosi a 0,76. Wykres to potwierdza, wymienione księgi są wręcz identyczne, widać bardzo podobny rozkład kolorów i małą rónice.