Сохрани и опубликуйсвоё исследование
О проекте | Cоглашение | Партнёры
В работе исследовался способ прогнозирования числа заражений коронавирусом при помощи нейросети.
Комментировать 0
Рецензировать 0
Скачать - 1,0 МБ
Enter the password to open this PDF file:
-
Министерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования «Петрозаводский государственный университет» Институт математики и информационных технологий Кафедра теории вероятностей и анализа данных (подпись соискателя) Быков Федор Юрьевич Выпускная квалификационная работа бакалавра Прогнозирование количества зараженных коронавирусом по Викиданным с использованием нейросети Направление 01.03.02 Прикладная математика и информатика Научный руководитель: к.т.н, А. А. Крижановский (подпись руководителя) Петрозаводск — 2021
СОДЕРЖАНИЕ ВВЕДЕНИЕ ………………...……………...………………………………………. 3 Глава 1. Заполнение данных по числу заражений коронавирусом в регионах ....5 𝑡 Глава 2. Построение алгоритма вычисления 𝑐𝑎𝑠𝑒𝑠𝑟 𝑇+1 при прочих известных 𝑧 данных. ……………………………………………………………..……….……..6 2.1 Выбор инструмента прогнозирования …………………....…….……...6 2.2 Подготовка и нормализация данных для анализа……………..………. 7 2.3 Испытание и корректировка работы нейронной сети ……………..….8 Глава 3. Оценка точности предсказания по известным данным .………...…….12 Глава 4. Предсказание числа заражений при помощи окна фиксированного размера. ……………………………………………………………………...…….14 4.1 Построение алгоритма вычисления числа заражений окном фиксированного размера …………………………………………...…….……...14 4.2 Поиск оптимального размера окна для предсказания значения на End+1 день …………………....……………………………………………......….……...16 ЗАКЛЮЧЕНИЕ……………………………...….………………...…….…………18 Литература…………….……………………………………………….………… 20 ПРИЛОЖЕНИЕ ………….……………………………………………....………. 21
Введение В 2020 году человечество столкнулось с серьезнейшими вызовами из-за пандемии нового коронавируса COVID-19. Многие страны не справляются с оказанием медицинской помощи заболевшим [1]. Пандемия приносит многочисленные жертвы, на 1 января 2021 года в мире скончалось порядка 1.82 млн человек [2]. Интерес специалистов в различных областях, как и широкой публики, вызывает вопрос: как долго и насколько тяжело будет поражено человечество коронавирусной инфекцией. Для прогнозирования ситуации с распространением COVID-19 в этой работе были использованы математические инструменты и нейронные сети. Цель работы заключается в том, чтобы, зная посуточное количество заражений по регионам и используя информацию с сайта Викиданных, спрогнозировать количество зараженных коронавирусом на сутки вперед. 𝑡 Известно посуточное число заражений коронавирусом 𝑐𝑎𝑠𝑒𝑠𝑟 𝑗 для 𝑖 нескольких (n = 85) [3] субъектов (регионов) Российской Федерации 𝑟 1,... , 𝑟 𝑛 за временной интервал 𝑡 1,... , 𝑡 (T дней). 𝑇 Обозначим посуточное число заражений суммарно по всей России R1, …, 𝑛 RT. Число заражений за j-й день равно 𝑅 𝑡 = ∑ 𝑐𝑎𝑠𝑒𝑠𝑟 𝑗 𝑖=1 𝑗 𝑖 Задача заключается в том, чтобы: 1. Построить алгоритм вычисления𝑅 при прочих известных данных, 𝑇+1 то есть предсказать/экстраполировать число заражений по России на завтра, если T — это сегодняшний день; 2
𝑡 2. Построить алгоритм вычисления 𝑐𝑎𝑠𝑒𝑠𝑟 при прочих известных 𝑇+1 𝑧 данных, то есть предсказать/экстраполировать число заражений для региона (z) на завтра; 3. Оценить точность предсказания (погрешность ошибки) по известным данным. Викиданные (англ. Wikidata) — совместно редактируемая база знаний, созданная Фондом Викимедиа и запущенная в октябре 2012 года. Используется для обеспечения централизованного хранения данных, которые могут содержаться в статьях Википедии. Для хранения структурированных данных используется следующая модель данных. Данные состоят из утверждений, которые описываются парами «ключ-значение». Утверждения хранят соответствие свойства с одним или несколькими значениями. Значения могут быть разных типов, включая другие записи Викиданных, строки, числа или файлы с фото/видео. Для уточнения значения утверждения могут использоваться дополнительную квалификаторы информацию (англ. в qualifiers). контексте Они данного предоставляют утверждения. Квалификаторы состоят также из пар «ключ-значение». Пример утверждения со свойствами и квалификаторами показан на Рис. 1. 3
Рис. 1 Утверждение в Викиданных о числе людей, заражённых вирусом на 6 и 9 марта 2020 года одного из субъектов РФ Глава 1. Заполнение данных по числу заражений коронавирусом в регионах Чтобы спрогнозировать количество зараженных коронавирусом на сутки вперед, были предварительно решены следующие задачи: 1. Заполнение в Викиданных у объектов “распространение COVID-19” для восьми регионов: Санкт-Петербург, Республика Карелия, Краснодарский край, Тверская область, Ленинградская область, Москва, Московская область и Республика Удмуртия — значений свойства «число случаев». Данные брались с сайта Яндекса [4]. Для быстрой загрузки инструмент больших автоматизации объёмов данных, использовался редактирования Викиданных QuickStatements1. 2. Построение SPARQL-скрипта (см. Приложение А), который выводит дату и число заражений для выбранного региона в табличном виде. 1 См. https://www.wikidata.org/wiki/Help:QuickStatements 4
𝑡 Глава 2. Построение алгоритма вычисления 𝑐𝑎𝑠𝑒𝑠𝑟 𝑇+1 𝑧 при прочих известных данных. 2.1 Выбор инструмента прогнозирования. В качестве инструмента был выбран PyTorch [5]. Это фреймворк машинного обучения для языка Python с открытым исходным кодом, созданный на базе библиотеки Torch для языка программирования Lua. Был рассмотрен и изучен пример "Time Sequence Prediction2", в котором сеть тренируется на некоторых синусоидальных сигналах, а затем компьютерная программа, написанная на основе библиотеки Torch, пытается предсказать значения сигнала в будущем. Начальный сигнал и прогнозируемые результаты показаны на рис. 2. Сначала подаётся несколько начальных сигналов (сплошная линия на рис. 2) на вход нейросети. После вычислений сеть генерирует предсказания (пунктирная линия на рис. 2). То есть сеть генерирует новые синусоидальные волны. Рис. 2 Пример работы нейросети предсказания будущих значений синусоидального сигнала на основе PyTorch 2 См. https://github.com/pytorch/examples/tree/master/time_sequence_prediction 5
2.2 Подготовка и нормализация данных для анализа Для того чтобы нейросеть могла работать с данными по числу заражений коронавирусной инфекцией, нужно подготовить данные в формате, пригодном для загрузки в библиотеку PyTorch. Для этого сначала число заражений по выбранному региону (z) были загружены из Викиданных в формате CSV файла при помощи ранее построенного SPARQL запроса (см. Приложение A). Потом с помощью скрипта (cм. Листинг 1.). Выгруженные данные были прочитаны и нормализованы, то есть приведены к интервалу [0, 1] путем деления 𝑡 𝑡 каждого значения 𝑐𝑎𝑠𝑒𝑠𝑟 𝑗 где 𝑗 ∈ 1,..., 𝑇 на значение 𝑐𝑎𝑠𝑒𝑠𝑟 𝑇, так как оно 𝑧 𝑧 максимальное (число инфицированных не убывает). После нормализации данные были сохранены в файл «traindata.pt» для дальнейшего чтения нейросетью. Для того чтобы потом показать данные в 𝑡 удобном виде, значение 𝑐𝑎𝑠𝑒𝑠𝑟 𝑇было сохранено в отдельный файл 𝑧 «traindatamn.pt». import numpy as np import torch import matplotlib.pyplot as plt import csv cas = [] # число заражений для обучения cas1 = [] # число заражений, по которым будет предсказывать i = 1 with open('datapy2.csv') as File: for row in csv.reader(File, delimiter=';'): cas.append(row[0]) cas1.append(row[1]) i += 1 data = np.empty((2, i-1), 'int64') data[0] = cas data[1] = cas1 data = data.astype('float64') torch.save(data[0, -1], open('traindatamn.pt', 'wb')) #сохраняем множитель масштаба(последнее значение) 6
data[0] /= data[0,-1] #нормализуем данные data[1] /= data[1,-1] fig = plt.figure() #просмотр обработанных данных ax = fig.add_subplot(111) ax.plot(data.T) plt.show() plt.savefig('predict.pdf') print(data.T) torch.save(data, open('traindata.pt', 'wb')) # сохраняем данные в файл Листинг 1. Чтение данных из CSV-файла, нормализация их и сохранение в файлы traindata.pt и traindatamn.pt 2.3 Испытание и корректировка работы нейронной сети Создаём нейронную сеть, состоящую из трёх слоёв (Листинг 2): входной слой lstm1, скрытый слой lstm2 и выходной слой linear. Далее в цикле каждое значение тензора input последовательно проходит через все три слоя нейронной сети. Для предсказания будущих значений в аналогичный цикл поступает последнее значение на выходе из предыдущего цикла. from __future__ import print_function import torch import torch.nn as nn import torch.optim as optim import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt ns = 200 # количество нейронов class Sequence(nn.Module): # создать нейронную сеть def __init__(self): super(Sequence, self).__init__() self.lstm1 = nn.LSTMCell(1, ns) # создаем слои self.lstm2 = nn.LSTMCell(ns, ns) self.linear = nn.Linear(ns, 1) def forward(self, input, future = 0): # принципы, по которым данные будут перемещаться outputs = [] h_t = torch.zeros(input.size(0), ns, dtype=torch.double) # создаем тензоры c_t = torch.zeros(input.size(0), ns, dtype=torch.double) h_t2 = torch.zeros(input.size(0), ns, dtype=torch.double) c_t2 = torch.zeros(input.size(0), ns, dtype=torch.double) for input_t in input.split(1, dim=1): # перебираем значения тензора input по одному 7
h_t, c_t = self.lstm1(input_t, (h_t, c_t)) # значения последовательно проходят h_t2, c_t2 = self.lstm2(h_t, (h_t2, c_t2)) # через слои output = self.linear(h_t2) outputs += [output] for i in range(future): # если нужно предсказывать будущее h_t, c_t = self.lstm1(output, (h_t, c_t)) h_t2, c_t2 = self.lstm2(h_t, (h_t2, c_t2)) # то же самое, только на вход значения # поступают из предыдущего output = self.linear(h_t2) outputs += [output] outputs = torch.cat(outputs, dim=1) return outputs Листинг. 2 Создание нейронной сети и принципов движения данных внутри неё (фрагмент кода) Загружаем данные в нейронную сеть из заранее подготовленного файла traindata.pt (Листинг 3). В переменную input помещается число заражений за 1, …, T-1 дни. В target помещается число заражений за 2, …, T дни. Значения из input должны стать значениями из target. На этом будет обучаться наша нейросеть. В test_input и test_target помещаются значения, по которым нейронная сеть будет предсказывать новые значения. В качестве метода подсчета функции потерь используется MSELoss3, который считает среднеквадратичную ошибку модели. Затем устанавливается метод оптимизации LBFGS4 и коэффициент скорости обучения «lr». В ходе обучения сеть проходит через несколько эпох. Эпохой называют момент, когда обучающий набор данных полностью проходит через нейронную сеть один раз [6]. Каждую эпоху входные данные проходят через нейронную сеть и на выходе подаются в функцию потерь, где считается разница между истинным и спрогнозированным значением и применяется обратное распространение ошибки [3]. В конце каждой эпохи выводится результат в виде графика. if __name__ == '__main__': np.random.seed(0) 3 4 # set random seed to 0 См. https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html См. https://en.wikipedia.org/wiki/Limited-memory_BFGS 8
torch.manual_seed(0) data = torch.load('traindata.pt') # load data and make training set input = torch.from_numpy(data[:1, :-1]) # обучающая выборка target = torch.from_numpy(data[:1, 1:]) # цель для обучающей выборки test_input = torch.from_numpy(data[1:, :-1]) # тестовая выборка, по которой нейросеть test_target = torch.from_numpy(data[1:, 1:]) # будет предсказывать значения ma = int(torch.load('traindatamn.pt')) # множитель масштаба print(ma) seq = Sequence() # build the model seq.double() criterion = nn.MSELoss() # задаём оптимизатор и параметры # use LBFGS as optimizer since we can load the whole data to train optimizer = optim.LBFGS(seq.parameters(), lr=0.25) for i in range(30): # начинаем обучать и задаём число эпох print('STEP: ', i) def closure(): optimizer.zero_grad() out = seq(input) loss = criterion(out, target) # считаем ошибку print('loss:', loss.item()) loss.backward() # Обратное распространение ошибки return loss optimizer.step(closure) # начинайте прогнозировать, здесь нет необходимости отслеживать градиент with torch.no_grad(): future = 20 # на сколько шагов предсказать значение pred = seq(test_input, future=future) loss = criterion(pred[:, :-future], test_target) print('test loss:', loss.item()) y = pred.detach().numpy() Листинг 3. Загрузка данных, обучение сети и прогнозирование. На графике (рис. 3) черной линией указаны актуальные значения, красной линией — спрогнозированные значения на известный период, красной пунктирной линией показаны спрогнозированные значения на будущее. Для построения графика были использованы данные по числу заражений в Республике Удмуртия актуальные на 11 мая 2020 года. 9
Рис. 3. График значений числа заражений, предсказанных на 15 эпохе. По оси Y расположено число заражений, по оси X — дни, начиная с нулевого дня (первый случай заражения). Изменяя гиперпараметр «коэффициент скорости обучения» и количество нейронов, можно влиять на скорость обучения сети и точность предсказаний. Гиперпараметр [7] модели — это конфигурация внешняя по отношению к модели, значение которой невозможно оценить по данным. На рис. 4 показан результат работы нейронной сети со 100 нейронами в скрытом слое и с коэффициентом скорости обучения равным 0,2. Для обучения и предсказания были использованы данные по количеству заражений в Республике Удмуртия на 17 апреля 2021 года. 10
Рис 4. График значений числа заражений предсказанных на 15 эпохе по данным актуальным на 17.04.2021. Глава 3. Оценка точности предсказания по известным данным Для оценки точности предсказания числа заражений был использован следующий метод. На вход нейросети были поданы данные по числу заражений за интервал времени 1...W, где 1 < 𝑊 < 𝑇, и предсказано значение W+1, затем была вычислена разность реального числа заражений на W+1 день и предсказанного числа заражений на W+1 день. Тем самым была получена величина ошибки предсказания. Затем в цикле менялось значение W с шагом 5, начиная c W = 31 и вычислялась ошибка. В процессе вычисления ошибки попадались и отсеивались выбросы. За выброс была принята ошибка больше чем 2 раза от 11
реального числа заражений. По полученным значениям ошибки был построен график (Рис. 5). В ходе всех вычислений было установлено количество нейронов в скрытом слое равное 100 и коэффициент скорости обучения равный 0,2. Количество эпох было установлено равное 17. Рис 5. График ошибки предсказания числа заражений на W+1 день. Для построения использовались данные актуальные на 17.04.2021. На рис. 5 показана зависимость величины ошибки предсказания от количества дней, по данным за которые обучалась нейросеть. Средняя абсолютная ошибка составила 27 человек. На графике наблюдаются сильные отклонения после 300 дня. Анализ логов работы нейронной сети показал некорректную работу на этих данных. Нейросеть прекращала обучаться не пройдя половины эпох. Это может быть вызвано плохо подобранными гиперпараметрами, а также резкой сменой тенденции роста числа заражений. Значения ошибки больше 100 по модулю были отброшены. Отбросив результаты ошибки, полученные во время некорректной работы сети, была пересчитана средняя абсолютная ошибка и она составила 16 человек. 12
Глава 4. Предсказание числа заражений при помощи окна фиксированного размера 4.1 Построение алгоритма вычисления числа заражений окном фиксированного размера Окном назовём диапазон дней с известным числом заражений, подаваемый на вход нейронной сети. В предыдущих исследованиях размер окна возрастал от W=31 до W=T. Сделаем окно фиксированного размера L=30, то есть нам известны данные за 30 предыдущих дней, и будем сдвигать его в цикле по одному дню с начала интервала до T-L. (Start; End) — это диапазон значений с известным числом заражений. Нейронная сеть должна подсчитывать число заражений на End + 1 день. Написанный цикл показан на листинге 4. Иногда во время работы нейронной сети на выходе получаются некорректные данные, которые на порядки отличаются от реальных значений. Анализ логов работы нейронной сети показал, что в таких случаях наблюдается резкий рост функции потерь. Для решения данной проблемы был написан алгоритм, который отслеживал превышение значения функции потерь определённого порогового значения, в нашем случае равного 10, и перезапускал нейронную сеть с другим зерном5 для начального распределения весов. for J in range(0, count-L, 1): Start = J # начальное J, по T-L, шаг # начальное значение окна End = Start + L # конечное значение окна value_calculated = 0.1 seed = 0 while value_calculated == 0.1: # если будет плохая сходимость, будем перезапускать нейронную сеть с другим зерном пока не будет нормальной сходимости 5 См. https://en.wikipedia.org/wiki/Random_seed 13
value_calculated = neural_net(data[:, Start:End]/data[0, End-1], real_data[0, End-1], J, real_data[0, End], seed) # data- окно размером L, последний End элемент для множителя, номер для графика, будущее значения для графика, зерно seed += 1 print("value_calculated: ", value_calculated) error.append(real_data[0, End] - value_calculated) val_cal.append(value_calculated) r_d.append(real_data[0, End]) # запоминаем значение ошибки # запоминаем предсказанное значение # запоминаем реальное значение print("error: ", error) Листинг 4. Цикл, в котором окном фиксированного размера L рассчитывается значение на End + 1 день. Затем окно смещается на 1 день. В цикле на вход нейронной сети подаются значения из окна. На каждой итерации подсчитывалось значение числа заражений на End + 1 день и сравнивалось с реальным значением на End + 1 день. По полученным значениям был построен график, показанный на рисунке 6. Для расчётов были использованы следующие параметры: Количество нейронов = 51, скорость сходимости = 0.2, количество эпох = 15. Также была подсчитана средняя абсолютная ошибка, величина которой составила 20 человек. Рис 6. График ошибки предсказания числа заражений на End + 1 день при размере окна 30 дней 14
4.2 Поиск оптимального размера окна для предсказания значения на End+1 день Создадим внешний цикл, который будет перебирать размер окна от 10 до 200 с шагом 10. Для каждого размера окна будем подсчитывать среднюю абсолютную ошибку и построим график зависимости ошибки от размера окна (Рис. 7). Рис 7. График зависимости средней абсолютной ошибки от размера окна. Также посчитаем среднюю абсолютную процентную ошибку чтобы перейти к относительной оценке. Считать будем относительно числа новых зараженных на прогнозируемый день. Построим график зависимости средней абсолютной процентной ошибки от размера окна (См. Рис. 8). 15
Рис 8. График зависимости средней абсолютной процентной ошибки от размера окна. Подсчитанный относительно числа новых зараженных. Исходя из графиков, наименьшая ошибка получилась при размере окна в 20 дней. Следовательно, оптимальный размер окна составил 20 дней (См. Рис. 9). Исходный код программы был загружен на GitHub [8]. Рис 9. График ошибки предсказания числа заражений на End + 1 день при размере окна 20 дней. 16
Заключение В ходе работы были загружены в Викиданные значения по числу заражений коронавирусом для нескольких субъектов (регионов) Российской Федерации. Был изучен пример нейронной сети "Time Sequence Prediction", написанный на Pytorch, и на его основе была создана нейронная сеть, способная предсказывать количество заражений. С помощью SPARQL-запросов были получены данные по числу заражений для выбранного региона из Викиданных. По полученным данным было предсказано число заражений на завтрашний день с использованием нейросети. Для оценки точности работы нейронной сети были сделаны предсказания по уже известным данным и вычислена ошибка предсказания. Результаты были представлены в виде графиков. После исключения некорректных данных была подсчитана средняя абсолютная ошибка, которая составила 16 человек. Для повышения точности работы нейросети было решено использовать окно фиксированного размера. При предсказании числа заражений были использованы размеры окна от 10 до 200 дней. При сравнении результатов, полученных при разных размерах окон, наилучший результат был получен при размере окна в 20 дней. Средняя абсолютная ошибка составила 13 человек. Средняя абсолютная процентная ошибка относительно числа новых зараженных составила 22%. Однако в начале выборки имеется большая процентная ошибка, это можно объяснить малым числом заражений в начале выборки. Также можно заметить, что для размера окна от 60 до 140 средние абсолютные процентные ошибки близки к ошибке для окна размером 20, но для больших размеров окна не принимаются во 17
внимание ошибки для начала выборки, когда число новых заражений мало. Это лучше, чем в предыдущем исследовании. Повышение точности можно объяснить тем, что с увеличением объема выборки накапливается погрешность самих данных. Также оказывают влияние на точность резкие смены тенденций заболеваемости, которые зависят от различных событий, произошедших в разные моменты времени. Таким образом, способ предсказания числа заражений при помощи нейросети показал неплохие результаты. Следовательно, нейросети могут помочь человечеству в прогнозировании развития пандемии коронавируса и борьбе с ней. 18
Литература [1] Глава ООН: Мир столкнулся с самым серьезным кризисом в здравоохранении // EADaily, 20.03.2020 [Электронный ресурс]. URL: https://eadaily.com/ru/news/2020/03/20/glava-oon-mir-stolknulsya-s-samym-sere znym-krizisom-v-zdravoohranenii. (дата обращения: 01.04.2021) [2] Коронавирус МИР за 1 января 2021 года // Coronavirusstat.ru [Электронный ресурс]. URL: https://coronavirusstat.ru/country/world/1527606/ (дата обращения: 01.04.2021) [3] Конституция Российской Федерации, Глава 3, статья 65 [Электронный ресурс]. URL: http://kremlin.ru/acts/constitution (01.04.2021) [4] Карта распространения коронавируса в России и мире // Yandex.ru [Электронный ресурс]. URL: https://yandex.ru/maps/covid19https://yandex.ru/maps/covid19 (дата обращения: 12.04.2020) [5] Макмахан Б., Рао Д. Знакомство с PyTorch: глубокое обучение при обработке естественного языка . Санкт-Петербург: Изд-во Питер, 2020. — 256 с. — ISBN 978-5-4461-1241-8. [6] Милютин И. Эпоха, батч, итерация — в чем различия? // Neurohive, 27.12.2018 [Электронный ресурс]. URL: https://neurohive.io/ru/osnovy-data-science/jepoha-razmer-batcha-iteracija/ (дата обращения: 15.04.2021) [7] Jason B., В чем разница между параметром и гиперпараметром? // www.machinelearningmastery.ru, 26.07.2017 [Электронный ресурс]. URL: https://www.machinelearningmastery.ru/difference-between-a-parameter-and-a-h yperparameter/ (дата обращения: 15.04.2021) [8] Быков Ф. GitHub [Электронный ресурс]. URL: https://github.com/saimur420/Time-Sequence-Prediction (25.05.2021) 19
ПРИЛОЖЕНИЕ Приложение А # For each day the number of cases (?casestmt) in Udmurt Republic (?state = Q5422) SELECT ?time ?cases { ?statecases wdt:P276 wd:Q5422; p:P1603 ?casestmt. ?casestmt ps:P1603 ?cases ; pq:P585 ?time. SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],ru". } } 20
Отзывы:
Авторизуйтесь, чтобы оставить отзыв