Python: 3-сигма детектор «аномалий» количества заказов и строкPython

Программы на Python
Anonymous
Python: 3-сигма детектор «аномалий» количества заказов и строк

Сообщение Anonymous »

Я хочу проанализировать данные о транзакциях в контексте электронной коммерции, где основное внимание уделяется обнаружению нетипичных действий в шаблонах заказов. Данные группируются по идентификатору клиента SoldTo, и для каждой группы мы применяем простой статистический метод для обнаружения аномалий на основе количества заказов и количества строк. В частности, эти шаги включают в себя:
  • Подготовку данных: обеспечение того, чтобы столбец даты (Created_on) имел
    правильный формат.
  • Группировка данных: группировка данных по полю «Продано»
    чтобы изолировать транзакции для каждого клиента. Вычисления скользящего окна
    : для каждой группы применяются вычисления скользящего окна
    для расчета скользящих средних и стандартных отклонений для
    количеств заказов и количества строк.
  • Применить Применение правила 3-х сигм: использование правила 3-х сигм для выявления транзакций, которые значительно отклоняются от нормы, отмечая их как нетипичные или подозрительные.
  • Независимая обработка: обработка каждой группы клиентов (SoldTo). независимо, чтобы
    гарантировать, что на механизм обнаружения не влияют данные
    других клиентов. Объединение результатов: после обработки мы записываем эти
    данные в файл .csv.
Моя проблема: Как В ходе теста я передаю ОДНОМУ известному человеку SoldTo, имеющему аномальные строки, и код работает для обнаружения аномальных строк, как и предполагалось! Но когда я добавляю более одного SoldTo, включая известные аномальные линии, они больше не обнаруживаются. Почему это так?
Вот что я пробовал использовать свой код вместе (надеюсь, так и будет) с двумя удобными для загрузки наборами данных (один имеет только один SoldTo, где мой код будет обнаруживать известные аномальные транзакции - и другой набор данных, содержащий (2) SoldTo current_row['avg_line_sigma_trigger'] or
next_row['total_quantity'] > current_row['avg_qty_sigma_trigger']):
atypical_indices.append(group.index[i + 1])

# Mark atypical rows in the dataframe
df['is_atypical'] = False
df.loc[atypical_indices, 'is_atypical'] = True

return df, atypical_indices

# Identify atypical rows
grouped, atypical_indices = identify_atypical(grouped)

# Print the dataframe and indices of atypical rows
print("Atypical rows indices:", atypical_indices)
print("")

print(grouped)

# Filter atypical rows within a specified date range
#check_these = grouped[(grouped['is_atypical'] == True) & (grouped['Created_on'] >= '2024-06-01')]
check_these = grouped[(grouped['is_atypical'] == True) & (grouped['total_quantity'] != 1) & (grouped['line_count'] != 1) ]
#check_these = grouped[(grouped['is_atypical'] == True)]

# Save the cleaned dataframe to a CSV file
check_these.sort_values(by='SoldTo', ascending=True).to_csv('order_behavior_analysis_3.csv', index=False)

[/code]
При использовании этих данных и наличии только одного проданного товара код возвращает результаты по мере необходимости:
Нетипичные индексы строк: [5, 6, 11]

Код: Выделить всё

[['SoldTo', 'Created_on', 'Sales_Doc', 'Order_Quantity'],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 4],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 4],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 2],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 2],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 17],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 4],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 2],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 11],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 6],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 4],
['59908158', Timestamp('2023-11-06 00:00:00'), 110893468, 11],
['59908158', Timestamp('2023-11-06 00:00:00'), 110893468, 10],
['59908158', Timestamp('2023-11-07 00:00:00'), 110902368, 33],
['59908158', Timestamp('2023-11-07 00:00:00'), 110902525, 10],
['59908158', Timestamp('2023-11-07 00:00:00'), 110902525, 4],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 8],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 6],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 16],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 20],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 20],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 4],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 1],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 20],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 8],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 3],
['59908158', Timestamp('2023-11-13 00:00:00'), 110966070, 52],
['59908158', Timestamp('2023-11-15 00:00:00'), 111035845, 15],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177113, 18],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177113, 5],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177887, 20],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177887, 11],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 4],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 8],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 20],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 22],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 4],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 16],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 12],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 20],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 18],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 3],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 18],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 20],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 7],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 22],
['59908158', Timestamp('2023-11-21 00:00:00'), 111446837, 9],
['59908158', Timestamp('2023-11-21 00:00:00'), 111446837, 13]]

Но, используя эти данные и имея (2) значения SoldTo, код возвращает новые строки, но больше не «обнаруживает» известные нетипичные строки и возвращает разные индексы:
Атипичные индексы строк: [1, 6, 12, 14, 17, 5, 6, 11]

Код: Выделить всё

[['SoldTo', 'Created_on', 'Sales_Doc', 'Order_Quantity'],
['56619720', Timestamp('2023-01-13 00:00:00'), 108036530, 10],
['56619720', Timestamp('2023-01-13 00:00:00'), 108036530, 1],
['56619720', Timestamp('2023-03-03 00:00:00'), 108391209, 20],
['56619720', Timestamp('2023-03-03 00:00:00'), 108391209, 2],
['56619720', Timestamp('2023-04-13 00:00:00'), 108738953, 30],
['56619720', Timestamp('2023-07-24 00:00:00'), 109827151, 20],
['56619720', Timestamp('2023-09-20 00:00:00'), 110467726, 30],
['56619720', Timestamp('2023-10-11 00:00:00'), 110658107, 10],
['56619720', Timestamp('2023-11-10 00:00:00'), 110946376, 2],
['56619720', Timestamp('2023-11-10 00:00:00'), 110946376, 3],
['56619720', Timestamp('2023-11-10 00:00:00'), 110946376, 5],
['56619720', Timestamp('2023-12-13 00:00:00'), 111681360, 5],
['56619720', Timestamp('2023-12-19 00:00:00'), 111739909, 6],
['56619720', Timestamp('2023-12-19 00:00:00'), 111739909, 4],
['56619720', Timestamp('2023-12-19 00:00:00'), 111739909, 2],
['56619720', Timestamp('2023-12-19 00:00:00'), 111739909, 2],
['56619720', Timestamp('2024-01-25 00:00:00'), 112057996, 5],
['56619720', Timestamp('2024-02-23 00:00:00'), 112322261, 12],
['56619720', Timestamp('2024-03-07 00:00:00'), 112453024, 5],
['56619720', Timestamp('2024-03-25 00:00:00'), 112625572, 5],
['56619720', Timestamp('2024-03-25 00:00:00'), 112625572, 3],
['56619720', Timestamp('2024-03-27 00:00:00'), 112651496, 2],
['56619720', Timestamp('2024-04-26 00:00:00'), 112942567, 5],
['56619720', Timestamp('2024-04-26 00:00:00'), 112942567, 5],
['56619720', Timestamp('2024-04-26 00:00:00'), 112942567, 2],
['56619720', Timestamp('2024-04-26 00:00:00'), 112942567, 2],
['56619720', Timestamp('2024-04-26 00:00:00'), 112942567, 2],
['56619720', Timestamp('2024-05-09 00:00:00'), 113200232, 2],
['56619720', Timestamp('2024-05-22 00:00:00'), 113359192, 2],
['56619720', Timestamp('2024-06-10 00:00:00'), 113534221, 1],
['56619720', Timestamp('2024-06-10 00:00:00'), 113534221, 34],
['56619720', Timestamp('2024-06-10 00:00:00'), 113534221, 20],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 4],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 4],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 2],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 2],
['59908158', Timestamp('2023-11-02 00:00:00'), 110866572, 17],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 4],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 2],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 11],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 6],
['59908158', Timestamp('2023-11-06 00:00:00'), 110884032, 4],
['59908158', Timestamp('2023-11-06 00:00:00'), 110893468, 11],
['59908158', Timestamp('2023-11-06 00:00:00'), 110893468, 10],
['59908158', Timestamp('2023-11-07 00:00:00'), 110902368, 33],
['59908158', Timestamp('2023-11-07 00:00:00'), 110902525, 10],
['59908158', Timestamp('2023-11-07 00:00:00'), 110902525, 4],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 8],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110929917, 6],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 16],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 20],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 20],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 10],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 4],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 1],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 20],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 8],
['59908158', Timestamp('2023-11-09 00:00:00'), 110930046, 3],
['59908158', Timestamp('2023-11-13 00:00:00'), 110966070, 52],
['59908158', Timestamp('2023-11-15 00:00:00'), 111035845, 15],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177113, 18],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177113, 5],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177887, 20],
['59908158', Timestamp('2023-11-16 00:00:00'), 111177887, 11],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 4],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 8],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 20],
['59908158',  Timestamp('2023-11-20 00:00:00'), 111430236, 22],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 4],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 16],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 12],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 20],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 18],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 3],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 18],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 20],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 7],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 10],
['59908158', Timestamp('2023-11-20 00:00:00'), 111430236, 22],
['59908158', Timestamp('2023-11-21 00:00:00'), 111446837, 9],
['59908158', Timestamp('2023-11-21 00:00:00'), 111446837, 13]]
Спасибо за помощь в интерпретации моего дальнейшего пути.

Подробнее здесь: https://stackoverflow.com/questions/786 ... -and-lines

Вернуться в «Python»