При обработке данных исходного DataSet часто попадаются аномальные значения, которые поставлены вместо пропусков, и мало того, что они скрываются, так ещё и несут вред общему делу. В данной статье будет разобран практический пример избавления от аномальных значений в связанных с географией данных при помощи инструментов известной библиотеки Pandas. 

В качестве примера возьмём достаточно известный соревновательный DataSet «Pump it Up: Data Mining the Water Table».

Сначала войдём в курс проблемы. Стоит задача определить состояние пункта водоснабжения («водоколонки») в Танзании по различным данным об этих пунктах: кто построил, когда построил, кол-во населения в округе и т.д. Однако особый интерес представляют  longtitude и latitude (долгота и широта), т.е. конкретное место расположения той или иной водоколонки на карте.

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

Отображение значений longtitude и latitude
Отображение значений longtitude и latitude

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

В нашем DataSet есть такие территориальные единицы как region (регион)  и subvillage (деревня). Регион состоит из деревень.

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

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

Идея проста:

  • Определяем к какой деревне принадлежит данная водоколонка

  • Считаем среднее расположение по всем водоколонкам, координаты которых НЕ ошибочны

  • Записываем получившиеся значения в longtitude и latitude для текущей водоколонки

  • И так для всех водоколонок, одиноко плавающих в океане

Вот мы и добрались до кода:

################################################################
# Получаем таблицу средних расположений водоколонок по деревням.
################################################################

average_coords_subvillage = data_all[data_all.longitude!=0].groupby(
  'subvillage')[['longitude', 'latitude']].mean()
Таблица средних координат
Таблица средних координат

С помощью метода groupby производим группировку по subvillage c подсчётом средних значений по долготе и широте.
В итоге получаем таблицу, где каждому subvillage соответствуют средние координаты широты и долготы по всем водоколонкам, координаты которых были известны (поэтому и используется срез [data_all.longitude!=0]).
Столбец subvillage становится индексным столбцом. Как раз посредством него и будет происходит последующая магия.

#################################
# Заполняем пропуски по деревням.
#################################

data_all.longitude[data_all.longitude==0] = data_all[data_all.longitude==0].subvillage.map(
    average_coords_subvillage['longitude']
)

data_all.latitude[data_all.latitude==-0.00000002] = data_all[data_all.latitude==-0.00000002].subvillage.map(
    average_coords_subvillage['latitude']
)

# *где 0 - аномальное значение по долготе, 2е-8 - аномальное значение по широте

Далее с помощью метода map происходит замена названия деревни на среднее значение широты, которое ей соответствует (срез [data_all.longitude==0] означает, что мы производим замену только для тех водоколонок, где долгота была ошибочна). Затем данные значения благополучно помещаются на места ошибочных значений долготы в столбец longtitude исходного DataSet.

Та же самая процедура происходит и с широтами.

И если теперь по новым значениям longtitude и latitude построить карту расположения водоколонок, то картинка получается куда приятнее:

Отображение значений longtitude и latitude после избавления от аномалий
Отображение значений longtitude и latitude после избавления от аномалий
Реальная карта Танзании со спутника
Реальная карта Танзании со спутника

Подведём итоги:

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

  • Неизвестные данные о расположении объектов можно заполнить посредством их принадлежности к какому-либо классу (привязанному к географии).

  • Методы groupby и map довольно удобные и мощные инструменты для решения такого рода задач.

P.S.:

На практике некоторые деревни:

  • содержали только одну водоколонку

  • данная водоколонка была с ошибочными координатами

Поэтому срез [data_all.longitude!=0] при формировании таблицы средних координат исключил такие деревни вовсе. А после применения map вместо координат долготы и широты в одинокие водоколонки записались NaN.

Данная проблема была решена :)

Но как бы вы решили её? Пишите в комментариях!

Комментарии (2)


  1. vampirek
    24.01.2022 08:38

    > по subvillage, т.к. это обеспечит большую точность в сравнении с регионом

    А не лучше ли subvillage + region ? Судя по данным, деревня обозначена только текстом, и высоко вероятно, что в разных регионах будут деревни с одним и тем же наименованием?


    1. VladislavSoren Автор
      24.01.2022 08:49

      Всего уникальных деревень в DataSet порядка 20 000 тысяч, поэтому не думаю что если повторения и есть, то их много)

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

      Так что без Subvillage + Region не обошлось)