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 год
<- oa_request("https://api.openalex.org/works?filter=language:ru,publication_year:2024", verbose = TRUE) df_works
#преобразовывание данных в датафрейм
<- works2df(df_works, abstract = TRUE) works
#фильтрация полученного датафрейма
<- works |>
filtered select(title, ab, type) |>
filter(type == "article") |>
filter(!is.na(ab)) |>
rename (abstract = ab) |>
select(-type)
#удаление аннотаций на английском
<- filtered[!grepl("[A-Za-z]", filtered$abstract), ]
iltered_text <- as_tibble(filtered_text) filtered_text
#токенизируем аннотации, чтобы выявить наиболее популярные темы
<- filtered_text |>
abstract unnest_tokens("word", "abstract", to_lower = FALSE)
# удаляем текст после точки и саму точку
<- abstract |>
cleaned_abstract mutate(word = gsub("\\..*", "", word))
<- cleaned_abstract |>
cleaned_abstract1 filter(!grepl("\\d", word))
# Убираем строки, где длина текста меньше или равна 1(это либо местоимения, либо ошибки токенизации)
<- cleaned_abstract1 |>
df_cleaned filter(nchar(word) > 3)
#лемматизация
udpipe_download_model(language = "russian-syntagrus")
<- udpipe_load_model(file = "russian-syntagrus-ud-2.5-191206.udpipe")
russian_syntagrus <- udpipe_annotate(russian_syntagrus, df_cleaned$word, title = df_cleaned$word)
filtered_annotate
<- as_tibble(filtered_annotate) annotate_tbl
# ручной поиск слов с ошибками в строках
<- annotate_tbl |>
df_mistake filter(grepl("научноисследовательский", lemma))
#Поиск наиболее часто встречающихся слов
<- annotate_tbl |>
most filter(!upos %in% "PRON") |>
count(lemma) |>
arrange(desc(n))
#облако наиболее частых слов
wordcloud2(data = most,
size = 1,
color = pal,
backgroundColor = "white",
shape = 'circle',
minSize = 1)
#поиск наиболее часто встречающихся существительных и глаголов
<- annotate_tbl |>
most_n filter(upos %in% "NOUN") |>
count(lemma) |>
arrange(-n) |>
slice_max(n, n = 20)
<- annotate_tbl |>
most_v filter(upos %in% "VERB") |>
count(lemma) |>
arrange(-n) |>
slice_max(n, n = 20)
#визуализация
<- ggplot(most_n, aes(x = reorder(lemma, -n), y = n, fill = n)) +
plot_nouns 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()
<- ggplot(most_v, aes(x = reorder(lemma, -n), y = n, fill = n)) +
plot_verbs 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)