Введение
Как крупнейший бакалейщик в Соединенных Штатах, 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
Давайте вернемся к нашей цели прогнозирования периодов разморозки в холодильных шкафах. Как описано ранее, возможность профилирования разморозки в холодильных шкафах является ключевым фактором при прогнозировании аномалий холодильного оборудования. Для целей этого блога мы будем полагаться на одномерные данные о температуре холодильного шкафа.
Сигнал температуры корпуса, показанный выше, типичен для холодильных шкафов, в которых необходимо поддерживать постоянную температуру и периодически размораживать. Проблема здесь заключается в том, что эти периоды разморозки постепенно смещаются с течением времени в зависимости от таких факторов, как внешняя погода, содержимое ящиков, движение в магазине, ремонт и т. д. В результате нам нужна надежная логика для обнаружения периодических краткосрочных разморозок. но медленно смещается на более длительный период времени.
Мы будем использовать преобразование Фурье для обработки сигнала температуры корпуса и извлечения из него сигнала разморозки. Для этого мы упростим температуру корпуса, состоящую из трех частей: размораживание, стационарная температура и ошибка. Как только мы делаем это предположение, остается только отфильтровать частотную составляющую, соответствующую оттаиванию, из температурного сигнала, преобразованного Фурье.
Ниже представлена общая схема этого процесса:
- Преобразуйте сигнал температуры корпуса из временной области в частотную область.
- Изучите частотный спектр и определите соответствующие компоненты. Для нашего варианта использования мы смогли определить, что: устойчивая температура имеет нулевую частоту (постоянный сигнал) и самую высокую величину, а сигнал оттаивания относится к частоте со второй по величине величиной.
- Отфильтруйте частотный спектр, чтобы он содержал только частоту, относящуюся к разморозке, и отфильтруйте остальные.
- Выполните обратное преобразование Фурье отфильтрованного частотного спектра, чтобы получить сигнал разморозки.
- Прогнозировать периоды разморозки в ближайшие дни путем экстраполяции идентифицированного сигнала разморозки.
# 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