Задача работы: проанализировать метаданные статей, написанных на русском языке за 2024 год. Данные необходимо извлечь из базы данных OpenAlex.
Постановка проблемы и результаты: недавно исследователи обнаружили, что количество ошибок в аннотациях значительно возросло, в связи с чем я хочу проверить аннотации на встречающиеся ошибки. Так как в ходе работы я столкнулась с рядом ограничений (словарь из библиотеки hunspell распознает узкоспециализированный термины и имена собственные как слова с ошибкой). Я вручную посмотрела как часто встречаются ошибки в написании слова «научно-исследовательский». В 2024 году — всего два вхождения, однако на выборке за 21-23 год встречалось порядка 50, однако из-за большого объема данных мне не удалось провести работу с этой выборкой, преимущественно из-за ограниченных сроков (одна загрузка датасета заняла более часа). Таким образом в статьях за 2024 год ошибки все же встречаются, но необходимо избавиться от ограничений, мешающих провести полный анализ ошибок в аннотациях. Также из выборки аннотаций я хочу выделить наиболее часто встречающие слова. В дальнейшем эти данные могут позволить сделать срез актуальных направлений в журналах или дисциплинах и тематиках (в БД они присвоены каждой статье). В дальнейшем я планирую преодолеть ограничения, связанные с узкими терминами и встречаемость аннотаций на казахском языке и провести анализ ошибок анннотаций в разрезе по журналам и тематикам.
Недостатки работы: значительно затруднили работу: выгрузка данных по API, изучение документации новых для меня пакетов (openalexR, hunspell), а также большой объем анализируемых данных. Так загрузка и работа с метаданными статей за пятилетний и даже трехлетний период (более млн слов) занимает большое количество времени, в связи с чем выборку пришлось значительно сократить.
library(rvest)library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ readr::guess_encoding() masks rvest::guess_encoding()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(openalexR)
Thank you for using openalexR!
To acknowledge our work, please cite the package by calling `citation("openalexR")`.
To suppress this message, add `openalexR.message = suppressed` to your .Renviron file.
Attaching package: 'data.table'
The following objects are masked from 'package:lubridate':
hour, isoweek, mday, minute, month, quarter, second, wday, week,
yday, year
The following objects are masked from 'package:dplyr':
between, first, last
The following object is masked from 'package:purrr':
transpose
library(httr)library(jsonlite)
Attaching package: 'jsonlite'
The following object is masked from 'package:purrr':
flatten
Attaching package: 'gridExtra'
The following object is masked from 'package:dplyr':
combine
# загрузка научных публикаций на русском языке за 2024 годdf_works <-oa_request("https://api.openalex.org/works?filter=language:ru,publication_year:2024", verbose =TRUE)
Getting 239 pages of results with a total of 47609 records...
#преобразовывание данных в датафреймworks <-works2df(df_works, abstract =TRUE)
# Убираем строки, где длина текста меньше или равна 1(это либо местоимения, либо ошибки токенизации)df_cleaned <- cleaned_abstract1 |>filter(nchar(word) >3)
Downloading udpipe model from https://raw.githubusercontent.com/jwijffels/udpipe.models.ud.2.5/master/inst/udpipe-ud-2.5-191206/russian-syntagrus-ud-2.5-191206.udpipe to /Users/nastasyaorlova/Desktop/russian-syntagrus-ud-2.5-191206.udpipe
- This model has been trained on version 2.5 of data from https://universaldependencies.org
- The model is distributed under the CC-BY-SA-NC license: https://creativecommons.org/licenses/by-nc-sa/4.0
- Visit https://github.com/jwijffels/udpipe.models.ud.2.5 for model license details.
- For a list of all models and their licenses (most models you can download with this package have either a CC-BY-SA or a CC-BY-SA-NC license) read the documentation at ?udpipe_download_model. For building your own models: visit the documentation by typing vignette('udpipe-train', package = 'udpipe')
Downloading finished, model stored at '/Users/nastasyaorlova/Desktop/russian-syntagrus-ud-2.5-191206.udpipe'
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))
#облако наиболее частых слов pal <-c("#FFB3BA", "#FFDFBA", "#FFFFBA", "#BAFFBF", "#BAE1FF")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)