Piątek, chmura słów, TextMining, morfologik i oczywiście R

Dzisiaj jest piątek, więc zamiast zaprzątać sobie głowę liczbami pooglądamy obrazki.

Dwa dni temu, w tym wpisie opisałem jak ściągnąć dane z Twittera i jako przykład ściągnąłem dane z kanału #debataACTA. Pokazałem też kilka podsumowań odkładając na później bardziej złożone analizy. Analizę nastawienia odłożę jeszcze na później, a dzisiaj pokażę jak danych tekstowych zrobić chmurę słów (ang. word cloud) używając R.

Samą chmurę słów można wykonać używając funkcji wordcloud() z pakietu wordcloud. Jako argumenty należy podać listę słów oraz współczynnik skalujący, odpowiadający wielkości danego słowa (najczęściej odpowiadający liczbie wystąpień danego słowa w tekście). Listę słów oraz częstości ich wystąpień można wygenerować używając funkcji str_split() i table(), ale aby było ciekawiej użyję w tym celu pakietu tm, który ma wiele przydatnych narzędzi do analizy tekstu (najwięcej przydatnych narzędzi ma do analizy tekstu angielskiego, ale z polskim też coś można zrobić).

Poniższy fragment kodu wczytuje dane, liczy tablicę częstości a następnie przedstawia ją graficznie z użyciem funkcji wordcloud(),

 

# Odczytaj dane
tweets = read.table(file="debataACTA4_13_luty.csv", sep=";", head=T)
 
# funkcje z pakietu tm i wordcloud
# do tworzenia korpusu wyrazów i ich wizualizacji
actaSlownik = Corpus(DataframeSource(data.frame(tweets[,2])))
actaSlownik = tm_map(actaSlownik, removePunctuation)
actaSlownik = tm_map(actaSlownik, tolower)
tdm = TermDocumentMatrix(actaSlownik)
m = as.matrix(tdm)
v = sort(rowSums(m),decreasing=TRUE)
 
# mając policzone częstości występowania możemy je zwizualizować
wordcloud(names(v), v^0.3, scale=c(5,0.5),random.order=F, colors="black")

 

Wykres otrzymany w ten sposób nie wygląda zbyt dobrze, ponieważ słowa występują w najróżniejszych odmianach a liczenie częstości osobno dla ,premierze’, 'premier’, 'premiera’, 'premierem’ nie wiele daje. Aby wykres wyglądał lepiej chcielibyśmy dla każdego ze słów znaleźć jego rdzeń i zliczać liczbę wystąpień rdzeni a nie różnych form. Jak to zrobić? Potrzebny będzie lematyzator, a dokładniej tzw. stemmer, czyli narzędzie, które dla każdego słowa wyodrębni tzw. 'stem’ (nie znam niestety polskiej terminologii a nie chcę tworzy kwiecistych tłumaczeń) czyli część słowa nie ulegającą odmianie.

Wykorzystam bezpłatny morfologik-stemmer dostępny na blogu http://morfologik.blogspot.com/ rozwijany przez Dawida Weissa i współpracowników. Narzędzie z którego skorzystałem to duży plik tekstowy mający w jednej kolumnie różne formy słów, w drugiej rdzenie a w trzeciej informacje o formie gramatycznej danego słowa. Oczywiście nie wszystkie słowa z twittera można znaleźć w tym zbiorze, nie ma tam np. wszystkich nazwisk. W każdym razie pierwsza transformacja polegała na przemapowaniu słowa na jego rdzeń, jeżeli słowo występuje w słowniku, lub pozostawienie słowa bez zmiany jeżeli w słowniku nie występuje. Dzięki temu z 13334 różnych słów zostaliśmy z 8597 słowami, z czego zdecydowana większość występuje tyko raz i nie znajdzie się na mapie tagów.

Zobaczmy jak wygląda rzeczona mapa.

[Rysunek 1. Chmura słów występujących przynajmniej dwa razy w zapisach z kanału debataACTA. Gdy było to możliwe słowa zostały przekształcone do swoich rdzeni. Wersja wektorowa tego rysunku (uwaga 7MB) znajduje się tutaj]

Dużo tych słów, mało widać, zróbmy więc jeszcze jedną iterację. Usuńmy wszystko co nie jest rzeczownikiem. Szczęśliwie słownik z pakietu morfologik ma informacje o tym czy dane słowo jest czy nie rzeczownikiem, więc zostawiamy tylko słowa, które znajdują się w słowniku i mają 'subst’ w trzeciej kolumnie.

[Rysunek 2. Chmura rzeczowników występujących przynajmniej dwa razy w zapisach z kanału debataACTA. Wersja wektorowa tego rysunku (uwaga 8MB) znajduje się tutaj]

Zróbmy jeszcze jeden eksperyment, mianowicie sprawdźmy jakie inne kanały występowały w wiadomościach z kanału #debataACTA. Zostawiamy więc tylko słowa zaczynające się od znaku #.

 

[Rysunek 3. Chmura nazw kanałów w wiadomościach na kanale debataACTA. Wersja wektorowa tego rysunku (uwaga 7MB) znajduje się tutaj]