Kto pisze teksty przemówień prezydenta Dudy?

Czytanie zajmie Ci około 11 minut

Pytanie tytułowe jest nieco przewrotne. Sprawdzimy czy wystąpienia są do siebie podobne, a przede wszystkim dowiemy się jak to zrobić. Nazwisk autorów wystąpień nie podam…

Niniejszy tekst to fragment (ale rozbudowany i zmodyfikowany) mojej prezentacji z konferencji “Machine Learning @ Enterprise”. Całość prezentacji z odpowiednimi skryptami znajdziecie na GitHubie.

Dzisiaj skorzystamy z bibliotek:

W pierwszym kroku potrzebujemy wypowiedzi Andrzeja Dudy. Na szczęście wszystko jest podane na tacy na oficjalnej stronie prezydenta, a jedyne czego potrzebujemy to wyłuskać teksty. Do tego celu przygotujemy kawałek kodu:

Dane mamy zebrane i zapisane. Ja zapuściłem powyższy skrypt 20 września rano i w dalszej części będę korzystał z zapisany danych.

O czym mówi Andrzej Duda?

Zobaczmy jakich słów najczęściej w swoich wypowiedziach używa Andrzej Duda. Da nam to bardzo zgrubny obraz tego o czym mówi. Bardzo zgrubny.

Prezydent mówi głównie o Polsce, wita szanownych słuchaczy, dziękuje im itd.

O kim mówi Andrzej Duda?

Kto jest częściej wspominany w wystąpieniach prezydenta? Premier, prezes partii czy szef MON (pamiętacie konflikt z Macierewiczem?), a może ktoś z opozycji?

Widzimy, że najważniejszy (czytaj: najczęściej wymieniany) w przemówieniach prezydenta jest prezes partii, do której prezydent nie należy (bo prezydent jest bezpartyjny). Albo jego brat – jeden z poprzednich prezydentów. O poprzednich prezydentach (innych) Duda mówi niewiele. Co ciekawe więcej mówił o Petru niż Schetynie.

Sprwadźmy czy to ile razy dana osoba jest wspominana zależy od momentu w czasie:

Pionowe linie oznaczają kolejno od lewej: początek rządu Beaty Szydło, zmianę premiera na Mateusza Morawieckiego i przebudowanie rządu (m.in. zmianę na stanowisku szefa MON). Wielkość bąbelka to liczba wystąpień danego nazwiska w wystąpieniach prezydenta z danego dnia.

To jest ciekawsze – Szydło po zakończeniu misji premiera rządu przestała być wymieniana, podobnie Macierewicz (w jego miejsce zaczął pojawiać się Błaszczak częściej niż wcześniej). Petru i Schetyna pojawili się po jednym razie – pewnie przy konkretnej okazji (trzeba by sprawdzić konkretne wystąpienia). O Wałęsie się nie mówi.

To Lech czy Jarosław?

Jednak Lech. Ale i tak Jarosław pojawia się często – sumarycznie Jarosława jest tyle, że wypada pomiędzy Szydło a Macierewiczem (Lech bierze 88% wymienionych Kaczyńskich).

Zanim przejdziemy dalej kilka słów o sposobie mierzenia podobieństwa tekstów.

Rozważmy podobieństwo słów: kiedy słowa są do siebie podobne? W rozumieniu języka możemy przyjąć, że wtedy, kiedy mają podobne znaczenie czy też sens, albo należą do jakiejś podobnej grupy (np. nazwy, liczebniki). W sensie matematycznym możemy mierzyć podobieństwo różnymi miarami, najczęstszą jest odległość kosinusowa między wektorami zdefiniowana wzorem:

    \[podobienstwo = cos(\theta) = \frac{A \cdot B}{|A| |B|} = \frac{\sum \limits _{i=1}^{n}{A_{i}B_{i}}}{{\sqrt {\sum \limits _{i=1}^{n}{A_{i}^{2}}}}{\sqrt {\sum \limits _{i=1}^{n}{B_{i}^{2}}}}}\]

Zatem potrzebujemy słów zapisanych jako wektory. Popularnym sposobem reprezentacji słów w przestrzeni wektorowej jest word2vec i słowniki typu GloVe lub zyskujący na popularności FastText. Mechanizm przygotowania reprezentacji wektorowej słów polega mniej więcej na przebadaniu ogromnej liczby dokumentów, określeniu popularności słów w każdym z dokumentów i całości korpusu (czyli wszystkich dokumentach razem), a także szukaniu częstotliwości wystąpienia każdego ze słów w przesuwającym się po dokumentach oknie określonej szerokości (liczby słów wpadających do okna). Warto doczytać, jest o tym sporo (z przykładami w Pythonie, ale też w R) – googlaj word2vec.

Przygotowanie takiego słownika słowo – wektor wymga dużo tekstu, dużo czasu. Są gotowe słowniki i z nich skorzystamy. Tutaj kłania się FastText gdzie znajdziemy słowniki dla 157 języków, w tym dla polskiego. Słownik w wersji tekstowej (plik csv) to ponad 4 GB – pobieramy go z odpowiedniej strony i rozpakowujemy. Zobaczmy co siedzi w środku.

Weźmy tylko kilkadziesiąt (N_VEC) pierwszych składowych wektora – dla ograniczenia konsumpcji pamięci. Po wczytaniu całego słownika i pierszych 100 składowych w pamięci słownik zajął 1.6GB.

Weźmy losowe N_WORDS słów z tego słownika i zredukujmy przestrzeń N_VEC wymiarową do dwóch wymiarów, aby dało się to pokazać na obrazku. Do redukcji użyjemy algorytmu t-SNE (może być PCA, ale t-SNE stara się trzymać bliskie wektory blisko po przeskalowaniu).

Teraz możemu już to narysować:

Spróbujcie pojeździć myszą po powyższym wykresie – punkty, które są blisko siebie to słowa w jakiś sposób podobne. Na przykład zgrupowane są różne liczby, różne sposoby zapisu dat, mogą się trafić ciągi wyglądające jak internetowe nicki. Zawartość słów zależy od korpusu (zbioru dokumentów) na którym słownik był trenowany. Na MLForum Joanna Misztal-Radecka pokazała slajd z słowami podobnymi do słowa gwiazda – korpus onetowy zwrócił synonimy typu aktorka, modelka zaś korpus wikipedia – planeta, galaktyka. Nie wiem na czym był trenowany FastText, ale widać nawet na powyższym wykresie, że wiele tam jest śmieci, zbitek wyrazów itp. Ewidentnie pochodzi to z procesu sczytywania jakichś stron internetowych, ale nie bardzo przyłożono się do oczyszczenia tekstu (ma to swoje wady i zalety).

Wszystko to słowa, ale jak zmierzyć podobieństwo dokumentów? Zamiast word2vec przydałby się jakiś doc2vec. No to zróbmy sobie! Niech wektor opisujący dokument będzie średnią z wektorów opisujących poszczególne słowa w dokumencie. Genialne w swojej prostocie! Potrzebujemy rozbić dokument na słowa, wypisać wektory kolejnych słów i całość uśrednić. Odpowiednie funkcje:

Zwróćcie uwagę, że nie korzystamy z całego słownika, a jedynie wybraliśmy z niego te słowa, które występują w wypowiedziach Dudy. Usunęliśmy też polskie stop words, chociaż nie trzeba tego robić. Będzie po prostu szybciej. Chociaż wcale nie tak szybko – całość trochę się przeliczała.

Porównajmy dwa przykładowe wystąpienie:

Jest to jakaś wartość – czy podobne są te teksty? Jak wiemy z matematyki wektory identyczne będą miały odległość kosinusową równą jeden. Policzymy więc odległości kosinusowe pomiędzy wszystkimi wystąpieniami (każdy z każdym):

Narysujmy całą macierz (właściwie tylko jej połowę – to jest macierz symetryczna względem przekątnej, nie musimy rysować całości):

albo interaktywnie, jeśli wykorzystamy Plot.ly (ale to wielkie, więc nie zamieszczam):

Możemy też zobaczyć rozkład podobieństw tekstów między sobą:

Rozkład mówi nam, że teksty są mniej więcej jednakowo podobne do siebie – nie ma wysp czy oddzielnych górek na wykresie. Możemy pokusić się o tezę, że skoro tak jest to autor jest potencjalnie jeden (albo kilku i wszyscy dobrze się maskują pisząc w podobnym stylu).

Ciekawe są wypowiedzi o numerach ponad 500 (konkretnie jest to numer 506), bo wyglądają na inne. Trzeba przeczytać tekst wystąpienia, wówczas okaże się że jego część (ściągniętego tekstu ze strony) jest po angielsku – stąd właśnie różnica.

Aby z większym prawdopodobieństwem stwierdzić czy jest jeden autor czy jest ich wielu możemy:

  • wziąć przede wszystkim większy słownik – pamiętacie, że na początku ograniczyliśmy się do 100 składowych wektora? A w słowniku jest ich 300
  • dodać dodatkowe cechy do porównania: liczbę znaków przestankowych, średnią długość słów (w znakach) oraz zdania (w słowach)
  • nie usuwać stop-words
  • policzyć ile słów w wypowiedzi (albo średnio w zdaniu) to stop words

To tylko kilka z pierwszych pomysłów. Czasem logarytm jakiejś wartości (szczególnie tej obliczonej) pomaga.

Poszukajmy jeszcze dwóch najbardziej podobnych wystąpień:

Są to (treść pod linkami):

a najczęściej występujące w nich słowa to:

Możemy pokusić się o rzutowanie wszystkich wektorów wystąpień na przestrzeń dwuwymiarową (identycznie jak dla pojedynczych słów wcześniej – korzystając z t-SNE).

Teraz zaznaczmy oddzielnymi kolorami punkty opisujące te dwa wystąpienia:

Widzimy, że dwa najbardziej podobne wystąpienia (to te powiększone: trójkąt i kwadrat) leżą blisko siebie, wręcz na sobie.

Co jeszcze można zrobić? Można próbować klasteryzacji (podziału na grupy) poszczególnych wystąpień prezydenta (np. poprzez kmeans na tabeli duda_sim_tsne), co w przypadku podziału na 6 grup da nam:

Klasteryzację można też przeprowadzić na wektorach przed t-SNE (co wydaje się mieć większy sens).

Zostańmy jednak przy naszych grupach ustalonych po t-SNE. Możemy przypisać numery grup do oryginalnych wystąpień i sprawdzić czy dwa teksty z jednej grupy dotyczą podobnych spraw, na przykład szukając najpopularniejszych słów w grupie::

Podobnie możemy przeprowadzić analizę tematów (poprzez LDA – też np. wybierając 6 tematów) i porównać czy klasteryzacja na wyniku t-SNE daje podobne przypisania do grup co LDA przypisania do tematów. Pozwólcie jednak, że na tym zakończymy :)

Analiza tekstu to bardzo rozległy temat – im więcej się w nim siedzi tym więcej przychodzi do głowy. Ale na tym to polega. Szczególnie, jeśli bawisz się danymi a nie budujesz coś (model, narzędzie), co ma rozwiązać określony cel.

Jeżeli zabawa (ale i nauka) danymi to Twój konik – koniecznie zostań fanem Dane i Analizy na Facebooku – tam więcej takich smaczków, mniej więcej raz na dzień coś nowego.

Mi z kolei miło będzie jeśli docenisz mój trud i poświęcony czas stawiając dużą kawę (albo po prostu dobre piwo z marketu).

Jestem też do wynajęcia o ile jest taka potrzeba, tutaj więcej info.

5 komentarzy do wpisu „Kto pisze teksty przemówień prezydenta Dudy?”

    • Czyli nie przeczytałeś nawet leadu: „Pytanie tytułowe jest nieco przewrotne. Sprawdzimy czy wystąpienia są do siebie podobne, a przede wszystkim dowiemy się jak to zrobić. Nazwisk autorów wystąpień nie podam…”

      • O jak kwikłem XD
        Łukasz, kiedyś trafiłem na bloga z wykopu (albo tylko tak mi się wydaje). Parę razy Cię szukałem w czeluściach internetu. Fajnie, że znowu dzięki wykopowi tu trafiłem. Może w niedługim czasie będę miał dla Ciebie małe zlecenie. Albo może raczej – pomożesz mi sprzedać swoje usługi dalej. Pozdrawiam!

Dodaj komentarz