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

Автомобильные аварии - огромная проблема в нашем мире. Около 1,3 миллиона человек ежегодно умирают во всем мире в результате автомобильных аварий и, кроме того, до 50 миллионов человек получают травмы (ASIRT). Может ли машинное обучение помочь спасти жизни? Я считаю, что да, и в этой статье подробно описан один из возможных подходов.

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

(Отказ от ответственности: я использую несколько другой набор данных о происшествиях, датируемый 2010 годом, но недоступный в Интернете)

Наш подход

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

В качестве положительных примеров мы можем использовать семь лет и около полумиллиона записей о дорожно-транспортных происшествиях. Тогда вы можете спросить: у вас есть положительные ярлыки, а где же ваши отрицательные ярлыки? Отличный вопрос! Возможным отрицательным примером является каждая отдельная комбинация отрезка дороги / часа. За 7 лет и 400 000 отдельных участков дороги это составляет примерно 24,5 МИЛЛИАРДА потенциальных отрицательных примеров.

Практики машинного обучения заметят здесь проблему, а именно несбалансированность классов. СИЛЬНЫЙ классовый дисбаланс. По сути, если бы мы использовали все эти данные для обучения модели, наша модель была бы сильно смещена в сторону отсутствия аварий. Это проблема, если мы хотим оценить риск аварии.

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

Исследование данных

Как выглядят почти полмиллиона несчастных случаев?

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

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

Входы?

Теперь, когда мы знаем, что хотим предсказать, каковы исходные данные? Что могло стать причиной автомобильной аварии. Ответ, конечно же, - это множество факторов, некоторые из которых мы включаем в этот анализ.

  • Погода (температура, скорость ветра, видимость, дождь / снег / лед, высота снега, глубина дождя и т. Д.)
  • Временные характеристики: час дня, день недели, месяц года, азимут / высота Солнца.
  • Статические характеристики, такие как ограничение скорости, кривизна дороги, средняя интенсивность движения, близость к перекресткам, выравнивание дороги север / юг / восток / запад, ширина дороги, тип дорожного покрытия и т. Д.
  • Человеческий фактор, например плотность населения, и отвлекающие факторы, например рекламные щиты.
  • Графические особенности дорожной сети, такие как центральность и поток
  • Бесчисленное множество других

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

(Отказ от ответственности: я сотрудник Esri, но у меня был опыт работы в географии с открытым исходным кодом. Вы определенно можете выполнить большую часть этого анализа без использования ArcGIS, но это будет сложнее. Если вы не пользователь ArcGIS, я все же настоятельно рекомендую взглянуть на ArcGIS API for Python, хотя бы из-за возможностей обработки данных, поскольку большая часть этих данных доступна из различных сервисов на основе ArcGIS. Разработчики этого API позаботились о резервном для многих утилит с открытым исходным кодом, таких как shapely, когда ArcGIS недоступен. Пространственная база данных, такая как PostgreSQL с PostGIS, будет иметь большое значение.)

На самом деле есть две отдельные части входных данных: статические функции и динамические функции.

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

Динамические характеристики меняются в зависимости от того, когда мы делаем прогноз. Это данные о погоде, геометрия Солнца и переменные времени (час, месяц, день и т. Д.).

Нам нужно вычислить все эти характеристики для каждого сегмента дороги, которых у нас около 400 000. Мы написали этот процесс с помощью библиотеки Python Arcpy, входящей в состав ArcGIS Pro. Давайте быстро взглянем на пример:

billboards_url = 'https://maps.udot.utah.gov/arcgis/rest/services/FI_Mandli2012/MapServer/2'
# Calc proximity to billboard
_ = arcpy.analysis.Near('centerlines_merged',
                        billboards_url)
_ = arcpy.management.CalculateField('centerlines_merged','proximity_to_billboard','!NEAR_DIST!')
_ = arcpy.management.DeleteField('centerlines_merged',['NEAR_DIST','NEAR_FID'])

В приведенном выше фрагменте кода использовался инструмент «Рядом», чтобы определить близость к ближайшему рекламному щиту для каждой дороги в наших данных по осевым линиям. Мы вычислили множество объектов на основе близости, чтобы сформировать наш набор статических классов объектов.

Нам также пришлось извлечь особенности из самой геометрии дороги. Например, для оценки кривизны дороги мы использовали «извилистость» в качестве метрики. Извилистость - это соотношение между длиной пути и кратчайшим расстоянием между конечными точками. Опять же, используя Arcpy, мы рассчитали это:

# Calc Sinuosity
code_block = \
'''
import math
def getSinuosity(shp):
    x0 = shp.firstPoint.x
    y0 = shp.firstPoint.y
    x1 = shp.lastPoint.x
    y1 = shp.lastPoint.y
euclid = math.sqrt((x0-x1)**2 + (y0-y1)**2)
    length = shp.length
    if euclid > 0:
        return length/euclid
    return 1.0
'''
_ = arcpy.management.CalculateField('centerlines_merged','sinuosity','getSinuosity(!Shape!)',code_block=code_block)

А теперь поговорим о погоде. Есть много различных погодных каналов, но мы решили использовать надежный почасовой источник погоды от NOAA. У нас есть несколько метеостанций, но нам нужно знать погоду на каждом участке дороги. Один из подходов - интерполировать погоду на наземных станциях на отдельные участки дороги. Для этого мы можем использовать технику, известную как «кригинг» в сообществе геостатистов или регрессия гауссовского процесса в сообществе машинного обучения. ArcGIS имеет встроенный инструмент «эмпирического байесовского кригинга» в наборе инструментов геостатистики, который содержит надежную реализацию этого метода, который использует эмпирическое априорное распределение, основанное на данных, и устраняет множество искажений параметров. Если это не вариант для вас, есть другие методы, такие как взвешивание обратных расстояний или простые пространственные соединения (я сделал это изначально для простоты). Если у вас есть другие данные для более точной оценки того, как география влияет на погодные характеристики (например, высота над уровнем моря или более сложные модели климата), вы можете загрузить их в географически взвешенную регрессионную модель, чтобы получить еще большую точность.

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

Сборка обучающего набора

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

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

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

  1. Произвольно выберите запись об аварии из положительных примеров.
  2. Произвольно изменить: отрезок дороги, час дня или день года.
  3. Если нового образца нет в записях о несчастном случае, добавьте его в список отрицательных образцов.
  4. Повторяйте до тех пор, пока у нас не будет большого количества отрицательных образцов (в несколько раз больше положительных образцов).

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

Как показано в приведенной выше сути, категориальные переменные, такие как час, день недели и месяц, кодируются в горячем режиме. Все непрерывные переменные преобразуются в z-значения с помощью scikit-learn StandardScaler. Мы также преобразуем извилистость с помощью логарифмического преобразования, так как большинство значений близки к единице, и мы хотим уловить больше на небольшой разнице, чем на большой (длинные ветреные дороги).

Модель

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

Я не буду вдаваться в подробности оптимизации и обучения гиперпараметров, но вот окончательный выбор модели:

params = {
    'max_depth':6,
    'min_child_weight': 5.0,
    'reg_lambda': 1.0,
    'reg_alpha':0.0,
    'scale_pos_weight':1.0,
    'eval_metric':'auc',
    'objective':'binary:logistic',
    'subsample':0.8,    
    'eta':0.3
}

Мы тренировались до схождения с 10 раундами ранней остановки, достигнув окончательного ROC AUC около 0,828 на сете удержания. В финальной модели было 80 деревьев.

При пороге 0,19 получаем следующие характеристики производительности:

Test Accuracy: 0.685907494583
Test F1: 0.461524665975
Test Precision: 0.311445366528
Test Recall: 0.890767937497
Test AUC: 0.828257459986
Test AP: 0.388845428164
Train Accuracy: 0.68895115694
Train F1: 0.466528546103
Train Precision: 0.314947399182
Train Recall: 0.899402111551
Train AUC: 0.836489144112
Test AP: 0.410456610829

Как я уже сказал ранее, мы намеренно усложнили разделение обучающей выборки, потому что хотели, чтобы результаты отражали истинную производительность модели. Значение отзыва 0,89 означает, что мы можем предсказать почти 90% автомобильных аварий, а значение точности 0,31 означает, что мы правы в отношении этих прогнозов примерно в 30% случаев. Это не идеально, но это отличное начало и определенно говорит нам кое-что о нашей способности предсказывать несчастные случаи. Есть много вещей, которые мы можем сделать, чтобы улучшить производительность этой модели, и, возможно, я вернусь к этому в одной из следующих статей.

Некоторые результаты

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

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

Очевидно, что положение Солнца говорит нам о времени суток и сезоне, но оно также позволяет нам смоделировать интересный фактор: находится ли солнце в глазах водителя? Давайте посмотрим на разделенную гистограмму для солнечной высоты и ориентации дороги.

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

А как насчет временных характеристик нашей модели? Может ли он делать прогнозы с течением времени?

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

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

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

Почему нас это волнует?

Мы построили достойную модель для прогнозирования риска несчастных случаев, но что мы можем с ней сделать? Существует множество возможных приложений, включая следующие, которые мы рассмотрели для приложений:

  • Безопасное планирование маршрута
  • Выделение аварийного транспорта
  • Проектирование проезжей части
  • Где разместить дополнительные указатели (например, для предупреждения о поворотах)

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

Это все, что у меня есть на сегодня, спасибо, что прочитали! Есть лучший подход? Мы что-то плохо делаем? Напишите в комментариях ниже!