Изменить выбросы, вызванные сбоями датчика в данных таймсерий - PullRequest
0 голосов
/ 19 июня 2020

Я работаю с данными таймсерий, собранными с датчика с интервалом в 5 минут. К сожалению, бывают случаи, когда измеренное значение (выход PV в ваттах) составляет внезапно 0 или очень высокое . Значения до и после верны :

Источник

def updateOutliersIQR(group):
  Q1 = group.yield.quantile(0.25)
  Q3 = group.yield.quantile(0.75)
  IQR = Q3 - Q1
  outliers = (group.yield < (Q1 - 1.5 * IQR)) | (group.yield > (Q3 + 1.5 * IQR))
  print(outliers[outliers == True]) 

# calling the function on a per-day level
df.groupby(df.index.date).apply(updateOutliers)

Попробуйте 2: плотность ядра оценка Источник

def updateOutliersKDE(group):
  a = 0.9
  r = group.yield.rolling(3, min_periods=1, win_type='parzen').sum()
  n = r.max()
  outliers = (r > n*a)
  print(outliers[outliers == True]) 

# calling the function on a per-day level
df.groupby(df.index.date).apply(updateOutliers)

Попробуйте 3: Медианный фильтр Источник (По предложению Джоннора)

def median_filter(num_std=3):
  def _median_filter(x):
    _median = np.median(x)
    _std = np.std(x)
    s = x[-3]
    if (s >= _median - num_std * _std and s <= _median + num_std * _std):
      return s
    else:
      return _median
  return _median_filter

# calling the function
df.yield.rolling(5, center=True).apply(median_filter(2), raw=True)

Редактировать: с попыткой 3 и окном 5 и стандартным 3, он, наконец, улавливает массивный выброс, но также теряет точность других (исправных) измерений датчика: введите описание изображения здесь

Есть ли какие-нибудь более эффективные подходы для обнаружения описанных «выбросов» или выполнения сглаживания в данных временного ряда с помощью случайной проблемы измерения датчика?

1 Ответ

0 голосов
/ 23 июня 2020

Ваши ненормальные значения ненормальны в том смысле, что

  • значения сильно отклоняются от значений вокруг него
  • значение меняется очень быстро от одного временного шага к другому

Таким образом, необходим фильтр, который смотрит на короткий временной контекст, чтобы отфильтровать их.

Одним из самых простых и эффективных является медианный фильтр .

filtered = pandas.rolling_median(df, window=5)

Чем длиннее окно, тем сильнее фильтр.

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

Конечно, можно также создать больше настраиваемых фильтров. Например, вычислите разницу первого порядка и отклоните изменения, превышающие определенный порог. Вы можете построить гистограмму различий, чтобы определить порог. Отметьте их как отсутствующие (NaN), а затем введите недостающие значения с использованием медианы / среднего.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...