library(rvest)
library(tidyverse)
library(openalexR)
library(dplyr)
library(tidyr)
library(tidytext)
library(tokenizers)
library(wordcloud2)
library(ggplot2)
library(udpipe)
library(readxl)
library(xml2)
library(data.table)
library(httr)
library(jsonlite)
library(dplyr)
library(wordcloud2)
library(RColorBrewer)
library(gridExtra)Анализ аннотацй русскоязычных статей
Задача работы: проанализировать метаданные статей, написанных на русском языке за 2024 год. Данные необходимо извлечь из базы данных OpenAlex.
Постановка проблемы и результаты: недавно исследователи обнаружили, что количество ошибок в аннотациях значительно возросло, в связи с чем я хочу проверить аннотации на встречающиеся ошибки. Так как в ходе работы я столкнулась с рядом ограничений (словарь из библиотеки hunspell распознает узкоспециализированный термины и имена собственные как слова с ошибкой). Я вручную посмотрела как часто встречаются ошибки в написании слова «научно-исследовательский». В 2024 году — всего два вхождения, однако на выборке за 21-23 год встречалось порядка 50, однако из-за большого объема данных мне не удалось провести работу с этой выборкой, преимущественно из-за ограниченных сроков (одна загрузка датасета заняла более часа). Таким образом в статьях за 2024 год ошибки все же встречаются, но необходимо избавиться от ограничений, мешающих провести полный анализ ошибок в аннотациях. Также из выборки аннотаций я хочу выделить наиболее часто встречающие слова. В дальнейшем эти данные могут позволить сделать срез актуальных направлений в журналах или дисциплинах и тематиках (в БД они присвоены каждой статье). В дальнейшем я планирую преодолеть ограничения, связанные с узкими терминами и встречаемость аннотаций на казахском языке и провести анализ ошибок анннотаций в разрезе по журналам и тематикам.
Недостатки работы: значительно затруднили работу: выгрузка данных по API, изучение документации новых для меня пакетов (openalexR, hunspell), а также большой объем анализируемых данных. Так загрузка и работа с метаданными статей за пятилетний и даже трехлетний период (более млн слов) занимает большое количество времени, в связи с чем выборку пришлось значительно сократить.
P.S. код не выполняется, так как датасет очень тяжелый. приложи скрины всех промежуточных таблиц
# загрузка научных публикаций на русском языке за 2024 год
df_works <- oa_request("https://api.openalex.org/works?filter=language:ru,publication_year:2024", verbose = TRUE)#преобразовывание данных в датафрейм
works <- works2df(df_works, abstract = TRUE)#фильтрация полученного датафрейма
filtered <- works |>
select(title, ab, type) |>
filter(type == "article") |>
filter(!is.na(ab)) |>
rename (abstract = ab) |>
select(-type)#удаление аннотаций на английском
iltered_text <- filtered[!grepl("[A-Za-z]", filtered$abstract), ]
filtered_text <- as_tibble(filtered_text)#токенизируем аннотации, чтобы выявить наиболее популярные темы
abstract <- filtered_text |>
unnest_tokens("word", "abstract", to_lower = FALSE)# удаляем текст после точки и саму точку
cleaned_abstract <- abstract |>
mutate(word = gsub("\\..*", "", word))cleaned_abstract1 <- cleaned_abstract |>
filter(!grepl("\\d", word))# Убираем строки, где длина текста меньше или равна 1(это либо местоимения, либо ошибки токенизации)
df_cleaned <- cleaned_abstract1 |>
filter(nchar(word) > 3) #лемматизация
udpipe_download_model(language = "russian-syntagrus")
russian_syntagrus <- udpipe_load_model(file = "russian-syntagrus-ud-2.5-191206.udpipe")
filtered_annotate <- udpipe_annotate(russian_syntagrus, df_cleaned$word, title = df_cleaned$word)
annotate_tbl <- as_tibble(filtered_annotate)# ручной поиск слов с ошибками в строках
df_mistake <- annotate_tbl |>
filter(grepl("научноисследовательский", lemma))#Поиск наиболее часто встречающихся слов
most <- annotate_tbl |>
filter(!upos %in% "PRON") |>
count(lemma) |>
arrange(desc(n)) #облако наиболее частых слов
wordcloud2(data = most,
size = 1,
color = pal,
backgroundColor = "white",
shape = 'circle',
minSize = 1)#поиск наиболее часто встречающихся существительных и глаголов
most_n <- annotate_tbl |>
filter(upos %in% "NOUN") |>
count(lemma) |>
arrange(-n) |>
slice_max(n, n = 20)
most_v <- annotate_tbl |>
filter(upos %in% "VERB") |>
count(lemma) |>
arrange(-n) |>
slice_max(n, n = 20)#визуализация
plot_nouns <- ggplot(most_n, aes(x = reorder(lemma, -n), y = n, fill = n)) +
geom_bar(stat = "identity") +
scale_fill_gradient(low = "lightblue", high = "darkblue") +
labs(title = "Наиболее частые существительные") +
theme_minimal(base_family = "Times New Roman") +
theme(text = element_text(size = 12),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank()) +
scale_y_continuous(labels = NULL) +
coord_flip()
plot_verbs <- ggplot(most_v, aes(x = reorder(lemma, -n), y = n, fill = n)) +
geom_bar(stat = "identity") +
scale_fill_gradient(low = "lightcoral", high = "red") +
labs(title = "Наиболее частые глаголы") +
theme_minimal(base_family = "Times New Roman") +
theme(text = element_text(size = 12),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank()) +
scale_y_continuous(labels = NULL) +
coord_flip()
grid.arrange(plot_nouns, plot_verbs, ncol = 2)