diff --git a/markov_model.py b/markov_model.py index 8711635..eb02971 100644 --- a/markov_model.py +++ b/markov_model.py @@ -4,7 +4,7 @@ import random import re from nltk import SyllableTokenizer from nltk.tokenize import word_tokenize -from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction +from nltk.translate.bleu_score import SmoothingFunction, sentence_bleu import pandas as pd import numpy as np import matplotlib.pyplot as plt @@ -107,21 +107,21 @@ def generate_lyrics(markov_model, start, limit, try_rhyme, rime): return lyrics, current_state -def get_bleu(verse, remaining_verses): - bleues = [] +def get_bleu(sentence, remaining_sentences): + lst = [] smoothie = SmoothingFunction() - for other_verse in remaining_verses: - bleu = sentence_bleu(verse, other_verse, smoothing_function=smoothie.method1) - bleues.append(bleu) - return bleues + for i in remaining_sentences: + bleu = sentence_bleu(sentence, i, smoothing_function=smoothie.method1) + lst.append(bleu) + return lst -def self_BLEU(verses): +def self_BLEU(sentences): bleu_scores = [] - for verse in verses: - remaining_verses = copy.deepcopy(verses) - remaining_verses.remove(verse) - bleu = get_bleu(verse, remaining_verses) + for i in sentences: + sentences_copy = copy.deepcopy(sentences) + sentences_copy.remove(i) + bleu = get_bleu(i, sentences_copy) bleu_scores.append(bleu) return np.mean(bleu_scores) @@ -166,9 +166,6 @@ def heaps_law(dataset, n_gram): def plot_heaps_laws(datasets, n_grams): - plt.xlabel("total number of states") - plt.ylabel("unique number of states") - plt.title("Heap's law") for n_gram in n_grams: x = [] y = [] @@ -177,6 +174,9 @@ def plot_heaps_laws(datasets, n_grams): x.append(total) y.append(unique) plt.plot(x, y, linewidth=1.0) + plt.xlabel("total number of states") + plt.ylabel("unique number of states") + plt.title("Heap's law") plt.legend(["n_gram: " + str(n_gram)]) plt.tight_layout() plt.show() diff --git a/report/images/chain.png b/report/images/chain.png new file mode 100644 index 0000000..9e328ce Binary files /dev/null and b/report/images/chain.png differ diff --git a/report/images/cross-entropy.png b/report/images/cross-entropy.png new file mode 100644 index 0000000..4cc642e Binary files /dev/null and b/report/images/cross-entropy.png differ diff --git a/report/images/english_mixtape.png b/report/images/english_mixtape.png new file mode 100644 index 0000000..0dd2618 Binary files /dev/null and b/report/images/english_mixtape.png differ diff --git a/report/images/generated_zipf1.png b/report/images/generated_zipf1.png new file mode 100644 index 0000000..a3637eb Binary files /dev/null and b/report/images/generated_zipf1.png differ diff --git a/report/images/generated_zipf2.png b/report/images/generated_zipf2.png new file mode 100644 index 0000000..3712b0e Binary files /dev/null and b/report/images/generated_zipf2.png differ diff --git a/report/images/heaps1.png b/report/images/heaps1.png new file mode 100644 index 0000000..f50ceab Binary files /dev/null and b/report/images/heaps1.png differ diff --git a/report/images/heaps2.png b/report/images/heaps2.png new file mode 100644 index 0000000..1bdf286 Binary files /dev/null and b/report/images/heaps2.png differ diff --git a/report/images/heaps3.png b/report/images/heaps3.png new file mode 100644 index 0000000..7420f05 Binary files /dev/null and b/report/images/heaps3.png differ diff --git a/report/images/heaps4.png b/report/images/heaps4.png new file mode 100644 index 0000000..93eb65a Binary files /dev/null and b/report/images/heaps4.png differ diff --git a/report/images/heaps5.png b/report/images/heaps5.png new file mode 100644 index 0000000..17502d4 Binary files /dev/null and b/report/images/heaps5.png differ diff --git a/report/images/perplexity.png b/report/images/perplexity.png new file mode 100644 index 0000000..c0a0978 Binary files /dev/null and b/report/images/perplexity.png differ diff --git a/report/images/plot.png b/report/images/plot.png deleted file mode 100644 index e2631fc..0000000 Binary files a/report/images/plot.png and /dev/null differ diff --git a/report/images/self-bleu.png b/report/images/self-bleu.png new file mode 100644 index 0000000..454b74a Binary files /dev/null and b/report/images/self-bleu.png differ diff --git a/report/images/somemix.png b/report/images/somemix.png new file mode 100644 index 0000000..2058616 Binary files /dev/null and b/report/images/somemix.png differ diff --git a/report/images/somemix_zipf1.png b/report/images/somemix_zipf1.png new file mode 100644 index 0000000..c6b6021 Binary files /dev/null and b/report/images/somemix_zipf1.png differ diff --git a/report/images/somemix_zipf2.png b/report/images/somemix_zipf2.png new file mode 100644 index 0000000..0495d94 Binary files /dev/null and b/report/images/somemix_zipf2.png differ diff --git a/report/report.pdf b/report/report.pdf index 02e0c55..e310d3f 100644 Binary files a/report/report.pdf and b/report/report.pdf differ diff --git a/report/report.tex b/report/report.tex index 8e8d988..bd81b11 100644 --- a/report/report.tex +++ b/report/report.tex @@ -6,6 +6,9 @@ \graphicspath{{images/}} \usepackage{blindtext} \usepackage{hyperref} +\usepackage{placeins} +\usepackage{caption} +\usepackage{subcaption} \title{Generacja tekstów piosenek} \author{Maciej Krzyżanowski, Sebastian Kutny, Tomasz Lewandowski} @@ -39,6 +42,7 @@ Przed rozpoczęciem przetwarzania danych są one oczyszczane poprzez ujednolceni Tekst jest generowany jako dowolna liczba wersów o dowolnej ilości słow. \newpage \section{Łańcuchy Markova} +\subsection{Wstęp} Łańcuchy Markova to matematyczny model służący do generowania tekstu lub sekwencji innych elementów, takich jak dźwięki lub obrazy. Ideą modelu jest analiza sekwencji istniejących elementów i wykorzystanie tych informacji do przewidywania, jakie elementy powinny pojawić się następnie. \\ \\ W przypadku generowania tekstu, łańcuchy Markova są zwykle stosowane do analizy sekwencji słów w tekście źródłowym i generowania nowych sekwencji słów na podstawie tych informacji. Proces zaczyna się od wyboru deterministycznego lub losowego początkowego stanu łańcucha, a następnie generowania kolejnych stanów na podstawie informacji o pradwopodobieństwie wystąpienia po sobie stanów w analizowanym tekście w kontekście poprzednio wygenerowanych stanów. Przykładowo, jeśli w tekście źródłowym po słowie "generator" często pojawia się słowo "piosenek", to model łańcucha Markova przypisze wysokie prawdopodobieństwo wystąpienia słowa "piosenek" po słowie "generator". \\ @@ -51,11 +55,137 @@ Model łańcuchów Markova nie jest idealny i może generować sekwencje, które \\ \begin{figure}[h] \centering - \includegraphics[width=0.75\textwidth]{plot} - \caption{Przykład łańcucha Markova, gdzie stany mogą oznaczać słowa lub sekwencje słów, a przejścia pomiędzy nimi określono jako prawdpopodobieństwa $p$} + \includegraphics[width=0.75\textwidth]{chain} + \caption{Przykład łańcucha Markova, dla zdania "The quick brown fox jumps over the lazy dog and the angry dog chase the quick brown fox.", dla wartości $ngram = 1$, oznaczającej stany jako pojedyncze słowama oraz wartoścami prawdopodobieństw przejść pomiędzy stanami obliczonych na podstawie zdania wejściowego.} \label{fig:mesh1} \end{figure} - +\FloatBarrier +\subsection{Prawo Zipfa} +Prawo Zipfa to empiryczna obserwacja dotycząca częstotliwości występowania słów w korpusie tekstów. Mówi ono, że jeśli posortujemy słowa występujące w tekście według częstotliwości ich wystąpień i przyporządkujemy każdemu słowu rangę zgodną z jego pozycją w rankingu, to liczba wystąpień słowa o danej randze jest odwrotnie proporcjonalna do wartości tej rangi. W praktyce oznacza to, że najczęściej występujące słowo będzie występować dwa razy częściej niż drugie na liście, trzy razy częściej niż trzecie, i tak dalej. \\ +\\ +Wykorzystując Prawo Zipfa w generacji tekstów piosenek, można zapewnić, że wygenerowany tekst będzie przypominał rzeczywiste teksty pod względem częstotliwości występowania słów. +\begin{figure} + \centering + \begin{subfigure}[b]{0.75\textwidth} + \centering + \includegraphics[width=\textwidth]{somemix_zipf1} + \caption{Wykres 1000 najczęściej pojawiających się słów dla zbioru danych $somemix.csv$.} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.75\textwidth} + \centering + \includegraphics[width=\textwidth]{somemix_zipf2} + \caption{Wykres stałej $constant = ranga * wystapienia$ dla zbioru danych $somemix.csv$} + \label{fig:mesh1} + \end{subfigure} +\end{figure} +\FloatBarrier +\begin{figure} + \centering + \begin{subfigure}[b]{0.75\textwidth} + \centering + \includegraphics[width=\textwidth]{generated_zipf1} + \caption{Wykres 1000 najczęściej pojawiających się słów dla piosenki wygenerowanej na podstawie $somemix.csv$ o 100 wersach po 500 słów.} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.75\textwidth} + \centering + \includegraphics[width=\textwidth]{generated_zipf2} + \caption{Wykres stałej $constant = ranga * wystapienia$ dla piosenki wygenerowanej na podstawie $somemix.csv$ o 100 wersach po 500 słów} + \label{fig:mesh1} + \end{subfigure} +\end{figure} +\FloatBarrier +Podobieństwo wykresów wskazuje na to, że tekst wyjściowy modelu będzie tej samej jakości, przypominając tekst dany na wejściu. +\subsection{Prawo Heapsa} +Prawo Heapsa opisuje zależność pomiędzy wielkością dokumentu w jednostce liter, słów, stanów złożonych ze słów w kontekście liczby unikalnych liter, słów, stanów złożonych ze słów pojawiających się w tekście. Na podstawie prawa, stwierdzamy, że liczba unikalnych stanów rośnie wolniej wraz ze zwiększającą się ilością stanów tekstu, co pozwala nam przewidzieć ilość unikalnych w zasobie danych, co pozwala na lepszą ocenę modelu Markova. +\begin{figure} + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{heaps1} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{heaps2} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{heaps3} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{heaps4} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{heaps5} + \label{fig:mesh1} + \end{subfigure} + \hfill + \caption{Wykres zależności liczby stanów unikalnych od rozmiaru tekstu oraz wartości $ngram$ dla zbiorów danych: $kyuss.csv, led\_zeppelin.csv, Black Sabbath.csv, ac\_dc.csv$.} + \label{fig:mesh1} +\end{figure} +\FloatBarrier +Prawo Heapsa sprawdza się dla danych. Dodatkowo widzimy, że zmiana jest zależna od $ngramu$. Rośnie ona zwykle wolniej dla większych $ngramow$ co może oznaczać częste pojawianie się w tekstach określonych złożeń słów. +\subsection{Entropia Krzyżowa} +Entropia Krzyżowa to miara zgodności między dwoma rozkładami prawdopodobieństwa. Pozwala określić jak dobrze model generujący tekst przewiduje następny stan na podstawie poprzednich. W przypadku generowania tekstu, entropia krzyżowa może być wykorzystana do oceny jakości generacji. Im mniejsza wartość entropii krzyżowej, tym większa zgodność między rozkładem prawdopodobieństwa generowanego tekstu a rozkładem prawdopodobieństwa prawdziwych tekstów. Pozwala to ocenić czy model tworzy teksty podobne do tych ze zbioru danych, czy też tworzy nowe i oryginalne sentencje. +\begin{figure}[h] + \centering + \includegraphics[width=0.75\textwidth]{cross-entropy} + \caption{Wykres wartości entropii krzyżowej dla tekstu generowanego na podstawie zbioru danych $somemix.csv$, zależnie od rozmiaru wygenerowanego tekstu.} + \label{fig:mesh1} +\end{figure} +\FloatBarrier +Jak widać, entropia krzyżowa rośnie niemal liniowo względem długości wygenerowanego tekstu. Oznacza to, że model coraz to bardziej generuje tekst niepodobny do oryginalnego zależnie od długości wygenerowanego tekstu. +\subsection{Perpleksja} +Perpleksja to stopień trudności zrozumienia tekstu, miara nieprzewidywalności modelu. Im niższa tym tekst bardziej przypomina oryginalny i jest bardziej kreatywny. Aby policzyć wartość perpleksji tekstu korzystamy ze wzoru: $Perplexity(M) = 2^{H(L,M)}$ gdzie $M$ oznacza model, $L$ oznacza wygenerowany tekst, a $H(L, M)$ wartość entropii krzyżowej. +\begin{figure}[h] + \centering + \includegraphics[width=0.75\textwidth]{perplexity} + \caption{Wykres wartości perpleksji dla tekstu generowanego na podstawie zbioru danych $somemix.csv$, zależnie od rozmiaru wygenerowanego tekstu.} + \label{fig:mesh1} +\end{figure} +\\Jak widać, wykresy eksperymentu dla entropii krzyżowej i perpleksji się nie różnią, ponieważ w gruncie rzeczy znaczą tą samą miarę. +\subsection{Self-BLEU} +Self-BLEU określa różnorodność generowanego tekstu. Wykorzystuje wskaźnik \href{https://pl.wikipedia.org/wiki/BLEU}{BLEU} (ang. BiLingual Evaluation Understudy), licząc jego wartość dla kombinacji par wszystkich unikalnych sentencji wygenerowanego tekstu, w tym przypadku wersów piosenki, otrzymując końcowo ich średnią. Im mniejsza wartość wskaźnika tym większa różnorodność w tekście. Metryka pozwala uniknąć monotonności tekstu. +\begin{figure}[h] + \centering + \includegraphics[width=0.75\textwidth]{self-bleu} + \caption{Wykres wartości Self-BLEU dla tekstu generowanego na podstawie zbioru danych $somemix.csv$, zależnie od rozmiaru wygenerowanego tekstu.} + \label{fig:mesh1} +\end{figure} +\\Jak widać, tekst zachowuje wysoką różnorodność, poprzez losowy wybór początku wersu rozkładem równomiernym, a z coraz to większym rozmiarem tekstu napotykamy na podobne frazy, co zmniejsza jego różnorodność, jednak wciąż wynik jest zależny od wygenerowanych tekstów. +\FloatBarrier +\subsection{Przykładowe wyniki} \newpage +\begin{figure} + \centering + \begin{subfigure}[b]{0.75\textwidth} + \centering + \includegraphics[width=\textwidth]{english_mixtape} + \label{fig:mesh1} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.75\textwidth} + \centering + \includegraphics[width=\textwidth]{somemix} + \label{fig:mesh1} + \end{subfigure} + \hfill + \caption{Przykładowe wyniki generacji 10 wersów po 10 słów, kolejno dla zbiorów danych: $english\_mixtape.csv$ oraz $somemix.csv$} + \label{fig:mesh1} +\end{figure} +\FloatBarrier \section{Rekurencyjne Sieci Neuronowe} \end{document}