Как провести конкурс по науке о данных? (EDA)

машинное обучение глубокое обучение компьютерное зрение NLP

Автор | Кемаль Эрдем Компилировать|ВКонтакте Источник | К науке о данных

Эта статья основана на статье об участии в конкурсе DENGAI (лихорадка денге) на платформе Driventa. Мой рейтинг составляет 0,2% (по состоянию на 14/9069, 2 июня 2020 г.). Некоторые идеи у меня в этом строго рассчитаны на такие соревнования, которые могут не особо пригодиться в реальной жизни.

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

описание проблемы

Во-первых, нам нужно обсудить саму конкуренцию. Целью DengAI является (в настоящее время, потому что Управление Driventa решило сделать его «постоянным» соревнованием, поэтому вы можете присоединиться сейчас) предсказать количество случаев денге за данную неделю на основе данных о погоде и местоположении.

Каждому участнику был предоставлен набор обучающих данных и набор тестовых данных (не набор данных проверки). MAE (средняя абсолютная ошибка) — это показатель, используемый для расчета баллов, а набор обучающих данных охватывает 28 лет еженедельных значений в 2 городах (1456 недель). Тестовые данные меньше, охватывают 5 и 3 года (в зависимости от города).

Лихорадка денге — переносимое комарами заболевание, которое встречается в тропических и субтропических регионах мира. Поскольку его переносят комары, распространение болезни связано с изменениями климата и погоды.

Набор обучающих данных:GitHub.com/ не позволяет вам лайкать oh/'s…

Тестовый набор данных:GitHub.com/ не позволяет вам лайкать oh/'s…

набор данных

Если мы посмотрим на обучающий набор данных, он имеет несколько функций:

индикаторы города и даты:

  • city: sj для Сан-Хуана, iq для Икитоса
  • week_start_date- Дата приведена в формате ГГГГ-ММ-дд

Измерения метеостанции ежедневных климатических данных GHCN NOAA:

  • station_max_temp_c-Максимальная температура
  • station_min_temp_c-самая низкая температура
  • station_avg_temp_c-Средняя температура
  • station_precip_mm-Общее количество осадков
  • station_diur_temp_rng_c- суточный диапазон температур

Спутниковые измерения осадков (шкала 0,25x0,25 градуса):

  • precipitation_amt_mm-Общее количество осадков

Аналитические измерения системы прогнозирования климата NCEP NOAA (шкала 0,5x0,5 градуса):

  • reanalysis_sat_precip_amt_mm-Общее количество осадков
  • reanalysis_dew_point_temp_k- Средняя температура точки росы
  • reanalysis_air_temp_k-Средняя температура
  • reanalysis_relative_humidity_percent- Средняя относительная влажность
  • reanalysis_specific_humidity_g_per_kg- Средняя удельная влажность
  • reanalysis_precip_amt_kg_per_m2-Общее количество осадков
  • reanalysis_max_air_temp_k= максимальная температура воздуха
  • reanalysis_min_air_temp_k- Минимальная температура воздуха
  • reanalysis_avg_temp_k-Средняя температура
  • reanalysis_tdtr_k- Диапазон дневных температур

Нормализованный разностный индекс растительности (NDVI) CDR NOAA (шкала 0,5x0,5 градуса):

  • ndvi_se- NVDI к юго-востоку от центра города
  • ndvi_sw- NVDI к юго-западу от центра города
  • ndvi_ne- NVDI к северо-востоку от центра города
  • ndvi_nw- NVDI к северо-западу от центра города

Кроме того, у нас есть информация об общем количестве случаев за неделю.

Легко обнаружить, что для каждой строки в наборе данных у нас есть несколько функций, описывающих похожие данные. Есть четыре категории:

  • температура

  • осадки

  • влажность

  • ndvi (эти четыре признака относятся к разным точкам города, поэтому это не совсем одни и те же данные)

Следовательно, мы должны иметь возможность удалить некоторые избыточные данные из ввода.

Пример ввода:

week_start_date 1994-05-07
total_cases 22
station_max_temp_c 33.3
station_avg_temp_c 27.7571428571
station_precip_mm 10.5
station_min_temp_c 22.8
station_diur_temp_rng_c 7.7
precipitation_amt_mm 68.0
reanalysis_sat_precip_amt_mm 68.0
reanalysis_dew_point_temp_k 295.235714286
reanalysis_air_temp_k 298.927142857
reanalysis_relative_humidity_percent 80.3528571429
reanalysis_specific_humidity_g_per_kg 16.6214285714
reanalysis_precip_amt_kg_per_m2 14.1
reanalysis_max_air_temp_k 301.1
reanalysis_min_air_temp_k 297.0
reanalysis_avg_temp_k 299.092857143
reanalysis_tdtr_k 2.67142857143
ndvi_location_1 0.1644143
ndvi_location_2 0.0652
ndvi_location_3 0.1321429
ndvi_location_4 0.08175

Формат подачи:

city,year,weekofyear,total_cases
sj,1990,18,4
sj,1990,19,5
...

Рейтинговая оценка:

анализ данных

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

import pandas as pd
pd.set_option("display.precision", 2)

df = pd.read_csv('./dengue_features_train_with_out.csv')
df.describe()

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

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

Вернемся к основному столу. Каждая строка содержит различный тип информации:

  • count- описывает количество не-NaN значений
  • mean- среднее значение всего столбца (для нормализации)
  • std- стандартное отклонение (также может использоваться для стандартизации)
  • min ->max- показать диапазон, содержащий значения (для масштабирования)

Начнем со счета. Важно знать, сколько записей в наборе данных отсутствует (одна или несколько), и решить, что делать с этими данными. Если посмотреть на значение ndvi_nw, то оно пусто в 13,3% случаев. Это может быть проблемой производительности, если вы решите заменить отсутствующее значение произвольным значением, например 0. Как правило, есть два распространенных решения:

  • установить среднее значение

  • интерполяция

Интерполяция (обработка отсутствующих данных)

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

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

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

Если считать с июля, у вас может быть [28, 27, -, -, 30]. В Лондоне среднегодовая температура составляет 11 градусов по Цельсию (или 52 градуса по Фаренгейту). Было бы неправильно использовать 11 в качестве заполнения температуры в этом случае. Вот почему мы должны использовать интерполяцию вместо среднего.

С интерполяцией (даже с большими промежутками) мы должны получить лучшие результаты. Если вы вычислите эти значения, вы должны получить (27+30)/2=28,5 и (28,5+30)/2=29,25, поэтому в итоге наш набор данных будет выглядеть как [28, 27, 28,5, 29,25, 30], намного лучше, чем [28, 27, 11, 11, 30].

Разбить набор данных на города

Поскольку мы обсудили некоторые важные вещи, мы можем определить метод, который позволит нам переопределить категориальный столбец (город) как двоичный вектор-столбец и интерполировать данные:

def extract_data(train_file_path, columns, categorical_columns=CATEGORICAL_COLUMNS, categories_desc=CATEGORIES,
                 interpolate=True):
    # 读取csv文件并返回
    all_data = pd.read_csv(train_file_path, usecols=columns)
    if categorical_columns is not None:
        # 将分类映射到列
        for feature_name in categorical_columns:
            mapping_dict = {categories_desc[feature_name][i]: categories_desc[feature_name][i] for i in
                            range(0, len(categories_desc[feature_name]))}
            all_data[feature_name] = all_data[feature_name].map(mapping_dict)

        # 将映射的分类数据更改为0/1列
        all_data = pd.get_dummies(all_data, prefix='', prefix_sep='')

    # 修复丢失的数据
    if interpolate:
        all_data = all_data.interpolate(method='linear', limit_direction='forward')

    return all_data

Все константы (такие как отправка колонн) определены в этой точке:gist.GitHub.com/Не позволяй себе быть таким, как о/30…

Эта функция возвращает набор данных с двумя двоичными столбцами с именами sj и iq с логическими значениями, где для города задано значение sj или iq.

данные графика

Важно отображать данные, чтобы визуализировать распределение значений в ряду. Мы будем использовать библиотеку под названием Seaborn, чтобы помочь нам построить наши данные.

sns.pairplot(dataset[["precipitation_amt_mm", "reanalysis_sat_precip_amt_mm", "station_precip_mm"]], diag_kind="kde")

Здесь у нас есть только одна особенность набора данных, и мы можем четко различать сезоны и города (средние значения из297 до292).

Еще одна полезная вещь — связь между различными функциями. Таким образом, мы можем удалить некоторые избыточные функции из набора данных.

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

корреляция данных

Когда мы используем много функций, нам не нужно делать попарный график для каждой пары. Другой вариант — рассчитать то, что называется оценкой релевантности. Различные типы данных имеют разные типы зависимостей. Мы используем метод corr() для создания числовых корреляций для набора данных.

Если есть категориальные столбцы, которые не следует считать бинарными, вы можете вычислить меру Cramer V-Association, чтобы найти «корреляции» между ними и другими данными.

import pandas as pd
import seaborn as sns

# 导入我们的提取函数
from helpers import extract_data
from data_info import *

train_data = extract_data(train_file, CSV_COLUMNS)

# 获取“sj”city的数据并删除两个二进制列
sj_train = train_data[train_data['sj'] == 1].drop(['sj', 'iq'], axis=1)

# 生成热图
corr = sj_train.corr()
mask = np.triu(np.ones_like(corr, dtype=np.bool))
plt.figure(figsize=(20, 10))
ax = sns.heatmap(
    corr, 
     mask=mask, 
    vmin=-1, vmax=1, center=0,
    cmap=sns.diverging_palette(20, 220, n=200),
    square=True
)
ax.set_title('Data correlation for city "sj"')
ax.set_xticklabels(
    ax.get_xticklabels(),
    rotation=45,
    horizontalalignment='right'
);

ты сможешьiqГород делает то же самое и сравнивает два (корреляции разные).

Если вы посмотрите на эту тепловую карту, станет ясно, какие функции коррелируют, а какие нет. Вы должны знать, что есть положительные и отрицательные корреляции (темно-синий и темно-красный). Белые объекты без корреляции.

Есть несколько наборов признаков, которые имеют положительную корреляцию и, что неудивительно, относятся к одному и тому же типу меры (например, корреляция между station_min_temp_c и station_avg_temp_c). Но есть также корреляции между различными функциями (например, reanalysis_specific_humidity_g_per_kg и reanalysis_dew_point_temp_k). Мы также должны сосредоточиться на корреляции между total_cases и другими функциями, так как это то, что нам нужно предсказать.

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

sorted_y = corr.sort_values(by='total_cases', axis=0).drop('total_cases')
plt.figure(figsize=(20, 10))
ax = sns.barplot(x=sorted_y.total_cases, y=sorted_y.index, color="b")
ax.set_title('Correlation with total_cases in "sj"')

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

Также важно наблюдать за тем, как целевые значения распределяются в наборе данных. Мы можем легко сделать это с пандами:

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

Что такое значение NDVI?

Последнее, что мы обсудим в этой статье, — это индекс NDVI (Normalized Difference Vegetation Index). Этот индекс является индикатором вегетации. Высокие отрицательные значения соответствуют воде, значения ближе к 0 представляют камни/песок/снег, а значения ближе к 1 тропическому лесу. В заданном наборе данных каждый город имеет 4 разных значения NDVI (каждое значение соответствует разным углам на карте).

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

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

в заключении

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

использованная литература:

DengAI: Predicting Disease Spread woohoo.driven data.org/competition…

Оригинальная ссылка:к data science.com/Deng Ai-how-…

Добро пожаловать на сайт блога Panchuang AI:panchuang.net/

sklearn машинное обучение китайские официальные документы:sklearn123.com/

Добро пожаловать на станцию ​​сводки ресурсов блога Panchuang:docs.panchuang.net/