Подход с обнаружением аномалий на исторических данных полета

Задний план

В данных временных рядов, представленных в виде простой линейной диаграммы, мы часто можем довольно легко определить пики. Однако какие из этих вершин произошли случайно? И есть ли в непиковых данных какой-либо сигнал, на который мы действительно должны обращать внимание? На эти вопросы можно ответить с помощью статистического подхода, часто известного как обнаружение аномалий. В этом коротком сообщении блога мы продемонстрируем такой подход на исторических данных полета, полученных здесь с помощью пакета Twitter AnomalyDetection в R.

Набор данных состоит из около 7 миллионов полетной информации в 2008 году с 29 функциями, такими как:

Дата: год, месяц, день месяца, день недели
DepTime: фактическое время отправления
CRSDepTime : время вылета по расписанию;
ArrTime: фактическое время прибытия;
CRSArrTime: время прибытия по расписанию;
UniqueCarrier: авиакомпании
FlightNum: номер рейса
TailNum: бортовой номер самолета
DepDelay: задержка времени вылета (в минут)
ArrDelay: задержка времени прибытия (в минутах)

Цель

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

Подход

Сначала мы упорядочим набор данных в стандартный формат ввода для пакета AnomalyDetection, который требует двух столбцов данных. Первый столбец - это отметка времени, а второй столбец - задержка во времени отправления. Учитывая большой объем информации о рейсах в наборе данных, мы будем изучать только ненормальные задержки на маршруте полета из Чикаго (международный аэропорт О’Хара) в Нью-Йорк (международный аэропорт Джона Ф. Кеннеди). Мы также сравним аномальные задержки между разными авиакомпаниями.

Алгоритм

Как мы знаем, обычная практика построения модели временных рядов имеет вид Y = S + T + e, где Y - метрика (в нашем случае задержка отправления в минутах), S - сезонность, T - тенденция, e - ошибка (или нерегулярные составляющие). Нам нужно сначала разложить задержку в минутах на эти 3 категории и удалить периодические компоненты и медианное значение данных, чтобы создать остаточное значение для нашего алгоритма.

Основным алгоритмом пакета AnomalyDetection является Seasonal Hybrid ESD (S-H-ESD), который основан на Общем тесте ESD для обнаружения аномалий, как объясняется здесь (прямая цитата ниже).

«Процедура ESD вычисляет статистику

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

, и следующая статистика рассчитывается по уменьшенному размеру выборки после удаления выборки с наибольшим отклонением, и так далее для последующей статистики. Пакет R Twitter основан на этой процедуре, работая с сезонностью и кусочной аппроксимацией ».

Результаты

1… В целом (3505 рейсов, отклонения 0,31%)

Далее мы увидим задержки у разных авиакомпаний, выполняющих один и тот же маршрут.

2… American Airlines (632 рейса, отклонения от нормы 0,95%)

3… JetBlue Airlines (1457 рейсов, отклонения от нормы 0,96%)

4… American Eagle Airlines (253 рейса с отклонениями 0,79%)

5… Comair (1163 рейса, отклонения от нормы 0,95%)

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

Код R

library(devtools)
library(ggplot2)
library(AnomalyDetection)
setwd("~/Desktop/flight")
mydata <- read.csv("2008.csv")
#Manipulate time and date into desired format
mydata$Year <- substr(mydata$Year, 3, 4)
mydata$date <- paste(mydata$Month,"/",mydata$DayofMonth,"/",mydata$Year,sep="")
mydata$time_dep <- as.character(mydata$DepTime)
mydata$time_dep <- ifelse(nchar(mydata$time_dep)<4,paste("0",mydata$time_dep,sep=""),mydata$time_dep)
mydata$time_hour <- substr(mydata$time_dep, 1, 2)
mydata$time_min <- substr(mydata$time_dep, 3, 4)
mydata$time_dep_final <- paste(mydata$date," ",mydata$time_hour,":",mydata$time_min,sep="")
mydata$time_dep_final <- strptime(mydata$time_dep_final, "%m/%d/%y %H:%M")
mydata <- mydata[complete.cases(mydata$DepDelay),]
mydata <- mydata[complete.cases(mydata$time_dep_final),]
write.csv(mydata,"flightdelay.csv")
mydata <- read.csv("flightdelay.csv")
#Include flights where origin was Chicago ORD and destination was New York JFK only
ORD_JFK <- mydata[mydata$Origin=="ORD" & mydata$Dest=="JFK",]
ggplot(data=ORD_JFK,aes(x=time_dep_final,y=DepDelay,color=UniqueCarrier))+
  geom_line()+
  xlab("2008 Overall")+
  ylab("Delay in Departure Time (minutes)")+
  scale_colour_hue(name="Airlines",
                      breaks=c("AA","B6","MQ","OH"),
                      labels=c("American Airlines","JetBlue Airlines","American Eagle Airlines","Comair"))
write.csv(ORD_JFK,"ORD_JFK.csv")
ORD_JFK <- read.csv("ORD_JFK.csv")
#Remove invalid values
ORD_JFK <- ORD_JFK[-2318,]
#Input only 2 columns for the AnomalyDetection package
ORD_JFK_ad <- ORD_JFK[,c(35,17)]
#Run anomaly detection on all flights
ORD_JFK_anomaly = AnomalyDetectionTs(
  x=ORD_JFK_ad,
  max_anoms=0.01,
  direction = "both",
  alpha = 0.05,
  longterm = T,
  plot = T,
  xlabel="2008 Overall",
  ylabel="Delay in Departure Times (minutes)")
ORD_JFK_anomaly$plot
ORD_JFK_anomaly$anoms
#Run anomaly detection on AA flights
ORD_JFK_AA_ad <- ORD_JFK[ORD_JFK$UniqueCarrier=="AA",]
ORD_JFK_AA_ad <- ORD_JFK_AA_ad[,c(35,17)]
ORD_JFK_AA_anomaly = AnomalyDetectionTs(
  x=ORD_JFK_AA_ad,
  max_anoms=0.01,
  direction = "both",
  alpha = 0.05,
  longterm = F,
  plot = T,
  xlabel="2008 American Airlines",
  ylabel="Delay in Departure Time (minutes)")
ORD_JFK_AA_anomaly$plot
ORD_JFK_AA_anomaly$anoms
##Run anomaly detection on B6 flights
ORD_JFK_B6_ad <- ORD_JFK[ORD_JFK$UniqueCarrier=="B6",]
ORD_JFK_B6_ad <- ORD_JFK_B6_ad[,c(35,17)]
ORD_JFK_B6_anomaly = AnomalyDetectionTs(
  x=ORD_JFK_B6_ad,
  max_anoms=0.01,
  direction = "both",
  alpha = 0.05,
  longterm = F,
  plot = T,
  xlabel="2008 JetBlue Airlines",
  ylabel="Delay in Departure Time (minutes)")
ORD_JFK_B6_anomaly$plot
ORD_JFK_B6_anomaly$anoms
#Run anomaly detection on MQ flights
ORD_JFK_MQ_ad <- ORD_JFK[ORD_JFK$UniqueCarrier=="MQ",]
ORD_JFK_MQ_ad <- ORD_JFK_MQ_ad[,c(35,17)]
ORD_JFK_MQ_anomaly = AnomalyDetectionTs(
  x=ORD_JFK_MQ_ad,
  max_anoms=0.01,
  direction = "both",
  alpha = 0.05,
  longterm = F,
  plot = T,
  xlabel="2008 American Eagle Airlines",
  ylabel="Delay in Departure Time (minutes)")
ORD_JFK_MQ_anomaly$plot
ORD_JFK_MQ_anomaly$anoms
#Run anomaly detection on OH flights
ORD_JFK_OH_ad <- ORD_JFK[ORD_JFK$UniqueCarrier=="OH",]
ORD_JFK_OH_ad <- ORD_JFK_OH_ad[,c(35,17)]
ORD_JFK_OH_anomaly = AnomalyDetectionTs(
  x=ORD_JFK_OH_ad,
  max_anoms=0.01,
  direction = "both",
  alpha = 0.05,
  longterm = F,
  plot = T,
  xlabel="2008 Comair Airlines",
  ylabel="Delay in Departure Time (minutes)")
ORD_JFK_OH_anomaly$plot
ORD_JFK_OH_anomaly$anoms

Вопросы, комментарии или проблемы?
[email protected]