Введение

Как крупнейший бакалейщик в Соединенных Штатах, Walmart имеет массовую сборку холодильных систем для супермаркетов в своих магазинах по всей стране. Качество продуктов питания является неотъемлемой частью нашего обслуживания клиентов, и Walmart ежегодно тратит значительные суммы на техническое обслуживание своего обширного ассортимента холодильных систем. Стремясь улучшить общие методы технического обслуживания, мы используем стратегии профилактического и упреждающего обслуживания. Мы в Walmart Global Tech используем данные IoT и создаем алгоритмы для изучения и упреждающего обнаружения аномальных событий в холодильных системах в Walmart.

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

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

Чтобы понять идею, лежащую в основе преобразования Фурье, давайте вернемся в историю и познакомимся с одной из самых ранних математических моделей Вселенной под названием система Птолемея. Птолемей вместе с другими греческими физиками пытался смоделировать вселенную с Землей в ее центре и планетами, движущимися по кругу. Однако траектории Солнца, Луны, планет и звезд, наблюдаемые с Земли, не являются круглыми. Поэтому Птолемей добавил «эксцентриситет» к своим моделям, используя идею о том, что планеты движутся по одному большому кругу, но в то же время также движутся по маленькому кругу, как точка на краю колеса. Эта модель по-прежнему не объясняла движение планет правильно, и в конце концов ее усовершенствовали, добавив больше кругов поверх кругов, чтобы она выглядела примерно так:

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

Забавное примечание: рисуем лицо Гомера Симпсона, используя систему эпициклов Птолемея: Птолемей и Гомер (Симпсон)

За кулисами:

Теперь, когда у нас есть общее представление о преобразовании Фурье, давайте углубимся в то, как оно работает. Начнем с рассмотрения особенностей кругового пути. Любой круговой путь можно описать с помощью трех вещей: размера, скорости и начального угла. Изменяя их, мы можем создавать различные круговые движения.

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

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

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

С точки зрения реализации, давайте посмотрим, как это сделать на Python. Мы создадим простой синусоидальный сигнал и посмотрим на его частотный профиль с помощью БПФ (БПФ — это более быстрая реализация преобразования Фурье).

import numpy as np
import matplotlib.pyplot as plt

## Create a simple signal 
# sampling rate and frequency
dt = 0.01
f = 10
t = np.arange(0,1,dt)
# signal
f = np.sin(2*np.pi*f*t)
## Compute the Fast Fourier Transform (FFT)
n = len(t)
# Compute the FFT
fhat = np.fft.fft(f,n)                
# Compute the Amplitude
A = fhat * np.conj(fhat) / n
# Create frequencies
freq = (1/(dt*n)) * np.arange(n)      
# Only plot the first half of freqs
l = np.arange(1,np.floor(n/2),dtype='int') 
## Plots
fig,axs = plt.subplots(1,2)
plt.sca(axs[0])
plt.plot(t,f)
plt.sca(axs[1])
plt.stem(freq[l],A[l])

Точно так же, выполнив обратное преобразование Фурье, мы можем получить сигнал из частотного спектра обратно в сигнал во временной области.

# Inverse FFT for filtered time signal
inv_fft = np.fft.ifft(fhat)

По сути, используя преобразование Фурье, мы можем разработать общую структуру для обработки сигналов следующим образом:

  • Возьмите временной сигнал
  • Разделите его на составляющие синусоидальные сигналы
  • Разделяйте и анализируйте отдельные составляющие сигналы по мере необходимости

Игрушечный пример: шумоподавление информационных сигналов

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

- Частоты высокой амплитуды, соответствующие исходному чистому сигналу

- Низкая амплитуда и нерегулярные частоты, соответствующие шуму, добавленному к сигналу

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

  • Разложите зашумленный сигнал из временной области на составляющие его частоты с помощью преобразования Фурье.
  • Отфильтруйте все низкочастотные компоненты, используя подходящий порог*
  • Преобразуйте отфильтрованный сигнал в частотной области обратно во временную область с помощью обратного преобразования Фурье.

* порог может быть определен эмпирически или с использованием знаний предметной области.

import numpy as np
## Create a sample information signal as a sum of two frequencies
dt = 0.001
t = np.arange(0,1,dt)
f = np.sin(2*np.pi*75*t) + np.sin(2*np.pi*120*t) 
f_clean = f
# Add some noise
f = f + 1.5*np.random.randn(len(t))

## Compute the Fast Fourier Transform (FFT)
n = len(t)
# Compute the FFT
fhat = np.fft.fft(f,n)
# Compute the Amplitude
A = fhat * np.conj(fhat) / n
# Compute the frequencies
freq = (1/(dt*n)) * np.arange(n)

# Create an index to filter large frequencies
idx = A >= 50
# Zero out smaller frequencies
fhat = idx * fhat     
# Take inverse FFT to retrieve the original signal
inv_fft = np.fft.ifft(fhat) 

Прогнозирование разморозки в холодильных шкафах в Walmart

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

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

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

Ниже представлена ​​общая схема этого процесса:

  1. Преобразуйте сигнал температуры корпуса из временной области в частотную область.
  2. Изучите частотный спектр и определите соответствующие компоненты. Для нашего варианта использования мы смогли определить, что: устойчивая температура имеет нулевую частоту (постоянный сигнал) и самую высокую величину, а сигнал оттаивания относится к частоте со второй по величине величиной.
  3. Отфильтруйте частотный спектр, чтобы он содержал только частоту, относящуюся к разморозке, и отфильтруйте остальные.
  4. Выполните обратное преобразование Фурье отфильтрованного частотного спектра, чтобы получить сигнал разморозки.
  5. Прогнозировать периоды разморозки в ближайшие дни путем экстраполяции идентифицированного сигнала разморозки.
# Function to extract defrost signal from case temperature data
def get_defrost(x):
    
    ## Calculate fast fourier transform
    fhat = np.fft.fft(x,len(x))
    A = fhat * np.conj(fhat) / len(x)
    ## Get the second highest amplitude in frequency domain 
    #  that will belong to the defrost signal
    idx = A >= sorted(A)[-2] 
    
    # filter out remaining frequencies 
    fhat = idx*fhat    
    
    
    ## Inverse FFT to extract the defrost signal
    ffilt = np.fft.ifft(fhat) 
    
    return abs(ffilt)

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

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

Пример № 3 особенно интересен, так как здесь производительность модели плохая, но при осмотре видно, что это проблема качества данных. Хотя прогнозируемая разморозка выглядит правильно, фактическая команда не синхронизирована с циклом разморозки (пиковое значение достигает после разморозки). Таким образом, случаи, когда модель работает очень плохо, можно рассматривать как потенциальные проблемы с качеством данных и помечать для дальнейшего изучения.

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

В заключение, текущий подход позволяет нам сделать следующее:

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

Рекомендации



Шумоподавление данных с помощью FFT [Python] — https://www.youtube.com/watch?v=s2K1JfNR7Sc

Но что такое преобразование Фурье? Визуальное введение — https://www.youtube.com/watch?v=spUNpyF58BY