如何Keras自動編碼器給極端罕見事件分類

2021-01-09 讀芯術

全文共7940字,預計學習時長30分鐘或更長

來源:Pexels

本文將以一家造紙廠的生產為例,介紹如何使用自動編碼器構建罕見事件分類器。

現實生活中罕見事件的數據集

背景

1. 什麼是極端罕見事件?

在罕見事件問題中,數據集是不平衡的。也就是說,正樣本比負樣本數量少。典型罕見事件問題的正樣本數約佔總數的5-10%。而在極端罕見的事件問題中,正樣本數據只有不到1%。例如,本文使用的數據集裡,這一比例只有約0.6%。

這種極端罕見的事件問題在現實世界中非常常見,例如,工廠中的機器故障或在網上點擊購買時頁面失蹤。

對這些罕見事件進行分類非常有挑戰性。近來,深度學習被廣泛應用於分類中。然而正樣本數太少不利於深度學習的應用。不論數據總量多大,深度學習的使用都會受制於陽性數據的數量。

2. 為什麼要使用深度學習?

這個問題很合理。為什麼不考慮使用其他機器學習方法呢?

答案很主觀。我們總是可以採用某種機器學習方法來達到目的。為了使其成功,可以對負樣本數據進行欠採樣,以獲得接近更平衡的數據集。由於只有0.6%的正樣本數據,欠採樣將會導致數據集大小約為原始數據集的1%。機器學習方法如SVM或Random Forest仍然適用於這種大小的數據集。然而,其準確性將受到限制。剩下約99%的數據中的信息將無法使用。

如果數據足夠的話,深度學習或許更有效。它還能通過使用不同的體系結構實現模型改進的靈活性。因此,我們選擇嘗試使用深度學習的方法。

在本文中,我們將學習如何使用一個簡單的全連接層自動編碼器來構建罕見事件分類器。本文是為了演示如何使用自動編碼器來實現極端罕見事件分類器的構建。用戶可以自行探索自動編碼器的不同架構和配置。

用自動編碼器進行分類

用自動編碼器分類類似於異常檢測。在異常檢測中,先學習正常過程的模式。任何不遵循此模式的都被歸類為異常。對於罕見事件的二進位分類,可以採用類似的方法使用自動編碼器。

1. 什麼是自動編碼器?

· 自動編碼器由編碼器和解碼器兩個模塊組成。

· 編碼器學習某一進程的隱含特性。這些特性通常在一個降低的維度中。

· 解碼器可以根據這些隱含特性重新創建原始數據。

圖1解釋自動編碼器[資料來源: iSystems Design實驗室SeungchulLee教授]

2. 如何使用自動編碼器構建罕見事件分類?

· 將數據分為正標記和負標記兩部分。

· 負標記的數據視為正常狀態——無事件。

· 忽略正標記的數據,用負標記數據訓練自動編碼器。

· 所以重構誤差的概率就很小。

· 然而,如果試圖從稀有事件中重構數據,自動編碼器就很難工作。

· 這就會造成在罕見事件中發生重構誤差的概率比較高。

· 如此高的重構誤差,並將其標記為罕見事件預測。

· 此過程與異常檢測方法類似。

實際應用

1. 數據和問題

這是來自一家造紙廠關於紙張破損的二進位標記數據。紙張破損在造紙業是個很嚴重的問題。一起紙張破損就會造成數千美元損失,而造紙廠每天都會有數幾起破損。這導致每年數百萬美元的損失和工作風險。

因為生產過程本身的性質,很難檢測到紙張破損。破損概率降低5%都能給廠家帶來巨大的利益。

我們的數據包含15天內收集的約18,000行數據。y列包含兩類標籤,1表示紙張破損。其餘列是預測,正標記樣本約124例(約0.6%)。

2. 編碼

導入所需的庫。

%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"]

注意,我們正在為可重現結果設置隨機種子。

3. 數據處理

現在,讀取並準備數據。

df = pd.read_csv("data/processminer-rare-event-mts - data.csv")這個罕見事件問題的目標就是在紙張破損發生之前就及時做出預測。我們試著在破損發生前四分鐘就要預測到。為了建立這個模型,把標籤向上移動兩行(相當於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):

'''

This function will shift the binary labels in a dataframe.

The curve shift will be with respect to the 1s.

For example, if shift is -2, the following process

will happen: if row n is labeled as 1, then

- Make row (n+shift_by):(n+shift_by-1) = 1.

- Remove row n.

i.e. the labels will be shifted up to 2 rows up.

Inputs:

df A pandas dataframe with a binary labeled column.

This labeled column should be named as 'y'.

shift_by An integer denoting the number of rows to shift.

Output

df A dataframe with the binary labels shifted by shift.

'''

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'

# Add vector to the df

df.insert(loc=0, column=labelcol+'tmp', value=vector)

# Remove the rows with labelcol == 1.

df = df.drop(df[df[labelcol] == 1].index)

# Drop labelcol and rename the tmp col as labelcol

df = df.drop(labelcol, axis=1)

df = df.rename(columns={labelcol+'tmp': labelcol})

# Make the labelcol binary

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)

4. 標準化

自動編碼器最好使用標準化數據(轉換為Gaussian、均值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))

由自動編碼器構造的分類器

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)

2. 訓練

訓練模型並將其保存在文件中。保存訓練過的模型會為將來的分析省很多時間。

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

圖2:自動編碼器的損失曲線

3. 分類

接下來將展示如何利用自動編碼器重構誤差來構造罕見事件分類器。

如前所述,如果重構誤差較大,將其歸類為紙張破損。需要確定這個閾值。

使用驗證集來確定閾值。

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()

圖3:閾值為0.85可以在精確度和召回率之間有合理權衡。

現在,對測試數據進行分類。

不要根據測試數據來估計分類閾值,這會導致過度擬合。

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:使用閾值= 0.85進行分類。閾值線上方的橙色和藍色圓點分別表示真陽性和假陽性。

圖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()

圖5:測試預測的混淆矩陣

在32次的破損中,我們預測到了9次。注意,其中包括提前兩或四分鐘的預測。這一概率約為28%,對造紙業來說是一個不錯的召回率。假陽性率約為6.3%。這對造紙廠來說不是最好的結果,但也不壞。

該模型還可以進一步改進,降低假陽性率以提高召回率。觀察如下AUC值後探討改進方法。

ROC曲線和AUC(Area Under Curve)

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。

值得注意的是,這是一個(多變量的)時間序列數據。我們並未考慮數據中的時間信息/模式。

留言 點讚 關注

我們一起分享AI學習與發展的乾貨

歡迎關注全平臺AI垂類自媒體 「讀芯術」

相關焦點

  • 利用深度變體自動編碼器改進宏基因組的組裝
    利用深度變體自動編碼器改進宏基因組的組裝 作者:小柯機器人 發布時間:2021/1/5 16:19:03 丹麥哥本哈根大學Simon Rasmussen課題組的最新研究利用深度變體自動編碼器改進了宏基因組的組裝。
  • 代碼詳解:一文讀懂自動編碼器的前世今生
    全文共5718字,預計學習時長20分鐘或更長變分自動編碼器(VAE)可以說是最實用的自動編碼器,但是在討論VAE之前,還必須了解一下用於數據壓縮或去噪的傳統自動編碼器。變分自動編碼器的厲害之處假設你正在開發一款開放性世界端遊,且遊戲裡的景觀設定相當複雜。
  • 用TensorFlow和Keras構建卷積神經網絡
    本文主要介紹如何在Python中使用TensorFlow和Keras構建卷積神經網絡。 卷積神經網絡是過去十年中深度學習成為一大熱點的部分原因。今天將使用TensorFlow的eager API來訓練圖像分類器,以辨別圖像內容是狗還是貓。人工神經網絡在許多領域都展現出了其強大功能,最近已經應用到很多行業中。
  • 對鳶尾花識別之Keras
    *第三方庫numpypandassklearnkeras處理鳶尾花數據集了解數據集鳶尾花數據集是一個經典的機器學習數據集,非常適合用來入門 One-Hot編碼是分類變量作為二進位向量的表示。這首先要求將分類值映射到整數值。然後,每個整數值被表示為二進位向量,除了整數的索引之外,它都是零值,它被標記為1。 One-Hot編碼是將類別變量轉換為機器學習算法易於利用的一種形式的過程。
  • 使用Keras構建深度圖像搜尋引擎
    我們如何建立一個系統,能夠找到這些圖像的子集來更好地回答用戶的搜索查詢?我們基本上需要的是一個搜尋引擎,它能夠根據圖像與搜索查詢的對應程度對圖像結果進行排序,可以用一種自然語言表示,,也可以用其他查詢圖像表示。
  • Keras官方中文版文檔正式發布了
    Keras 官方文檔:https://keras.io/zh/Keras 第三方文檔:http://keras-cn.readthedocs.io/en/latest/以下我們將簡要介紹這次官方發布的 Keras 文檔。
  • 二分類、多分類、回歸任務,一個項目get競賽必備模型
    近日,有開發者在 GitHub 上開源了一個包含數據挖掘類比賽常用模型的項目,主要涵蓋二分類、多分類以及回歸任務。項目代碼全部使用 Python 實現。項目地址:https://github.com/QLMX/data_mining_models該項目包含二分類模型、多分類模型以及回歸模型,它們分別基於 lightgbm 實現、xgboost 實現、keras 實現和 pytorch 實現:lightgbmbinary_class.py :lightgbm
  • 如何在Keras中自定義機器學習性能指標
    在本教程中,我們不會深入探討每一個指標或何時使用它,我們將使用Keras構建幾個簡單的自定義指標,以進行二元分類。請始終參考下面的混淆矩陣以了解其餘內容。import keras.backend as K精度(Precision)我們需要記住,y_true和y_pred的操作不是NumPy數組,而是Theano或Tensorflow張量。這就是為什麼我們將Keras後端提供的操作用於指標的原因。
  • 通過Keras 構建基於 LSTM 模型的故事生成器
    from tensorflow.keras.preprocessing.sequence import pad_sequencesfrom tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout, Bidirectionalfrom tensorflow.keras.preprocessing.text
  • MXNet開放支持Keras,高效實現CNN與RNN的分布式訓練
    用 Keras 2 和 MXNet 進行分布式訓練本文介紹了如何安裝 Keras-MXNet,以及如何訓練 CNN 和 RNN。如果你以前使用過其它深度學習引擎進行分布式訓練,那你可能了解其中的難度和無趣。本文將展示如何使用 Keras-MXNet 進行訓練。安裝僅需幾步1. 部署 AWS 深度學習 AMI2.
  • 在Keras中可視化LSTM
    有沒有想過是否有可能看到每個單元如何對最終輸出做出貢獻。我很好奇,試圖將其可視化。在滿足我好奇的神經元的同時,我偶然發現了Andrej Karpathy的博客,名為「循環神經網絡的不合理有效性」。如果你想獲得更深入的解釋,建議你瀏覽他的博客。在本文中,我們不僅將在Keras中構建文本生成模型,還將可視化生成文本時某些單元格正在查看的內容。
  • 手把手教程:如何從零開始訓練 TF 模型並在安卓系統上運行
    我將以 MNIST 數據為例介紹圖像分類,並分享一些你可能會面臨的常見問題。本教程著重於端到端的體驗,我不會深入探討各種 tf.Keras API 或 Android 開發。下載我的示例代碼並執行以下操作:
  • MXNet 宣布支持 Keras 2,可更加方便快捷地實現 CNN 及 RNN 分布式...
    用 Keras 2 和 MXNet 做分布式訓練本文介紹如何安裝 Keras-MXNet 並演示如何訓練 CNN 和 RNN。如果您之前嘗試過使用其他深度學習引擎做分布式訓練,那麼您應該知道這過程可能很乏味而且很困難。現在,讓我們看看用 Keras-MXNet  訓練會怎樣。
  • 機器翻譯:谷歌翻譯是如何對幾乎所有語言進行翻譯的?
    全文共13204字,預計學習時長34分鐘谷歌翻譯大家想必都不陌生,但你有沒有想過,它究竟是如何將幾乎所有的已知語言翻譯成我們所選擇的語言?本文將解開這個謎團,並且向各位展示如何用長短期記憶網絡(LSTM)構建語言翻譯程序。
  • 快速訓練殘差網絡 ResNet-101,完成圖像分類與預測,精度高達 98%|...
    以我們的圖像分類任務為例:假如任務A的任務是貓狗分類,任務B是要對老虎、獅子進行分類。可以發現,任務 A 和任務 B 存在大量的共享知識,比如這些動物都可以從毛髮,體型,形態等方面進行辨別。因此在已經存在一個針對任務A訓練好的模型前提下,在訓練任務B的模型時,我們可以不從零開始訓練,而是基於在任務 A 上獲得的知識再進行訓練。
  • TensorFlow 2.1指南:keras模式、渴望模式和圖形模式(附代碼)
    Keras模式import numpy as npimport tensorflow as tffrom tensorflow import kerasfrom tensorflow.keras.layers import Input, Dense, Flatten, Conv2Dfrom tensorflow.keras
  • 光柵編碼器如何影響音圈電機精度?
    光柵編碼器如何影響音圈電機精度?對於經常使用的光柵尺,我們通常關注以下技術規格:1、光柵尺的結構:鋼帶、玻璃;2、光柵尺的信號類型:串行信號、方波信號、正弦波信號(1-Vpp);3、光柵尺的解析度;4、光柵尺的信號周期、倍頻;光柵尺按照結構分類
  • 有關藝術畫作分類的 Kaggle 比賽經驗分享
    在這個項目中,我將使用遷移學習和深度學習框架Keras對kaggle數據集中的不同藝術作品圖像進行分類。  你將學到什麼!使用keras庫進行分類任務使用keras進行遷移學習數據增強使用keras的「ImageDataGenerator()」來增強數據。
  • Mini-VGG實現CIFAR10數據集分類
    概要本篇博客主要講解了CIFAR10數據集的預處理,Mini-VGG的tensorflow和keras實現,並實現了CIFAR數據集的分類。32,那麼使用VGG16來實現CIFAR10數據集的分類任務,那麼CIFAR10數據集的圖像在經過VGG16的卷積模塊作用下提取得到特徵維度為1 * 1 * 1024。
  • 基於RTX2060構建TensorFlow-gpu(keras)學習平臺
    開始菜單運行anaconda navigator檢查是否安裝了notebook(默認有安裝)三、安裝tensorflow/keras在激活的環境中安裝:1. 如果機器上有gpu,則安裝gpu版本,沒有GPU就安裝cpu版。版本問題,現在TensorFlow到了最新的2.0.0版本,但是很多函數不兼容1.**版本。