- Оригинальный адрес:Extreme Rare Event Classification using Autoencoders in Keras
- Оригинальный автор:Chitta Ranjan
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:ccJia
- Корректор:lsvih
В этой статье мы научимся создавать классификатор редких событий с помощью автоэнкодеров. Мы будем использовать реальный набор данных о редких событиях из [1].
задний план
Что такое чрезвычайно редкое событие?
В проблеме редких событий мы сталкиваемся с несбалансированным набором данных. Это означает, что у нас очень мало положительных меток по сравнению с отрицательными. В типичной проблеме редких событий положительные образцы составляют около 5-10% от общего числа данных. В задаче о чрезвычайно редких событиях у нас есть менее 1% положительных данных. Например, в используемом нами наборе данных было всего 0,6% положительных образцов.
Такие чрезвычайно редкие события очень распространены в реальном мире. Например, разрывы бумаги и отказы машин на фабриках, клики или покупки в индустрии онлайн-продаж.
Разобраться в этих редких событиях непросто. В последнее время глубокое обучение широко используется в задачах классификации. Тем не мение,Небольшое количество положительных образцов ограничивает применение глубокого обучения.. Независимо от объема данных количество положительных образцов будет ограничивать эффективность глубокого обучения.
Зачем ломать голову над глубоким обучением?
Это резонный вопрос. Почему бы нам не рассмотреть возможность использования других методов машинного обучения?
Ответ субъективен. Мы можем использовать методы машинного обучения. Чтобы заставить его работать, мы можем отрицательно сэмплировать отрицательные данные, чтобы данные были близки к балансу. Поскольку данные положительной выборки составляют всего 0,6%, набор данных с уменьшенной выборкой составляет всего около 1% от исходного размера набора данных. Некоторые методы машинного обучения, такие как: SVM, случайный лес и т. д., могут работать с таким объемом данных. Однако его точность будет ограничена. Это потому, что мы не будем использовать оставшиеся 99% данных.
Глубокое обучение будет работать лучше, если будет достаточно данных. Он также может гибко улучшать модель, используя различные структуры. Поэтому мы готовы экспериментировать с методами глубокого обучения.
В этом твитеМы собираемся научиться использовать простой полносвязный автокодировщик слоев для создания классификатора редких событий.. Цель твита — продемонстрировать автоэнкодерную реализацию чрезвычайно редкого классификатора событий. Мы оставляем работу по изучению различных структур и конфигураций автоэнкодера читателю. Если у вас есть интересные находки, поделитесь с нами.
Автоэнкодеры для классификации
То, как автоэнкодеры справляются с задачами классификации, похоже нааномальное обнаружение. При обнаружении аномалий мы изучаем закономерности нормальных процессов. Все, что не соответствует этому шаблону, считается аномальным. Для задачи бинарной классификации редких событий мы можем использовать автоэнкодер аналогичным образом (дальнейшее чтение[2]).
Быстрый взгляд: что такое автоэнкодер?
- Автоэнкодер состоит из энкодера и декодера.
- Декодер использует для изучения скрытые особенности процесса. Эти функции обычно представлены небольшим числом измерений.
- Декодер может восстановить исходные данные из скрытых признаков.
Как использовать автоэнкодеры для классификации редких событий?
- Сначала мы делим данные на две части: метки положительного образца и метки отрицательного образца.
- Отрицательные метки проб по соглашениюнормальныйгосударство.нормальныйСостояние — это бессобытийный процесс.
- Мы будем игнорировать положительные данные при обучении этого автоэнкодера на отрицательных данных.
- Теперь этот автоэнкодер узнает всенормальныйхарактеристики процесса.
- Хорошо обученный автоэнкодер может предсказать любойнормальныйсостояние процесса (поскольку они имеют одинаковую структуру и распределение).
- Следовательно, ошибка реконструкции будет меньше.
- Однако, если мы реконструируем данные из редкого события, автоэнкодер столкнется с трудностями.
- Это приводит к высокой ошибке реконструкции при реконструкции редких событий.
- Мы можем зафиксировать эти высокие ошибки реконструкции и обозначить их как редкие события.
- Этот процесс аналогичен обнаружению аномалий.
выполнить
данные и вопросы
Это дихотомическая этикетка с данными об обрыве бумаги на бумажной фабрике. На бумажных фабриках поломка бумаги представляет собой серьезную проблему. Один разрыв бумаги может стоить тысячи долларов, и на фабриках случается как минимум один или несколько разрывов бумаги в день. Это приводит к миллионам долларов убытков и производственных рисков каждый год.
Из-за характера процесса обнаружение сбоев является очень сложной задачей. Как упоминалось в [1], даже снижение количества трещин на 5% может принести металлургическим предприятиям значительную выгоду.
За 15 дней сбора мы получаем 18 тысяч строк данных. Столбец «y» содержит двоичные метки, где 1 представляет разрыв. Остальные столбцы являются предикторами. Вот 124 положительных образца (~ 0,6%).
Загрузите данные из [здесь] (docs.Google.com/forms//oh/1…) для загрузки данных.
код
Import the desired libraries.
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from pylab import rcParams
import tensorflow as tf
from keras.models import Model, load_model
from keras.layers import Input, Dense
from keras.callbacks import ModelCheckpoint, TensorBoard
from keras import regularizers
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, precision_recall_curve
from sklearn.metrics import recall_score, classification_report, auc, roc_curve
from sklearn.metrics import precision_recall_fscore_support, f1_score
from numpy.random import seed
seed(1)
from tensorflow import set_random_seed
set_random_seed(2)
SEED = 123 #used to help randomly select the data points
DATA_SPLIT_PCT = 0.2
rcParams['figure.figsize'] = 8, 6
LABELS = ["Normal","Break"]
Обратите внимание, что мы устанавливаем случайное начальное число для воспроизводимых результатов.
обработка данных
Теперь давайте прочитаем и подготовим данные.
df = pd.read_csv("data/processminer-rare-event-mts - data.csv")
Цель этой задачи о редких событиях — предсказать переломы до того, как они произойдут. Стараемся предугадать перерыв на 4 минуты вперед. Чтобы построить эту модель, мы продвигаем метки данных на 2 строки (что соответствует 4 минутам). Реализовано с помощью этой строки кодаdf.y=df.y.shift(-2)
. Однако в этой задаче мы хотим сделать следующее: определить, будет ли строка n помечена как положительная выборка,
-
позволять (n-2) и (n-1) помечен как 1. Это помогает классификатору научиться предсказывать на 4 минуты вперед.
-
УдалитьnРяд. Потому что мы не хотим, чтобы классификатор научился предсказывать происходящий разрыв.
Мы разработаем следующую UDF для этого движения кривой.
sign = lambda x: (1, -1)[x < 0]
def curve_shift(df, shift_by):
'''
这个函数是用来偏移数据中的二分类标签。
平移只针对标签为 1 的数据
举个例子,如果偏移量为 -2,下面的处理将会发生:
如果是 n 行的标签为 1,那么
- 使 (n+shift_by):(n+shift_by-1) = 1
- 删除第 n 行。
也就是说标签会上移 2 行。
输入:
df 一个分类标签列的 pandas 数据。
这个标签列的名字是 ‘y’。
shift_by 一个整数,表示要移动的行数。
输出:
df 按照偏移量平移过后的数据。
'''
vector = df['y'].copy()
for s in range(abs(shift_by)):
tmp = vector.shift(sign(shift_by))
tmp = tmp.fillna(0)
vector += tmp
labelcol = 'y'
# 添加向量到 df
df.insert(loc=0, column=labelcol+'tmp', value=vector)
# 删除 labelcol == 1 的行.
df = df.drop(df[df[labelcol] == 1].index)
# 丢弃 labelcol 同时将 tmp 作为 labelcol。
df = df.drop(labelcol, axis=1)
df = df.rename(columns={labelcol+'tmp': labelcol})
# 制作二分类标签
df.loc[df[labelcol] > 0, labelcol] = 1
return df
Теперь мы разделяем данные на обучающий набор, проверочный набор и тестовый набор. Затем мы будем использовать только подмножество, помеченное 0, для обучения автоэнкодера.
df_train, df_test = train_test_split(df, test_size=DATA_SPLIT_PCT, random_state=SEED)
df_train, df_valid = train_test_split(df_train, test_size=DATA_SPLIT_PCT, random_state=SEED)
df_train_0 = df_train.loc[df['y'] == 0]
df_train_1 = df_train.loc[df['y'] == 1]
df_train_0_x = df_train_0.drop(['y'], axis=1)
df_train_1_x = df_train_1.drop(['y'], axis=1)
df_valid_0 = df_valid.loc[df['y'] == 0]
df_valid_1 = df_valid.loc[df['y'] == 1]
df_valid_0_x = df_valid_0.drop(['y'], axis=1)
df_valid_1_x = df_valid_1.drop(['y'], axis=1)
df_test_0 = df_test.loc[df['y'] == 0]
df_test_1 = df_test.loc[df['y'] == 1]
df_test_0_x = df_test_0.drop(['y'], axis=1)
df_test_1_x = df_test_1.drop(['y'], axis=1)
стандартизация
Для автоэнкодеров обычно лучше всего подходят нормализованные данные (преобразованные в гауссовский, среднее значение 0 и дисперсия 1).
scaler = StandardScaler().fit(df_train_0_x)
df_train_0_x_rescaled = scaler.transform(df_train_0_x)
df_valid_0_x_rescaled = scaler.transform(df_valid_0_x)
df_valid_x_rescaled = scaler.transform(df_valid.drop(['y'], axis = 1))
df_test_0_x_rescaled = scaler.transform(df_test_0_x)
df_test_x_rescaled = scaler.transform(df_test.drop(['y'], axis = 1))
классификатор автоэнкодера
инициализация
Во-первых, мы инициализируем структуру автоэнкодера. Мы просто создаем простой автоэнкодер. Читателю предстоит исследовать более сложные структуры и конфигурации.
nb_epoch = 100
batch_size = 128
input_dim = df_train_0_x_rescaled.shape[1] #num of predictor variables,
encoding_dim = 32
hidden_dim = int(encoding_dim / 2)
learning_rate = 1e-3
input_layer = Input(shape=(input_dim, ))
encoder = Dense(encoding_dim, activation="tanh", activity_regularizer=regularizers.l1(learning_rate))(input_layer)
encoder = Dense(hidden_dim, activation="relu")(encoder)
decoder = Dense(hidden_dim, activation='tanh')(encoder)
decoder = Dense(input_dim, activation='relu')(decoder)
autoencoder = Model(inputs=input_layer, outputs=decoder)
тренироваться
Мы обучим модель и сохраним ее в указанный файл. Хранение обученных моделей — отличный способ сэкономить время для будущего анализа.
autoencoder.compile(metrics=['accuracy'],
loss='mean_squared_error',
optimizer='adam')
cp = ModelCheckpoint(filepath="autoencoder_classifier.h5",
save_best_only=True,
verbose=0)
tb = TensorBoard(log_dir='./logs',
histogram_freq=0,
write_graph=True,
write_images=True)
history = autoencoder.fit(df_train_0_x_rescaled, df_train_0_x_rescaled,
epochs=nb_epoch,
batch_size=batch_size,
shuffle=True,
validation_data=(df_valid_0_x_rescaled, df_valid_0_x_rescaled),
verbose=1,
callbacks=[cp, tb]).history
Классификатор
Далее мы покажем, как мы можем использовать ошибку реконструкции автоэнкодера для редких событий для классификации.
Как упоминалось ранее, если ошибка реконструкции высока, мы будем считать это переломом. Нам нужно установить порог.
Мы используем набор проверки, чтобы установить порог.
valid_x_predictions = autoencoder.predict(df_valid_x_rescaled)
mse = np.mean(np.power(df_valid_x_rescaled - valid_x_predictions, 2), axis=1)
error_df = pd.DataFrame({'Reconstruction_error': mse,
'True_class': df_valid['y']})
precision_rt, recall_rt, threshold_rt = precision_recall_curve(error_df.True_class, error_df.Reconstruction_error)
plt.plot(threshold_rt, precision_rt[1:], label="Precision",linewidth=5)
plt.plot(threshold_rt, recall_rt[1:], label="Recall",linewidth=5)
plt.title('Precision and recall for different threshold values')
plt.xlabel('Threshold')
plt.ylabel('Precision/Recall')
plt.legend()
plt.show()
Теперь мы будем классифицировать тестовые данные.
Мы не должны оценивать пороги классификации на основе тестовых данных. Это может привести к переоснащению.
test_x_predictions = autoencoder.predict(df_test_x_rescaled)
mse = np.mean(np.power(df_test_x_rescaled - test_x_predictions, 2), axis=1)
error_df_test = pd.DataFrame({'Reconstruction_error': mse,
'True_class': df_test['y']})
error_df_test = error_df_test.reset_index()
threshold_fixed = 0.85
groups = error_df_test.groupby('True_class')
fig, ax = plt.subplots()
for name, group in groups:
ax.plot(group.index, group.Reconstruction_error, marker='o', ms=3.5, linestyle='',
label= "Break" if name == 1 else "Normal")
ax.hlines(threshold_fixed, ax.get_xlim()[0], ax.get_xlim()[1], colors="r", zorder=100, label='Threshold')
ax.legend()
plt.title("Reconstruction error for different classes")
plt.ylabel("Reconstruction error")
plt.xlabel("Data point index")
plt.show();
На рис. 4 оранжевые и синие точки над пороговой линией представляют истинные положительные и ложные положительные результаты соответственно. Как мы видим, у нас много ложных срабатываний. Для лучшего понимания мы используем матрицу путаницы для представления.
pred_y = [1 if e > threshold_fixed else 0 for e in error_df.Reconstruction_error.values]
conf_matrix = confusion_matrix(error_df.True_class, pred_y)
plt.figure(figsize=(12, 12))
sns.heatmap(conf_matrix, xticklabels=LABELS, yticklabels=LABELS, annot=True, fmt="d");
plt.title("Confusion matrix")
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.show()
Мы можем предсказать 9 из 32 брейков. Примечательно, что эти результаты были предсказаны на 2-4 минуты вперед. Этот показатель составляет около 28%, что уже является хорошим показателем отзыва для бумажной промышленности. Ложные срабатывания составляют примерно 6,3%. Это не идеально, но и не плохо для завода.
Модель также можно улучшить, чтобы увеличить отзыв с небольшим уровнем ложных срабатываний. Мы обсудим AUC ниже, а затем обсудим следующий метод улучшения.
Кривая ROC и AUC
false_pos_rate, true_pos_rate, thresholds = roc_curve(error_df.True_class, error_df.Reconstruction_error)
roc_auc = auc(false_pos_rate, true_pos_rate,)
plt.plot(false_pos_rate, true_pos_rate, linewidth=5, label='AUC = %0.3f'% roc_auc)
plt.plot([0,1],[0,1], linewidth=5)
plt.xlim([-0.01, 1])
plt.ylim([0, 1.01])
plt.legend(loc='lower right')
plt.title('Receiver operating characteristic curve (ROC)')
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()
Структура AUC равна 0,624.
Репозиторий на гитхабе
Код с комментариями находится вздесь.cran2367/autoencoder_classifier**Модель автоэнкодера для классификации редких событий. Внесите свой вклад в разработку cran2367/autoencoder_classifier, создав…**github.com
Что может быть лучше?
Это (многомерные) данные временного ряда. Мы не рассматривали временную информацию/паттерны в данных. Мы будемследующий твитУзнайте, можете ли вы комбинировать RNN для классификации. мы постараемсяLSTM autoencoder.
в заключении
Мы исследуем классификатор с автоматическим кодированием, работающий с двоичными данными чрезвычайно редких событий на бумажной фабрике. Мы добились приличной точности. Наша цель — продемонстрировать базовое применение автоэнкодеров в задаче классификации редких событий. Позже мы постараемся разработать другие методы, в том числе способные сочетать пространственно-временные признаки.LSTM Autoencoderдля достижения лучшего эффекта.
Следующий твит об автокодировании LSTM находится здесь.LSTM Autoencoder for rare event classification.
Цитировать
- Ranjan, C., Mustonen, M., Paynabar, K., & Pourak, K. (2018). Dataset: Rare Event Classification in Multivariate Time Series. arXiv preprint arXiv:1809.10717.
- woohoo.data science.com/blog/fraud-…
- Github repo: GitHub.com/infection2367/AU…
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.