Обнаружение выбросов с помощью BigQuery со стандартным отклонением - PullRequest
0 голосов
/ 25 октября 2018

У меня в настоящее время есть таблица в BigQuery, которая содержит некоторые выбросы

Пример таблицы:

port - qty - datetime
--------------------------------
TCP1 - 13 - 2018/06/11 11:20:23
UDP2 - 15 - 2018/06/11 11:24:24
TCP3 - 14 - 2018/06/11 11:24:27
TCP1 - 2  - 2018/06/11 11:24:26 
UDP2 - 15 - 2018/06/11 11:35:32
TCP3 - 13 - 2018/06/11 11:45:23
TCP3 - 14 - 2018/06/11 11:54:22
TCP3 - 30 - 2018/06/11 11:55:33

Я хотел бы иметь возможность отсеять выбросы на различных портах в 2018 году /06/11 с использованием SQL и стандартного отклонения

Результат:

TCP1 - 2  - 2018/06/11 11:24:26
TCP3 - 30 - 2018/06/11 11:55:33

Я провел некоторое исследование и обнаружил, что стандартное отклонение может помочь отсеять выбросы.Тем не менее, я не знаю, как написать запрос SQL, чтобы заставить эту работу.Любая помощь будет принята с благодарностью.

(это самая близкая тема, которую я смог найти по этой теме: Использование BigQuery для поиска выбросов со стандартными отклонениями в сочетании с предложением WHERE )

1 Ответ

0 голосов
/ 25 октября 2018

Ниже приведен пример для BigQuery Standard SQL

#standardSQL
WITH stats AS (
  SELECT DATE(PARSE_TIMESTAMP('%Y/%m/%d %T', datetime)) dt,
    AVG(qty) - 1.5 * STDDEV(qty) down,
    AVG(qty) + 1.5 * STDDEV(qty) up
  FROM `project.dataset.table`
  GROUP BY dt
)
SELECT port, qty, datetime 
FROM `project.dataset.table`
JOIN stats 
ON dt = DATE(PARSE_TIMESTAMP('%Y/%m/%d %T', datetime))
WHERE NOT qty BETWEEN down AND up  

Вы можете протестировать, поиграть с вышеупомянутыми, используя фиктивные данные из вашего вопроса:

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'TCP1' port, 13 qty, '2018/06/11 11:20:23' datetime UNION ALL
  SELECT 'UDP2', 15, '2018/06/11 11:24:24' UNION ALL
  SELECT 'TCP3', 14, '2018/06/11 11:24:27' UNION ALL
  SELECT 'TCP1', 2 , '2018/06/11 11:24:26' UNION ALL 
  SELECT 'UDP2', 15, '2018/06/11 11:35:32' UNION ALL
  SELECT 'TCP3', 13, '2018/06/11 11:45:23' UNION ALL
  SELECT 'TCP3', 14, '2018/06/11 11:54:22' UNION ALL
  SELECT 'TCP3', 30, '2018/06/11 11:55:33' 
), stats AS (
  SELECT DATE(PARSE_TIMESTAMP('%Y/%m/%d %T', datetime)) dt,
    AVG(qty) - 1.5 * STDDEV(qty) down,
    AVG(qty) + 1.5 * STDDEV(qty) up
  FROM `project.dataset.table`
  GROUP BY dt
)
SELECT port, qty, datetime 
FROM `project.dataset.table`
JOIN stats 
ON dt = DATE(PARSE_TIMESTAMP('%Y/%m/%d %T', datetime))
WHERE NOT qty BETWEEN down AND up  

с результатом как

Row port    qty datetime     
1   TCP1    2   2018/06/11 11:24:26  
2   TCP3    30  2018/06/11 11:55:33  
...