Борьба с коронавирусом с помощью науки о данных

Примечание редакции: Towards Data Science - это издание Medium, в основном основанное на изучении науки о данных и машинного обучения. Мы не являемся специалистами в области здравоохранения или эпидемиологами, и мнения, изложенные в этой статье, не следует интерпретировать как профессиональные советы. Чтобы узнать больше о пандемии коронавируса, нажмите здесь.

Фон

COVID-19, болезнь, вызванная вирусом SARS-CoV-2, пережила 2020 год и в течение шести месяцев стала причиной смерти более 130000 человек в Соединенных Штатах. Поскольку объявление о блокировке в большинстве штатов за последние несколько месяцев вынудило многих специалистов по обработке данных закрыться, члены этого сообщества ищут способы внести свой вклад в борьбу с коронавирусом. Несмотря на то, что проводится множество исследований по поиску вакцин против коронавируса путем прогнозирования белковых структур или классификации случаев коронавируса с помощью неинвазивных процедур, таких как компьютерная томография, не было много общедоступных моделей, которые предназначались бы для прямого моделирования роста коронавирус.

Тем не менее, определенно есть приложения для моделей, которые предназначены для непосредственного моделирования роста коронавируса. Хотя эти модели могут использоваться, чтобы помочь городам разработать политику в отношении блокировки и повторного открытия определенных предприятий, они также могут быть чрезвычайно полезны для больниц, помогая им прогнозировать ресурсы, которые им потребуются на следующий день, с учетом конкретных данных. Например, больницы могут спрогнозировать количество коек или врачей, которые им понадобятся на следующий день, на основе местного прогноза случаев коронавируса и предыдущих данных о количестве необходимых коек или врачей.

Постановка задачи

Моей целью было разработать общедоступные модели, которые бы разумно предсказывали рост коронавируса на следующий день. Эту цель можно разбить и формализовать на две части:

  1. Построить модель, которая будет прогнозировать количество случаев коронавируса на следующий день на основе количества случаев коронавируса и смертей за последние n дней.
  2. Построить модель, которая будет прогнозировать количество смертей от коронавируса на следующий день на основе количества случаев и смертей от коронавируса за последние k дней.

Хотя я узнал, что n и k должны быть одинаковыми значениями после тщательного тестирования моих моделей, когда я впервые определил проблему, я предположил, что n и k могут быть разными числами, чтобы не ограничивать возможности улучшения моих индивидуальных моделей.

Наборы данных

Поскольку рост коронавируса был темой, которая интересовала широкую публику, а не только специалистов по данным или нишевых коммерческих секторов, найти данные по этой теме было несложно. Я решил использовать национальные данные по США из Github New York Times в репозитории covid-19-data, поскольку они обновлялись ежедневно и их было очень легко загрузить. Он также не содержал пропущенных значений, поэтому предварительная обработка данных была бы простой. Этот набор данных содержит три столбца с датой, общим количеством случаев коронавируса и общим количеством смертей от коронавируса с 21 января 2020 года.

Репозиторий, содержащий набор данных, который я использовал для этого проекта, можно найти здесь, а точный файл csv, который я использовал из этого репозитория, можно найти здесь.

Предварительная обработка данных

После того, как мы загрузим наши данные, будет хорошей привычкой построить графики для понимания данных. С помощью этого простого процесса мы можем увидеть, имеют ли наши данные сезонность, и дать нам некоторые рекомендации о том, какие модели следует рассматривать для этой проблемы регрессии. Давайте посмотрим на графики национальных случаев коронавируса и смертей с течением времени в днях.

Как видно из приведенных выше графиков, общее количество случаев заболевания коронавирусом и случаев смерти в стране постоянно увеличивается с разной скоростью, что указывает на логичность использования авторегрессивной модели. Поскольку форма обоих графиков указывает на некоторую связь между случаями и смертями, поскольку оба графика имеют схожую форму, было бы рационально использовать как число случаев, так и число смертей в качестве входных данных для прогнозирования числа случаев или числа смертей. смерть на следующий день.

Теперь, когда мы решили, какие входы и выходы мы будем использовать для наших моделей, пришло время создать эти входы и выходы. Давайте посмотрим на сегмент кода, который их создает.

#df is a dataframe that contains a list of dates, cases, and deaths
#inputs are a list of COVID-19 cases
#outputs are a list of COVID-19 deaths
past = 5
s = (len(inputs) , past  * 2)
betterinputs = np.zeros(s)
betteroutputs = np.zeros(len(inputs))
for i in range(len(inputs) - past):
  temp = np.zeros(past * 2)
  temp[0 : past] = inputs[i : i+ past]
  temp[past:] = outputs[i : i + past]
  betterinputs[i] = temp
  betteroutputs[i] = inputs[i+past] #when predicting cases
  #use betteroutputs[i] = outputs[i+past] when predicting deaths
betterinputs = betterinputs[0:len(df) - past]
betteroutputs = betteroutputs[0:len(df) - past]

После того, как мы создали наши входные и выходные массивы, важно разделить наши данные на наборы для обучения и тестирования. Это разделение позволяет нам проверить, насколько хороша наша модель и насколько хорошо она обобщает. Давайте посмотрим на код, который создает это разделение на обучение и тестирование ниже.

split = int(0.8*len(betterinputs))
X_train, X_test, y_train, y_test = betterinputs[:split], betterinputs[split:], betteroutputs[:split], betteroutputs[split:]
X_train = np.expand_dims(X_train, axis=2)
X_test = np.expand_dims(X_test, axis=2)

Модели

Контрольный показатель

Теперь, когда у нас есть входные и выходные данные, которые готовы к использованию в модели машинного обучения, пришло время разработать эталонную модель в качестве проверки работоспособности, чтобы убедиться, что мы не слишком усложняем вещи. Контрольная модель, которую я использовал, заключалась в том, чтобы вывести сегодняшнее количество случаев или смертей в качестве прогнозируемых значений завтрашнего числа случаев или смертей. Это подходящая эталонная модель для этой задачи, поскольку, хотя общее количество смертей и случаев заболевания коронавирусом в стране велико, изменение количества смертей и случаев заболевания коронавирусом в стране относительно невелико. Давайте посмотрим, как создать нашу эталонную модель количества смертей от коронавируса в стране и результатов, и визуализировать ее точность.

benchmark = []
for i in range(1, len(betteroutputs)):
  benchmark.append(betteroutputs[i])
sum = 0
for i in range(len(betteroutputs) - 1):
  sum += abs(float(betteroutputs[i]) - float(benchmark[i]))
print(sum / float(len(benchmark)))
from matplotlib import pyplot as plt
plt.semilogy(benchmark, label = "benchmark")
plt.semilogy(betteroutputs , label = "betteroutputs")
plt.semilogx(inputs, label = "cases")
plt.title('model accuracy')
plt.ylabel('deaths')
plt.xlabel('cases')
plt.legend()

Как видно из изображения выше, среднее количество смертей, прогнозируемое нашей простой эталонной моделью, очень близко к реальному значению по шкале общего числа случаев. Среднее значение 804,5 случаев смерти по шкале из более чем 100 000 общих смертей указывает на ошибку менее 0,8%, что обычно считается неплохим. Та же эталонная модель для национального числа случаев коронавируса в среднем составляет около 40000 случаев, что указывает на ошибку менее 2%. Хотя должен быть способ разработки моделей, которые лучше имитируют рост COVID-19, эти эталонные модели можно использовать для устранения других сложных и сложных архитектур с большим количеством параметров.

Риджская регрессия

Хотя я попытался создать несколько MLP с использованием последовательной модели Tensorflow с функциями регуляризации и активации ядра по умолчанию «relu» для имитации количества смертей и случаев коронавируса в стране, мои модели в большинстве случаев работали хуже, чем эталонный тест. По мере того как я уменьшал слои своего MLP и, в конечном итоге, дошел до одного плотного слоя, моя модель все еще работала хуже, чем эталон. Именно в этот момент я понял, что регуляризация L2 может быть чрезвычайно полезной, и переключил свою архитектуру модели на регрессию гребня. Регуляризация L2, также известная как Ridge Penalization, заставляет параметры в моделях машинного обучения быть небольшими, поскольку потери возрастают по мере увеличения параметров, и эта регуляризация часто используется для уменьшения вероятности переобучения модели. После того, как я изменил свою модель, чтобы включить эту регуляризацию, моя модель показала себя намного лучше, чем эталонная модель, особенно в прогнозировании случаев. Давайте посмотрим код для обучения обеих моих моделей.

from sklearn.linear_model import RidgeCV
model = RidgeCV(cv=2)
model.fit(X_train, y_train)

Теперь, когда мои модели подходят для данных обучения, пришло время спрогнозировать количество случаев коронавируса и смертей в стране для данных тестирования. Я решил измерить погрешность своих моделей, вычислив среднее количество случаев коронавируса и смертей, не соответствующих моим моделям. Вот сегмент кода, который прогнозирует национальные случаи коронавируса и смертельные случаи для данных тестирования, вычисляет ошибку на основе метрики, описанной выше, и сопоставляет прогнозируемые значения с реальными значениями.

predict = model.predict(X_test)
print("{}".format(np.linalg.norm(predict - y_test, 1)/len(y_test)))
plt.title("Model Accuracy")
plt.plot( days, predict, label = "predicitons")
plt.plot( days, y_test,  label = "real values")
plt.xlabel("Days after First United States Coronavirus Case")
plt.ylabel("National Cases of Coronavirus")
plt.legend()

Как видно из выходных данных приведенного выше сегмента кода, прогнозы модели для случаев в среднем отклоняются от реального значения только на 2869, что указывает на ошибку менее 0,2 процента, что в десять раз точнее, чем наш тест для случаев и в целом считается очень хорошим. Та же самая модель дает среднюю ошибку 489 смертей от реального значения, что составляет примерно 0,4% ошибки, что почти в два раза точнее, чем наш эталон для смертей.

Прогнозы на будущее

Теперь, когда мы спрогнозировали смерти и случаи коронавируса с использованием входных данных, которые модель не видела раньше, и знаем, что у этой модели может быть потенциал, основанный на ошибке ее прогнозов на данных тестирования, наконец, пришло время создать прогнозы для будущих данных. Давайте посмотрим на код для создания входных данных и прогнозов национальных случаев коронавируса или смертей на завтра. Я также включил вывод даты, чтобы указать, когда я предсказал свои результаты.

from datetime import date
size = (2 , past  * 2)
finalInput = np.zeros(size)
temp = np.zeros(past * 2)
temp[:past] = inputs[-past:]
temp[past:] = outputs[-past:]
finalInput[0] = temp
finalInput[1] = temp
futurePrediction = model.predict(finalInput)
futurePrediction = futurePrediction[0]
print("Prediction for tomorrow's national coronavirus deaths : " + str(int(futurePrediction)))
print("Today's date : " + str(date.today()))

Надеюсь, моя модель хорошо предсказывает завтра!

Примечание. Моя модель позволяет прогнозировать количество случаев коронавируса и случаев смерти в стране более чем на один день вперед (путем изменения меток ввода или использования прогноза смертей и случаев заболевания на следующий день как входные данные для модели на следующий день после смерти или случаев заболевания коронавирусом в стране), моя модель была предназначена для прогнозирования только на один день вперед и работает лучше всего в этом случае.

Недостатки модели и дальнейшие шаги

Хотя моя модель в настоящее время достаточно хорошо предсказывает количество случаев коронавируса и смертей на следующий день, как видно из ее точности тестирования, в моей модели есть некоторые недостатки. Во-первых, моя модель имеет линейные коэффициенты, поэтому естественно, что моя модель очень хорошо предсказывает текущие линейные данные. Однако, если количество случаев коронавируса в стране и количество смертей не будут продолжать демонстрировать линейную зависимость, моя модель может быть не такой точной, и именно в этот момент такая модель, как моя, нужна больше всего. Однако, хотя я не уверен, как можно значительно улучшить эту модель, используя ту же архитектуру, я считаю, что есть несколько других подходов, которые я могу попробовать улучшить свою модель:

  1. Я хотел бы проверить, будет ли MLP с регуляризацией ядра L2 работать лучше, чем моя модель регрессии Ridge; эта модель также сможет прогнозировать нелинейные отношения между случаями коронавируса и смертями.
  2. Я хотел бы разработать модель с использованием трансферного обучения для другой пандемии и сравнить ее с моей Ридж-регрессией; это также решило бы проблему моей текущей модели, заключающуюся в наличии только линейных коэффициентов. Эта модель также должна быть намного более точной при прогнозировании смертей и случаев заболевания на несколько дней вперед, а также может использоваться для моделирования снижения числа случаев коронавируса и смертей в целом.

Пока я пытаюсь разработать эти модели, чтобы сравнить их с моей исходной, я надеюсь, что моя существующая модель может быть использована в качестве 24-часового инструмента планирования для местных систем здравоохранения и лиц, принимающих решения. Хотя я создал свою текущую модель с использованием национальных данных, я считаю, что ее можно легко настроить с использованием данных округа или штата для удовлетворения конкретных потребностей учреждения.

Наконец-то…

Спасибо, что дочитали блог до конца! Я хотел бы услышать какие-либо комментарии о моем анализе или моем проекте. Вы можете найти и скачать полную записную книжку для моего проекта на моем гитхабе.

Не стесняйтесь оставить сообщение ниже или написать мне по электронной почте anaiysomalwar в gmail dot com.