Subskrybuj newsletter o cyfrowej humanistyce i innowacjach w sektorze kultury

ngramr - szybkie wykresy trendów językowych z wykorzystaniem danych Google Ngram Viewer

Okładka lekcji: portret kota w renesansowym stroju / Źródło: AI

Wprowadzenie

W poprzedniej lekcji poznaliśmy Google Ngram Viewer. Google Ngram Viewer pozwala na przeszukiwanie ogromnego zbioru tekstów w kilku językach i generowanie wykresów ilustrujących historyczne zmiany w częstości występowania słów lub fraz w tych tekstach. To ciekawe, chociaż niepozbawione wad narzędzie do analizy trendów językowych oraz do badania historii kulturowej i społecznej.

W tej lekcji nadal będziemy pracować z Google Ngram Viewer, ale tym razem zdalnie, bez odwiedzania strony books.google.com/ngrams. Dzięki R nie tylko pozyskamy interesujące nas dane, ale też wygenerujemy własne wykresy i dostosujemy ich estetykę do naszych potrzeb.

Cele lekcji

Kontynuujemy naukę podstaw języka R w zastosowaniach humanistycznych. W tej lekcji nauczymy się pracować z wykresami.

Efekty

Dzięki pakietowi ngramr będziemy potrafili szybko pobierać z Google Ngram Viewer dane dokumentujące interesujące nas trendy. Nauczymy się też programować i edytować wykresy (na podstawowym poziomie) - każdy wykres w R jest pewnym zbiorem obiektów i funkcji, który finalnie zapisać możemy jako plik graficzny lub nawet wizualizację internetową. Dowiemy się też, czym jest Grammar of Graphics i jaki wpływ ma na metody budowania wykresów w R.

Wymagania

Aby skorzystać z lekcji należy zapoznać się z lekcjami poświęconymi podstawom składni R i korzystania z serwisu Posit.cloud: Podstawy R w pracach ze zbiorami cyfrowymi: korzystamy z API Wellcome Collection (część I) oraz Podstawy R w pracach ze zbiorami cyfrowymi: korzystamy z API Wellcome Collection (część I). Warto zapoznać się także z lekcją poświęconą Google Ngram Viewer.

Niezbędne jest posiadanie konta w Posit.cloud - alternatywnie skorzystać można z desktopowego RStudio. Aby pracować w RStudio należy we własnym systemie operacyjnym zainstalować język R.

Część merytoryczna

Jak to możliwe, że jesteśmy w stanie pobierać dane z Google Ngram Viewer, skoro serwis ten nie udostępnia żadnego oficjalnego API? Dane Google Ngram Viewer wizualizowane są za pomocą JavaScript (JS), odpowiadającego za generowanie wykresu i obsługę kliknięć. Kod JavaScript generujący wykres korzysta jednak z konkretnych adresów URL zwracających dane - działa to trochę jak API.

Bezpośredni dostęp do danych

Wykres porównujący trendy historyczne fraz (unigramów) bauhaus i brutalism (dla lat 1900-2019) ma adres:

https://books.google.com/ngrams/graph?content=bauhaus%2Cbrutalism&year_start=1900&year_end=2019&corpus=en-2019&smoothing=3&case_insensitive=true

Pod tym adresem znajdziemy gotowy wykres:

Google Ngram Viewer - wykres trendu / Źródło: books.google.com/ngrams/ngram

Aby w przeglądarce wygenerować nie wykres, a dane z Google Ngram Viewer, wystarczy podmienić część adresu (zamiast graph wpisujemy json):

https://books.google.com/ngrams/json?content=bauhaus%2Cbrutalism&year_start=1900&year_end=2019&corpus=en-2019&smoothing=3&case_insensitive=true

Pakiet ngramr nie robi więc nic innego jak pobiera za pomocą adresu URL dane Google Ngram Viewer i przetwarza je do postaci wykresu, korzystając przy tym z pakietu ggplot2, jednego z podstawowych pakietów do pracy z wykresami w R.

Przygotowujemy środowisko

Po zalogowaniu się na Posit.cloud tworzymy nowe środowisko pracy (tutaj przypomnienie, jak to zrobić).

Kiedy mamy już dostęp do edytora i wszystkich jego paneli, możemy zacząć pracę. Najpierw musimy zainstalować pakiet ngramr. Robimy to albo w panelu Packages, albo bezpośrednio w konsoli:

install.packages("ngramr")

Pakiet zostanie zainstalowany z wieloma zależnościami. Jak widać, budowanie pakietów w R nie jest działaniem wyłącznie na własną rękę - tworząc własne rozwiązania, nieustannie korzysta się z pracy innych:

> install.packages("ngramr")
Installing package into /cloud/lib/x86_64-pc-linux-gnu-library/4.3
(as lib is unspecified)
also installing the dependencies sys, askpass, utf8, colorspace, jsonlite, mime, openssl, R6, generics, glue, lifecycle, magrittr, pillar, tidyselect, vctrs, fansi, pkgconfig, purrr, cpp11, stringi, gtable, isoband, withr, farver, labeling, munsell, RColorBrewer, viridisLite, httr, rlang, curl, dplyr, cli, tibble, tidyr, rjson, stringr, ggplot2, scales, xml2, textutils

W liście instalowanych pakietów znajdziemy jsonlite, którego używaliśmy już w poprzednich lekcjach 🤓.

Korzystamy z funkcji ggram()

Zainstalowaliśmy ngramr, ale wciąż nie możemy skorzystać z funkcji, które ten pakiet udostępnia. Musimy wczytać go do środowiska razem z biblioteką ggplot2:

library(ggplot2)
library(ngramr)

Zwróćmy uwagę, że w tym przypadku nie zapisujemy nazwy pakietu w cudzysłowach: pakiet to już obiekt, który wysyłamy do funkcji library().

Jedną z podstawowych funkcji (metod) pakietu ngramr jest ggram:

ggram(
  phrases,
  ignore_case = FALSE,
  code_corpus = FALSE,
  geom = "line",
  geom_options = list(),
  lab = NA,
  google_theme = FALSE,
  ...
)

Przykład funkcji z rzeczywistymi argumentami umieściłem poniżej:

ggram(c("bauhaus", "brutalism"), year_start = 1900, year_end = 2019, 
      corpus = "en-2019", ignore_case = TRUE, 
      geom = "area", geom_options = list(position = "stack")) + 
      labs(y = NULL)

W powyższym przykładzie wyszukiwane frazy bauhaus i brutalism podane są w funkcji c(), która tworzy obiekt (wektor) wieloelementowy. Możemy policzyć liczbę jego elementów za pomocą funkcji length():

> c("bauhaus","brutalism")
[1] "bauhaus"   "brutalism"
> length(c("bauhaus","brutalism"))
[1] 2

Generując wykres trendu, musimy wskazać nazwę korpusu - znajduje się ona w adresie URL podanym wyżej, wystarczy ją skopiować (en-2019). Oczywiście możemy użyć też innych korpusów dostępnych w Google Ngram Viewer.

Problem w zrozumieniu argumentów funkcji pojawia się w dalszej części składni. Tutaj ggram korzysta bezpośrednio z pakietu ggplot2, dlatego powinniśmy poświęcić mu trochę uwagi.

Tworzyć wykresy jak zdania

ggplot2 to pakiet służący do programowania wizualizacji danych, oparty na koncepcji Lelanda Wilkinsona, który w wydanej w 1999 roku książce The Grammar of Graphics zaproponował szczególne podejście do pracy nad wykresami:

Ta książka opisuje gramatyczne reguły tworzenia postrzegalnych (perceivable graphs) wykresów, czyli tego, co nazywamy grafiką (graphics). Gramatyka grafiki przenosi nas poza ograniczony zestaw wykresów (słów) do prawie nieograniczonego świata form graficznych (twierdzeń). Reguły gramatyki grafiki są czasem matematyczne, a czasem estetyczne. Matematyka dostarcza symbolicznych narzędzi do reprezentowania abstrakcji. Estetyka, w pierwotnym greckim znaczeniu, proponuje zasady relacji między atrybutami zmysłowymi (kolor, kształt, dźwięk itp.) a abstrakcjami. W współczesnym użyciu estetyka może również oznaczać gust.

Propozycję Wilkinsona można wyjaśnić tym prostym schematem, który pobrałem ze strony GeeksForGeeks. Wykresy nie są więc prostym wtłaczaniem danych w jakąś postać graficzną, ale - podobnie jak wypowiedzi w języku naturalnym - zbudowane są z wielu elementów, mających swoje właściwości i wchodzących w relacje z innymi elementami. Część z tych elementów ma charakter matematyczny (abstrakcyjny), część estetyczny, a każdy wykres składa się z warstw, które ze sobą zestawiamy:

Grammar of Graphics / Źródło: geeksforgeeks.org

Bardzo ciekawy esej o gramatyce wizualizacji danych napisał Przemysław Biecek. W lekcji poświęconej ggplot2 wrócimy jeszcze do tego tematu. Przed skorzystaniem z pakietu ngramr powinniśmy jednak wiedzieć, że wykresy tam generowane są zgodnie z ideą gramatyki grafiki. Co to znaczy w praktyce?

W funkcji ggram znajdują się takie parametry jak geom i geom_options. Do wyniku działania tej funkcji (już po zamknięciu nawiasu) dodawany jest (dosłownie) obiekt generowany funkcją labs - w ten sposób dodajemy kolejną warstwę gramatyki grafiki. Wykres generowany jest z rozmaitych cegiełek - niektóre zawierają dane źródłowe, inne koordynaty obiektów do wizualizacji, kolejne typ wykresu, jeszcze inne treść legendy itd. W R wykresy są programowalne - buduje się je z wielu elementów, co daje większą kontrolę nad ostateczną treścią i kształtem wykresu oraz pozwala generować go automatycznie dla różnych danych i różnych ustawień.

Praktyka gramatyki wykresów

Spróbujmy przyjrzeć się tym elementom gramatyki wykresu:

argument wartość znaczenie
geom area tworzy warstwę wykresu o określonym typie, w tym przypadku obszarowego (area chart)
geom_options list(position = “stack”) lista opcji formatujących wykres obszarowy: jeśli na wykresie będzie więcej niż jeden obszar, będą się na siebie nakładać
labs y = NULL w tym miejscu tworzone są i formatowane etykiety wykresu; oś Y nie będzie podpisana

Wróćmy teraz do Posit.cloud i wygenerujmy w końcu wykres - wpiszmy go do obiektu w1:

w1 <- ggram(c("bauhaus", "brutalism"), year_start = 1900, year_end = 2019, corpus = "en-2019", ignore_case = TRUE, geom = "area", geom_options = list(position = "stack")) + labs(y = NULL)

Wywołajmy ten obiekt:

w1

Po prawej stronie ekranu pokaże się wykres z danymi z Google Ngram Viewer. Możemy wyeksportować go do pliku o wybranym formacie (pdf, svg, png).

Wykres danych z Google Ngram Viewer / Źródło: Posit.cloud

Jak widać na zrzucie ekranu, nasz wykres w1 jest obiektem (listą), zawierającą rozmaite elementy zgodne z ideą gramatytki wykresów. Spróbujmy teraz skorzystać z elastyczności w budowaniu wykresów i nieco zmienić naszą wizualizację. Skorzystałem z ChatGPT aby pomóc sobie z przygotowaniem elementów wykresu, bo jest ich w tym przypadku bardzo wiele:

w2 <- ggram(c("bauhaus", "brutalism"), year_start = 1900, year_end = 2019, corpus = "en-2019", ignore_case = TRUE, geom = "line") + labs(y = NULL, title = "Wybrane style architektoniczne w korpusie Google Ngram Viewer (en-2019)") + scale_colour_manual(values = c("red", "green"), guide = guide_legend(title = NULL, position = "bottom"), labels = c("Bauhaus", "Brutalism")) + scale_linetype_manual(values = c("solid", "dashed")) + theme(legend.position = "bottom") + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black", linewidth = 0.5))

W efekcie udało się wygenerować wykres liniowy, dodać legendę i kolory:

Wykres danych z Google Ngram Viewer / Źródło: Posit.cloud

Warto dodać, że pakiet ngramr pozwala na wygenerowanie wykresu o estetyce zbliżonej do wykresów Google Ngram Viewer. Musimy skorzystać z argumentu google_theme:

> w3 <- ggram(c("bauhaus", "brutalism"), year_start = 1900, year_end = 2019, corpus = "en-2019", ignore_case = TRUE, google_theme = TRUE) + theme(legend.direction = "vertical")

Wyeksportowany wykres (svg) w motywie Google Ngram Viewer można z powodzeniem umieścić w publikacji naukowej, raporcie albo podręczniku:

Wykres danych z Google Ngram Viewer / Źródło: Posit.cloud

Podsumowanie

Dostęp do danych (a nie tylko wykresów) Google Ngram Viewer pozwolił nam na generowanie własnych wizualizacji z wykorzystaniem pakietu ngramr. Aby użyć funkcji generującej wykres, musieliśmy poznać podstawy gramatyki wizualizacji danych, którą zaproponował Leland Wilkinson. Ręczne składanie wykresów w R bywa trudne, jednak daje nam pełną kontrolę nad wizualizacją: od warstwy pozyskiwania, przetwarzania i pokazywania danych do estetyki. Co więcej, wykresy takie możemy generować automatycznie, jedynie podmieniając dane.

Wykorzystanie metod

Grammar of Graphics jest wykorzystywana w wielu narzędziach do tworzenia wykresów, w tym również w rozwiązaniach dla języków programowania: ggplot2 (dla języka R), Plotnine (Pythona) czy Vega (JavaScript).

Programowalne wykresy wykorzystywane są także do automatycznego generowania raportów czy budowania internetowych narzędzi analitycznych, w których - zgodnie z ideą gramatyki wizualizacji - programuje się nie tylko warstwę estetyczną, ale poszczególne warstwy danych i metod ich prezentacji.

Pomysł na warsztat

Lekcja może być wykorzystana w ramach cyklu warsztatów wprowadzających do programowania w R. Poza tym zastosowaniem, metody opisane w tej lekcji można wykorzystać do szybkiego przygotowywania materiałów warsztatowych do zajęć bazujących na interpretowaniu danych z Google Ngram Viewer.

Wątek Grammar of Graphics może być też niezależnie wykorzystany w warsztatach poświęconych wizualizacjom danych.