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

Искусственный интеллект предлагает эффективный и быстрый способ анализа и осмысления огромных объемов сложных данных и даже прогнозирования заболеваемости и распространения заболеваний. Мы видели некоторые успехи в борьбе с пандемией covid-19, например, Понимание голубых точек. И, возможно, предполагаемые недостатки по сравнению с другими попытками отслеживания заболеваемости covid-19 были связаны с непредсказуемой природой самого нового вируса.

А что, если мы попытаемся применить прогнозирование машинного обучения к вирусу, который имеет различимую структуру и регулярно отслеживается? Это было целью моего проекта для Африканской интенсивной программы по науке о данных. Но это не учебник о том, как построить модель прогнозирования. Вы можете ознакомиться с полным кодом в моем github repo/Influenza-Spook. В этом посте я поделюсь неожиданными выводами, которые я получил о тенденциях гриппа из этого проекта, и о том, как наука о данных изменила мой религиозный взгляд на научную истину.

Почему грипп? Ну, помимо легкодоступных и в основном полных данных эпиднадзора (WHO Flunet), грипп считается сезонным заболеванием, на которое влияют сезонные предикторы.

Вы, наверное, знакомы с термином «сезон гриппа». Это научная истина, что в большинстве стран мира, за исключением тропических и субтропических регионов, заболеваемость гриппом имеет сезонный характер. Более холодные месяцы означают увеличение заболеваемости гриппом. На приведенном ниже графике необработанных данных видно, что пики приходятся на одни и те же месяцы.

Необработанные данные, по-видимому, соответствуют предположению о сезонности. Я проверил графики заболеваемости вирусом гриппа А и В, и они в значительной степени следуют аналогичной схеме. Обратите внимание на пик эпидемии гриппа AHINI в 2009 году.

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

#prepare the data: prophet expects your datetime column to be named ds and your time-series y.
df= prophet_df[[‘ds’, ‘y’]]
df.columns = [‘ds’, ‘y’]
df[‘ds’]= to_datetime(df[‘ds’])
# define the model
model = Prophet(yearly_seasonality=True, weekly_seasonality=True, daily_seasonality=False)
# fit the model
model.fit(df)
#Generate the forecast dates
future_data = prophet.make_future_dataframe(periods=14)
#Make the forecast
forecast=prophet.predict(future_data)

Я использовал данные Региона Западной части Тихого океана ВОЗ. Данные довольно просты:

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

from pandas import read_csv
from pandas import to_datetime
from fbprophet import Prophet
#Pre-process categorical data
_=data.pop('TITLE') #remove the column that classifies disease level
one_hot_encoded_data = pd.get_dummies(data)
#Create data for prophet
prophet_df=one_hot_encoded_data.reset_index()
prophet_df.rename(columns = {'EDATE':'ds', 'ALL_INF':'y'}, inplace = True)
#split data at about a 70:30 non-random split.
x_train=prophet_df[:12180]
x_test=prophet_df[12180:]

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

# define the model
model = Prophet(weekly_seasonality=False, )
# fit the model
model.fit(x_train)

Вторая модель учитывала подтип, местонахождение и дату.

#Create list of regressors
regs = ['Year', 'Week', 'SDATE', 'AH1', 'AH1N12009', 'AH3', 'AH5',
       'ANOTSUBTYPED', 'INF_A', 'BYAMAGATA', 'BVICTORIA', 'BNOTDETERMINED','INF_B', 'ALL_INF2']
#Additional Regressors
pro_regressor= Prophet()
for r in regs:
    pro_regressor.add_regressor(r)
    
#Fitting the data
pro_regressor.fit(x_train)

Если вы использовали Prophet раньше, вы, вероятно, знаете о трудностях, возникающих при добавлении дополнительных регрессоров к подобранной модели. Функция make_future_dataframe пророка возвращает только серию дат. Как же тогда получить данные за прогнозный период? Вероятно, вы могли бы построить модели для прогнозирования и этих переменных.

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

#Write function to create pro-regressor future data
def add_regressor_to_future(future_data):
    new=future_data.reindex(columns= ['ds','Year', 'Week', 'SDATE', 'AH1', 'AH1N12009', 'AH3', 'AH5',
       'ANOTSUBTYPED', 'INF_A', 'BYAMAGATA', 'BVICTORIA', 'BNOTDETERMINED',
       'INF_B', 'ALL_INF2'])
    new.Year=future_data.ds.dt.year
    new.Week=future_data.ds.dt.week
    future_data['SDATE']=future_data.ds.dt.to_period('W').dt.start_time
    future_data['SDATE'] = pd.to_datetime(future_data['SDATE'])
    new['SDATE']=future_data.ds
    
    df=data.groupby('Year').median()
    #df.set_index('Year', inplace=True)
    new.set_index('Year', inplace=True)
    new.update(df)
    new = new.fillna(0)
    new=new.reset_index()
    return new
#Create pro-regressor data
future_data =model.make_future_dataframe(periods=14)
future_data = add_regressor_to_future(future_data)

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

Конечно, я ожидал некоторой случайности, ведь грипп — это вариабельный вирус. Я не ожидал найти отсутствие сезонности. Может это данные? Возможный. Или, возможно, как ученые-инфекционисты, мы недостаточно проанализировали болезнь. Может быть, нет такого понятия, как «сезон гриппа». Возможно, изменение температуры не является таким уж важным фактором в заболеваемости гриппом. В любом случае, крайне важно, чтобы мы переоценили то, что мы знаем о динамике передачи определенных заболеваний и их кажущихся сезонных циклах. Но это задача для другой науки.

Так как же выступил Пророк? В данных прогноза нет большой разницы между моделью с одним регрессором и моделью с несколькими регрессорами.

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