#Szerző és cím kinyerése az EREDETI fajlnevek vektorból
texts$szerzo <- basename(dirname(fajlnevek))
texts$cim <- sub("\\.txt$", "", basename(fajlnevek))
konyv_korpusz <- quanteda::corpus(texts)
# Ellenőrzés
summary(konyv_korpusz) Tokens (Szóelőfordulások/Textus-szavak) =
A szövegben található összes szó száma, függetlenül attól, hogy hányszor
ismétlődnek.
Types (Szóalakok/Szótári szavak) = A szövegben
előforduló különböző, egyedi szóalakok száma. Minden egyedi forma csak
egyszer számít.
A Type/Token arány (TTR) a szöveggazdagságot,
választékosságot mutatja.
szavak <- tokens(konyv_korpusz,
remove_punct = TRUE,
remove_numbers = TRUE,
remove_symbols = TRUE)
szavak <- tokens_tolower(szavak)
# Magyar szavak és az egyedi szavak összevonása egy vektorba
sajat_kizárandó <- c(stopwords("hu"), "page", "oldal", "txt", "pdf")
# Alkalmazás a korpuszon
szavak <- tokens_remove(szavak, sajat_kizárandó)
#Figyelem! Ez egy kiemelt információs doboz.
A szövegbányászatban (text mining) és a természetes nyelvfeldolgozásban (NLP) a stopword-ök (stoplisták vagy tiltószavak) olyan rendkívül gyakori szavak, amelyek kevés önálló jelentéssel bírnak, ezért a szövegek előfeldolgozása során általában eltávolítjuk őket. Példák stopword-ökre: Angol nyelvben: the, is, at, which, on, and, a, an Magyar nyelvben: a, az, egy, és, hogy, vagy, volt, mint, sem Ha van egy mondatunk: „A macska ül az asztal mellett.” – a stopword-ök (a, az, mellett) kiszűrése után a lényegi kulcsszavak maradnak meg: „macska, ül, asztal”. A magyar nyelv szaktudósok által kiválasztott tiltószavai (összesen 199 db):
## [1] "a" "ahogy" "ahol" "aki" "akik"
## [6] "akkor" "alatt" "által" "általában" "amely"
## [11] "amelyek" "amelyekben" "amelyeket" "amelyet" "amelynek"
## [16] "ami" "amit" "amolyan" "amíg" "amikor"
## [21] "át" "abban" "ahhoz" "annak" "arra"
## [26] "arról" "az" "azok" "azon" "azt"
## [31] "azzal" "azért" "aztán" "azután" "azonban"
## [36] "bár" "be" "belül" "benne" "cikk"
## [41] "cikkek" "cikkeket" "csak" "de" "e"
## [46] "eddig" "egész" "egy" "egyes" "egyetlen"
## [51] "egyéb" "egyik" "egyre" "ekkor" "el"
## [56] "elég" "ellen" "elő" "először" "előtt"
## [61] "első" "én" "éppen" "ebben" "ehhez"
## [66] "emilyen" "ennek" "erre" "ez" "ezt"
## [71] "ezek" "ezen" "ezzel" "ezért" "és"
## [76] "fel" "felé" "hanem" "hiszen" "hogy"
## [81] "hogyan" "igen" "így" "illetve" "ill."
## [86] "ill" "ilyen" "ilyenkor" "ison" "ismét"
## [91] "itt" "jó" "jól" "jobban" "kell"
## [96] "kellett" "keresztül" "keressünk" "ki" "kívül"
## [101] "között" "közül" "legalább" "lehet" "lehetett"
## [106] "legyen" "lenne" "lenni" "lesz" "lett"
## [111] "maga" "magát" "majd" "majd" "már"
## [116] "más" "másik" "meg" "még" "mellett"
## [121] "mert" "mely" "melyek" "mi" "mit"
## [126] "míg" "miért" "milyen" "mikor" "minden"
## [131] "mindent" "mindenki" "mindig" "mint" "mintha"
## [136] "mivel" "most" "nagy" "nagyobb" "nagyon"
## [141] "ne" "néha" "nekem" "neki" "nem"
## [146] "néhány" "nélkül" "nincs" "olyan" "ott"
## [151] "össze" "ő" "ők" "őket" "pedig"
## [156] "persze" "rá" "s" "saját" "sem"
## [161] "semmi" "sok" "sokat" "sokkal" "számára"
## [166] "szemben" "szerint" "szinte" "talán" "tehát"
## [171] "teljes" "tovább" "továbbá" "több" "úgy"
## [176] "ugyanis" "új" "újabb" "újra" "után"
## [181] "utána" "utolsó" "vagy" "vagyis" "valaki"
## [186] "valami" "valamint" "való" "vagyok" "van"
## [191] "vannak" "volt" "voltam" "voltak" "voltunk"
## [196] "vissza" "vele" "viszont" "volna"
# 1. Szükséges csomagok telepítése és betöltése
# install.packages(c("quanteda", "quanteda.textmodels", "quanteda.textplots"))
library(quanteda)
library(quanteda.textplots)
# 2. A konyv korpusz betöltése és tokenizálása
# Kisbetűssé alakítunk és eltávolítjuk az írásjeleket
tokens_konyv <- tokens(konyv_korpusz,
remove_punct = TRUE,
remove_symbols = TRUE) %>%
tokens_tolower()
# 3. Stop szavak (töltelékszavak) eltávolítása
tokens_clean <- tokens_select(tokens_konyv,
pattern = stopwords("hu"),
selection = "remove")
# 4. Dokumentum-kifejezés mátrix (DFM) létrehozása
# Csak a leggyakoribb szavakat tartjuk meg a hálózat átláthatóságáért
dfm_konyv <- dfm(tokens_clean)
dfm_top <- dfm_select(dfm_konyv, pattern = names(topfeatures(dfm_konyv, 50)))
# 5. Szó-együttelőfordulási mátrix (FCM) létrehozása
fcm_konyv <- fcm(dfm_top)
# 6. A szóhálózat kirajzolása
textplot_network(fcm_konyv,
min_freq = 0.8, # Kapcsolatok erősségének szűrése
edge_color = "steelblue", # Élek színe
edge_alpha = 0.6, # Élek átlátszósága
vertex_labelsize = 4) # Címkék betűmérete## feature frequency rank docfreq group
## 1 is 15359 1 16 all
## 2 ha 5390 2 16 all
## 3 hát 3096 3 16 all
## 4 se 2888 4 15 all
## 5 ember 2464 5 16 all
## 6 két 2436 6 16 all
## 7 kis 2209 7 16 all
## 8 te 2104 8 16 all
## 9 mondta 1843 9 16 all
## 10 úr 1701 10 16 all
## 11 le 1363 11 16 all
## 12 mind 1214 12 16 all
## 13 szép 1114 13 16 all
## 14 szólt 1063 14 15 all
## 15 hol 1034 15 16 all
## 16 török 1031 16 7 all
## 17 egyszer 985 17 16 all
## 18 öreg 942 18 16 all
## 19 asszony 939 19 15 all
## 20 ön 939 19 9 all
## 21 hozzá 847 21 16 all
## 22 no 847 21 15 all
## 23 uram 837 23 13 all
## 24 nap 833 24 16 all
## 25 nézett 819 25 15 all
ggplot(gyakori_szavak, aes(x =
reorder(feature, frequency), y = frequency)) +
geom_col() +
coord_flip() +
labs(title = "A 25 leggyakoribb szó a teljes korpuszban", x = "Szavak", y = "Gyakoriság")# Ha még nincs meg a gyakori_szavak, így generálható:
gyakori_szavak <- textstat_frequency(konyv_dfm, n = 25)
# wordcloud2 adatframe-et vár "word" és "freq" oszlopokkal
if(!require(ggwordcloud)) install.packages("ggwordcloud")## A szükséges csomag betöltődik: ggwordcloud
library(ggwordcloud)
# 1. Adatok előkészítése
wc_data <- data.frame(
word = gyakori_szavak$feature,
freq = gyakori_szavak$frequency
)
# 2. Kirajzolás ggplot alapon
ggplot(wc_data, aes(label = word, size = freq, color = freq)) +
geom_text_wordcloud(shape = "triangle-forward") + # A beépített formák közül ez hasonlít legjobban a toll hegyére
scale_size_area(max_size = 25) +
theme_minimal() +
scale_color_gradient(low = "darkblue", high = "darkred")A szavakat írótoll alakban rendeztettem el az algoritmussal (ld. forráskód), a ‘stylus’ ui. az ókori Rómában ezt jelentette, s innen került át a mai nyelvekbe.
#A stilometriai elemzések alapja a dokumentum/szó gyakoriságtáblázat. Az
#alábbi függvény ezt normált relatív értékekkel adja vissza.
# Csoportonkénti TOP 5 szó kigyűjtése
#freq_top5 <- textstat_frequency(konyv_dfm, n = 5, groups = docvars(konyv_dfm,"szerzo"))
#print(freq_top5)
tofu <- topfeatures(
konyv_dfm,
n = 20,
decreasing = TRUE,
groups = szerzo
)
print(tofu)## $`Fekete István`
## is ha gyula mondta bütyök kis hát miska kele bácsi
## 2206 820 758 492 466 436 412 384 355 332
## se nézett öreg ember kutya le érezte két csikasz gólya
## 311 299 254 226 216 211 203 198 197 186
##
## $`Gárdonyi Géza`
## is török ha hát gergely két se ember
## 2870 937 877 858 732 646 466 444
## te felelte uram mondotta kis atilla szólt pap
## 440 408 359 334 326 277 274 264
## asszony mind hol le
## 255 254 250 250
##
## $`Jókai Mór`
## is ha hát ön úr két timár ember te mind
## 2439 1168 733 694 667 646 618 607 595 485
## őt szép no mihály kis le egyszer hozzá szólt amint
## 361 352 342 340 338 301 291 288 285 274
##
## $`Kosztolányi Dezső`
## is se nero mondta császár szólt anna seneca
## 1104 451 400 305 249 238 210 190
## melyet föl te két ha kis őt kérdezte
## 176 170 164 161 159 158 149 143
## jancsi le ment valamit
## 113 109 103 103
##
## $`Márai Sándor`
## is ember ha j emberi te élet
## 763 336 317 262 222 186 160
## emberek mondja tábornok világ krisztina soha mondta
## 147 145 132 128 111 108 102
## melyet valamit két valamilyen igazi napon
## 86 81 78 73 66 61
##
## $`Mikszáth Kálmán`
## is ha jókai se hát kis ember két úr magyar közt
## 2134 699 616 496 339 332 285 261 217 196 189
## szép gyuri hol le öreg végre mégis hozzá pál
## 188 171 157 155 142 133 130 130 127
##
## $`Móra Ferenc`
## is se ha ferenc mátyás hát császár kis te etel
## 3262 951 863 615 497 496 470 458 450 429
## ember két mondta isten úr lány föl ugyan fiú le
## 326 321 297 287 284 251 230 221 218 215
##
## $`Rejtő Jenő`
## is ha sir mondta gróf ön úr ember kérem leány hát
## 581 487 280 275 245 178 175 169 162 148 146
## kis mr lord két miss kissé tanár hiszem állt
## 142 139 135 125 123 113 112 98 97
A stilometriai elemzések alapja a dokumentum × szó
frekvenciatáblázat. A make.table.of.frequencies() ezt
normalizált relatív értékként adja vissza.
# make.table.of.frequencies() a szólistát (features) és a korpuszt várja.
texts_raw <- as.list(as.character(konyv_korpusz))
# `load.corpus()` és `make.frequency.list()` — Korpusz betöltése és szógyakoriságok# Tokenizálás a stylo txt.to.words() segítségével
word_lists <- lapply(texts_raw, txt.to.words)
# make.frequency.list() alapértelmezetten (value=FALSE) csak a szavak neveit adja vissza.
# value=TRUE esetén a frekvenciaértékeket adja, a neveket names()-szel érjük el.
freq_list_vals <- make.frequency.list(word_lists, value = TRUE) # named numeric vektor
freq_list_words <- names(freq_list_vals) # szavak sorrendben
# A features argumentum: karaktervektor a szavakról (freq_list_words)
freq_table <- make.table.of.frequencies(word_lists, freq_list_words, relative = TRUE)## processing 16 text samples
## .
## combining frequencies into a table...
freq_table_100 <- freq_table[, 1:100]
cat("Táblázat dimenziói:", nrow(freq_table_100), "dokumentum ×",
ncol(freq_table_100), "szó\n")## Táblázat dimenziói: 16 dokumentum × 100 szó
# Első 6 sor és 8 oszlop megtekintése
knitr::kable(round(freq_table_100[1:16, 1:10], 4),
caption = "Relatív szófrekvenciák (16 dokumentum, top 10 szó)")| a | az | és | nem | hogy | is | egy | s | volt | de | |
|---|---|---|---|---|---|---|---|---|---|---|
| Kele.txt | 9.1833 | 2.6079 | 2.7720 | 2.1610 | 1.0637 | 1.3626 | 0.7091 | 0.3619 | 0.8175 | 1.2453 |
| Tüskevár.txt | 8.4372 | 2.2713 | 2.7583 | 2.0899 | 1.2520 | 1.5242 | 0.8832 | 0.5502 | 0.8952 | 1.3809 |
| A láthatatlan ember.txt | 9.8224 | 2.9230 | 1.5485 | 1.4379 | 1.7319 | 1.5633 | 0.9132 | 1.1209 | 0.7351 | 0.8322 |
| Egri csillagok.txt | 10.7482 | 3.0666 | 1.6043 | 1.2616 | 1.4344 | 1.2580 | 1.0396 | 0.9720 | 0.6044 | 0.5985 |
| A kőszívű ember fiai.txt | 7.1920 | 3.0327 | 1.0001 | 1.5487 | 1.5346 | 0.7958 | 1.2137 | 1.2453 | 0.7670 | 0.4340 |
| Az arany ember.txt | 7.8196 | 2.9742 | 0.9611 | 1.5077 | 1.7157 | 0.8991 | 1.0726 | 1.6509 | 0.8110 | 0.4172 |
| Édes Anna.txt | 7.8504 | 2.9549 | 1.3251 | 1.5396 | 1.7140 | 1.1868 | 1.3131 | 0.7197 | 0.8039 | 0.6375 |
| Néró, a véres költő.txt | 7.0404 | 2.2368 | 2.9921 | 1.7664 | 1.2707 | 0.9229 | 0.8688 | 0.3767 | 0.6849 | 0.6327 |
| A gyertyak csonkig egnek.txt | 9.0030 | 3.0919 | 2.8191 | 1.9263 | 1.0499 | 1.0306 | 1.0058 | 1.6286 | 0.9425 | 0.5071 |
| Füveskonyv.txt | 7.3494 | 3.4508 | 3.3421 | 1.8549 | 1.1705 | 1.2441 | 0.8443 | 1.3496 | 0.1599 | 0.6940 |
| Jókai Mór élete és kora.txt | 8.0824 | 2.8969 | 1.6645 | 1.3507 | 1.3437 | 1.2990 | 1.1772 | 0.8651 | 0.9677 | 0.8090 |
| Szent Péter esernyője.txt | 8.4838 | 3.1855 | 1.0861 | 1.5160 | 1.5505 | 1.2512 | 1.2723 | 0.8348 | 0.8271 | 0.8635 |
| Aranykoporsó.txt | 9.0161 | 3.3532 | 1.6402 | 1.7903 | 1.7830 | 1.3846 | 0.6568 | 0.8206 | 0.7214 | 0.7005 |
| Ének a búzamezőkről.txt | 8.7138 | 3.6177 | 1.3460 | 2.1291 | 2.0209 | 2.2182 | 0.6851 | 0.2598 | 0.6571 | 1.1244 |
| A láthatatlan légió.txt | 7.8436 | 2.5479 | 2.8067 | 1.7315 | 1.7268 | 0.7011 | 1.4586 | 0.0188 | 0.6799 | 0.9481 |
| A szőke ciklon.txt | 8.1940 | 2.5689 | 2.5079 | 1.3722 | 1.8328 | 0.6897 | 1.4282 | 0.0244 | 0.6386 | 0.6727 |
dist.delta() — Burrows-féle delta távolság a művek
közöttA Burrows-Delta a stilometria legismertebb
távolságmértéke: a z-score-ra normalizált szófrekvenciák
Manhattan-távolságaként számítja ki két szöveg stilisztikai
különbségét.
A Z-score (magyarul:
sztenderdizált érték vagy Z-érték) azt mutatja meg, hogy egy adott
adatpont hány szórásnyi távolságra van a csoport átlagától. A kifejezést
a tudomány, az orvostudomány és a pénzügy különböző területein
használják, de a magva mindegyiknél ugyanaz a matematikai elv.
A
képlet: \(Z = \frac{X - \mu}{\sigma}\),
ahol x a megfigyelt érték, μ a populáció átlaga, és σ a populáció
szórása.
A Manhattan-távolság a két pont közötti távolságot méri
úgy, hogy csak vízszintesen és függőlegesen lehet haladni – mint egy
sakktáblán vagy városban, ahol csak az utcákon lehet közlekedni.
Képlete (2D-ben): \[d_{\text{Manhattan}}(A,
B) = |x_1 - x_2| + |y_1 - y_2|\] szemben az euklideszi
távolsággal, amely az „átlós” légvonalbeli távolságot méri: \[d_{\text{Euler}}(A, B) = \sqrt{(x_1 - x_2)^2 +
(y_1 - y_2)^2}\]
# Z-score normalizálás
zscores <- scale(freq_table_100)
# Delta-távolság kiszámítása
delta_dist <- dist.delta(freq_table_100)
delta_mat <- as.matrix(delta_dist)
# Leghasonlóbb szövegpárok (legkisebb Delta-érték)
delta_df <- as.data.frame(as.table(delta_mat)) %>%
rename(Doc1 = Var1, Doc2 = Var2, Delta = Freq) %>%
filter(as.character(Doc1) < as.character(Doc2)) %>%
arrange(Delta) %>%
head(15)
knitr::kable(delta_df, digits = 3,
caption = "Leghasonlóbb szövegpárok (legkisebb Burrows-Delta)") %>%
kable_styling(bootstrap_options = c("striped", "condensed"))| Doc1 | Doc2 | Delta |
|---|---|---|
| A kőszívű ember fiai.txt | Az arany ember.txt | 0.390 |
| A láthatatlan légió.txt | A szőke ciklon.txt | 0.569 |
| Kele.txt | Tüskevár.txt | 0.595 |
| Jókai Mór élete és kora.txt | Szent Péter esernyője.txt | 0.680 |
| A láthatatlan ember.txt | Egri csillagok.txt | 0.711 |
| A kőszívű ember fiai.txt | Szent Péter esernyője.txt | 0.757 |
| Édes Anna.txt | Néró, a véres költő.txt | 0.772 |
| Az arany ember.txt | Szent Péter esernyője.txt | 0.780 |
| Édes Anna.txt | Szent Péter esernyője.txt | 0.818 |
| A szőke ciklon.txt | Édes Anna.txt | 0.834 |
| Aranykoporsó.txt | Édes Anna.txt | 0.845 |
| Aranykoporsó.txt | Ének a búzamezőkről.txt | 0.863 |
| Kele.txt | Szent Péter esernyője.txt | 0.865 |
| Édes Anna.txt | Jókai Mór élete és kora.txt | 0.873 |
| A szőke ciklon.txt | Szent Péter esernyője.txt | 0.877 |
delta_long <- as.data.frame(delta_mat) %>%
tibble::rownames_to_column("Doc1") %>%
pivot_longer(-Doc1, names_to = "Doc2", values_to = "Delta")
ggplot(delta_long, aes(x = Doc1, y = Doc2, fill = Delta)) +
geom_tile() +
scale_fill_distiller(palette = "RdYlBu", direction = -1) +
labs(title = "Burrows-Delta hőtérkép",
subtitle = "A 16 vizsgált regény páronkénti távolsága",
x = NULL, y = NULL) +
theme_minimal(base_size = 10) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))dist.cosine() — Koszinusz-távolságA koszinusz-hasonlóság a vektorok szögét méri;
dist.cosine() az ebből számított távolságot adja vissza (1
− koszinusz-hasonlóság).
cos_dist <- dist.cosine(freq_table_100)
cos_mat <- as.matrix(cos_dist)
# Leghasonlóbb párok koszinusz szerint
cos_df <- as.data.frame(as.table(cos_mat)) %>%
rename(Doc1 = Var1, Doc2 = Var2, CosDist = Freq) %>%
filter(as.character(Doc1) < as.character(Doc2)) %>%
arrange(CosDist) %>%
head(15)
knitr::kable(cos_df, digits = 4,
caption = "Leghasonlóbb párok — koszinusz-távolság alapján") %>%
kable_styling(bootstrap_options = c("striped", "condensed"))| Doc1 | Doc2 | CosDist |
|---|---|---|
| A kőszívű ember fiai.txt | Az arany ember.txt | 0.0025 |
| Kele.txt | Tüskevár.txt | 0.0040 |
| A láthatatlan légió.txt | A szőke ciklon.txt | 0.0045 |
| Jókai Mór élete és kora.txt | Szent Péter esernyője.txt | 0.0052 |
| Édes Anna.txt | Szent Péter esernyője.txt | 0.0053 |
| A láthatatlan ember.txt | Egri csillagok.txt | 0.0058 |
| Édes Anna.txt | Jókai Mór élete és kora.txt | 0.0062 |
| Aranykoporsó.txt | Édes Anna.txt | 0.0073 |
| A láthatatlan ember.txt | Aranykoporsó.txt | 0.0074 |
| Aranykoporsó.txt | Jókai Mór élete és kora.txt | 0.0076 |
| Aranykoporsó.txt | Szent Péter esernyője.txt | 0.0078 |
| A kőszívű ember fiai.txt | Szent Péter esernyője.txt | 0.0086 |
| A láthatatlan ember.txt | Szent Péter esernyője.txt | 0.0089 |
| A láthatatlan ember.txt | Jókai Mór élete és kora.txt | 0.0091 |
| Az arany ember.txt | Szent Péter esernyője.txt | 0.0109 |
A stylo belső munkafolyamatát követve a
Delta-távolságmátrixból hierarchikus klaszter és dendrogram
készíthető.
## Warning: a(z) 'ggdendro' csomag az R 4.5.2 verziójával lett fordítva
# Hierarchikus klaszterezés Ward-módszerrel
hc <- hclust(delta_dist, method = "ward.D2")
# Dendrogram ggplot-tal
dend_data <- dendro_data(hc, type = "rectangle")
ggplot() +
geom_segment(data = segment(dend_data),
aes(x = x, y = y, xend = xend, yend = yend),
colour = "#555555") +
geom_text(data = label(dend_data),
aes(x = x, y = y, label = label),
hjust = 1, size = 2.8, nudge_y = -0.02) +
coord_flip() +
scale_y_reverse(expand = expansion(mult = c(.3, .05))) +
labs(title = "Hierarchikus klaszterfa — Burrows-Delta (Ward)",
subtitle = "16 magyar regény",
x = NULL, y = "Delta-távolság") +
theme_minimal(base_size = 11) +
theme(axis.text.y = element_blank(),
panel.grid = element_blank()) A stylo a szavakon kívül
n-gramokkal is tud dolgozni, amelyek robusztusabbak
zajosabb szövegekre. A make.ngrams() függvény ezt
biztosítja. Felmerülhet, hogy ekkora háttér adatbázis mellett (16 teljes
regény) ezek a számok valóben megfelelnek-e a szövegeknek? Nos, az egyik
regény szívemhez különösen közel álló két alakjának példájával, a
nagyszerű ‘kwic’ - ‘keyword in context’ - függvény segítségével a regény
szavainak sorszámáig menő pontossággal támasztom alá a statisztikát.
# Karakter-trigramok (egy minta-könyven illusztrálva)
sample_words <- word_lists[["Kele.txt"]]
char_trigrams <- make.ngrams(sample_words, ngram.size = 3)
# Top 20 karakter-trigram
char_freq <- sort(table(char_trigrams), decreasing = TRUE)
top_char <- data.frame(
trigram = names(char_freq)[1:25],
count = as.numeric(char_freq)[1:25]
)
knitr::kable(top_char,
caption = "Top 25 szó-trigram — Fekete István: Kele") %>%
kable_styling(bootstrap_options = c("striped", "condensed")) | trigram | count |
|---|---|
| a nagy fény | 26 |
| tás tás tás | 19 |
| most már nem | 18 |
| a kis fény | 16 |
| volt mint a | 16 |
| már nem is | 15 |
| azt mondta volna | 12 |
| és most már | 12 |
| a gólya nem | 10 |
| a kutya nem | 10 |
| a magányos gólya | 10 |
| mintha azt mondta | 10 |
| a nagy fehérség | 9 |
| de ez a | 9 |
| de most már | 9 |
| meg se moccant | 9 |
| nem is volt | 9 |
| a levegőbe és | 8 |
| a levegőben a | 8 |
| abban a pillanatban | 8 |
| az ember nem | 8 |
| az öreg gólya | 8 |
| az öreg ribizke | 8 |
| azt mondta hogy | 8 |
| billegette fülét miska | 8 |
# A gyakorisági lista elkészítése (Melyek a leggyakoribb szavak?)
global_frequent_words <- make.frequency.list(szavak)
# 5. A keresett numerikus MÁTRIX legenerálása
# Itt az első 100 leggyakoribb szót (MFW) vesszük alapul, relatív gyakorisággal
fkv_matrix <- make.table.of.frequencies(szavak,
features = global_frequent_words[1:100],
relative = TRUE)## processing 16 text samples
## .
## combining frequencies into a table...
# --- ELLENŐRZÉS ---
# Nézzük meg a mátrix szerkezetét (dimenzióit)
print(dim(fkv_matrix)) # Sorok száma (szövegek) x Oszlopok száma (100 szó)## [1] 16 100
## is ha hát se
## Kele.txt 2.278853 0.8282284 0.40186229 0.622396471
## Tüskevár.txt 2.569783 0.9707174 0.49945624 0.114794377
## A láthatatlan ember.txt 2.493546 0.7723752 0.58950086 0.342082616
## Egri csillagok.txt 1.978446 0.5989686 0.67528503 0.354987165
## A kőszívű ember fiai.txt 1.278868 0.6467707 0.43230919 0.098200781
## Az arany ember.txt 1.483636 0.6759290 0.39760528 0.123825644
## Édes Anna.txt 1.867154 0.2523182 0.21447045 0.586639753
## Néró, a véres költő.txt 1.411285 0.2177568 0.06615397 0.730450123
## A gyertyak csonkig egnek.txt 1.719777 0.5104152 0.05977836 0.009196671
## Füveskonyv.txt 2.018682 1.0690192 0.03632590 0.025947068
## Jókai Mór élete és kora.txt 2.060050 0.6283014 0.20155685 0.453155407
## Szent Péter esernyője.txt 2.022458 0.7661766 0.60177430 0.527327998
## Aranykoporsó.txt 2.262760 0.6898295 0.19178449 0.680909267
## Ének a búzamezőkről.txt 3.752912 0.8605815 0.79156242 1.063324994
## A láthatatlan légió.txt 1.104972 0.9900256 0.40787571 0.037079610
## A szőke ciklon.txt 1.077233 0.8374253 0.13703323 0.000000000
## ember két kis te
## Kele.txt 0.36755697 0.19112963 0.52683166 0.25483950
## Tüskevár.txt 0.15305917 0.24167237 0.44507995 0.15104523
## A láthatatlan ember.txt 0.33347676 0.35929432 0.20008606 0.32917384
## Egri csillagok.txt 0.33417359 0.55387248 0.26942023 0.33186097
## A kőszívű ember fiai.txt 0.27089871 0.40521932 0.14899429 0.28782988
## Az arany ember.txt 0.41691754 0.32603633 0.23401911 0.38624513
## Édes Anna.txt 0.07884943 0.31855169 0.26493408 0.19239261
## Néró, a véres költő.txt 0.12679512 0.16538493 0.20397475 0.28391080
## A gyertyak csonkig egnek.txt 0.69894698 0.29889180 0.06437670 0.52880857
## Füveskonyv.txt 0.95485210 0.06746238 0.02594707 0.36844837
## Jókai Mór élete és kora.txt 0.24464832 0.22657770 0.29886016 0.04309147
## Szent Péter esernyője.txt 0.33811030 0.30398908 0.36292574 0.10856753
## Aranykoporsó.txt 0.19327119 0.28693338 0.41627641 0.53818593
## Ének a búzamezőkről.txt 0.42274178 0.27607627 0.38391856 0.18980243
## A láthatatlan légió.txt 0.35967222 0.19281397 0.25584931 0.05561941
## A szőke ciklon.txt 0.27406646 0.27787294 0.27787294 0.03425831
## mondta úr
## Kele.txt 0.394511149 0.029404558
## Tüskevár.txt 0.666612962 0.074515648
## A láthatatlan ember.txt 0.131239243 0.144148021
## Egri csillagok.txt 0.123725168 0.197729007
## A kőszívű ember fiai.txt 0.097072036 0.413120527
## Az arany ember.txt 0.087473162 0.341940541
## Édes Anna.txt 0.305935785 0.189238630
## Néró, a véres költő.txt 0.573334436 0.005512831
## A gyertyak csonkig egnek.txt 0.464431876 0.018393342
## Füveskonyv.txt 0.005189414 0.025947068
## Jókai Mór élete és kora.txt 0.029190992 0.063942174
## Szent Péter esernyője.txt 0.062038588 0.530429927
## Aranykoporsó.txt 0.221518517 0.055007954
## Ének a búzamezőkről.txt 0.319213183 0.532740920
## A láthatatlan légió.txt 0.630353369 0.470911046
## A szőke ciklon.txt 0.399680256 0.182710974
#A `stylo` a PCA-t a frekvenciatáblán végzi. Az `prcomp()` + vizualizáció
#megmutatja, milyen stilisztikai tengelyek mentén különülnek el a szövegek.
# PCA a z-score-olt top 100 MFW-en
zscores <- scale(freq_table_100)
pca_res <- prcomp(zscores, scale. = FALSE)
#
#1. Összefoglaló táblázat (megmutatja a magyarázott variancia %-os arányát)
#2. Az első 5 szöveg koordinátáinak megtekintése az első 2 főkomponensen
#head(pca_res$x[, 1:2])
#3. Megnézni, melyik szavak kapták a legnagyobb súlyt az első főkomponensben
head(sort(pca_res$rotation[, 1], decreasing = TRUE))## vagy minden és ember kell ilyen
## 0.1617785 0.1578463 0.1552553 0.1456440 0.1427342 0.1398548
#
# 1. A szórásokat négyzetre emeljük, hogy megkapjuk a varianciákat (sajátértékeket)
pca_variance <- pca_res$sdev^2
# 2. Kiszámoljuk az egyes komponensek százalékos arányát a teljes varianciához képest
pca_percentage <- (pca_variance / sum(pca_variance)) * 100
# 3. Kerekítjük az eredményt tizedesjegyre a szebb megjelenésért
pca_percentage <- round(pca_percentage, 1)
# Ellenőrzés: írassuk ki az első két komponens százalékát
print(paste0("PC1: ", pca_percentage[1], "%"))## [1] "PC1: 24.8%"
## [1] "PC2: 15%"
# And now visualize PCA results
# Grafikon rajzolása a százalékos értékek automatikus megjelenítésével
plot(pca_res$x[,1], pca_res$x[,2],
xlab = paste0("PC1 (", pca_percentage[1], "%)"),
ylab = paste0("PC2 (", pca_percentage[2], "%)"),
main = "Szövegek stilisztikai térképe (PCA)",
type = "n")
# Szövegek neveinek kiírása
text(pca_res$x[,1], pca_res$x[,2],
labels = rownames(fkv_matrix),
col = "darkred", cex = 0.8)#
# 1. Kiszámoljuk a százalékokat (ha az előző lépésből nem maradt meg a memóriában)
pca_variance <- pca_res$sdev^2
pca_percentage <- (pca_variance / sum(pca_variance)) * 100
# 2. Megrajzoljuk a kőgörbét az első 10 főkomponensre
plot(pca_percentage[1:10],
type = "b", # "b" mint both: pontok és vonalak egyszerre
pch = 19, # Teli kör alakú pontok
col = "blue", # Kék színű vonal
lwd = 2, # Vonalvastagság
xlab = "Főkomponensek",
ylab = "Magyarázott variancia (%)",
main = "Scree Plot (Százalékos bontás)",
xaxt = "n") # Kikapcsoljuk az alapértelmezett X tengelyt a szebb számozásért
# 3. Egyedi X tengely feliratok (PC1, PC2, PC3...)
axis(1, at = 1:10, labels = paste0("PC", 1:10))
# 4. Rács hozzáadása a könnyebb leolvashatóságért
grid(nx = NULL, ny = TRUE, col = "gray", lty = "dotted")#
# Biplot
# 1. Kiszámoljuk a szavak távolságát a középponttól a PC1 és PC2 síkon
word_importance <- rowSums(pca_res$rotation[, 1:2]^2)
# 2. Kiválasztjuk a 10 legnagyobb hatású szó indexét
top_words <- order(word_importance, decreasing = TRUE)[1:10]
# 3. Készítünk egy másolatot a PCA eredményből, ahol csak a top szavak maradnak
pca_clean <- pca_res
pca_clean$rotation <- pca_res$rotation[top_words, ]
# 4. Erre hívjuk meg a biplotot – a kép letisztul, a nyilak értelmezhetőek lesznek
# 1. Üres grafikon létrehozása a tengelyekkel
plot(pca_res$x[,1], pca_res$x[,2],
xlab = "PC1", ylab = "PC2",
main = "Tiszta PCA Grafikon",
type = "n") # a "n" jelentése: ne rajzoljon pontokat
# 2. Csak a regények címeinek kiírása
text(pca_res$x[,1], pca_res$x[,2],
labels = rownames(pca_res$x),
col = "darkgray", cex = 0.8, font = 2) # font = 2: félkövér szöveg
#…………………………………………………….