機器學習動手做Lesson 2 — 使用Adversarial Validation來檢查驗證資料集的分布

施威銘研究室
6 min readJun 18, 2021

--

在訓練模型的時候,我們通常會將手上的資料分成訓練資料集,以及驗證資料集。一般來說,訓練資料集跟驗證資料集的資料分布要類似,這樣我們才能透過驗證方法了解模型的效能。換個方式想,如果訓練資料跟驗證資料的資料分布完全不同,那麼即使訓練模型的過程中很順利,模型也是沒辦法對驗證資料做出好的預測。

那麼我們該如何知道訓練資料集跟驗證資料集的資料分布類似呢?今天,我們來看看Adversarial Validation如何幫我們檢查驗證資料集的分布狀況。

一、Adversarial Validation的基本想法

我們的目標是「訓練資料集跟驗證資料集的資料分布越像越好」,所謂「越像越好」的意思是「如果閉著眼睛把訓練資料跟驗證資料混在一起,然後從中間隨便抓一筆資料出來,沒辦法知道該資料原本是在訓練資料集,還是驗證資料集」。

因此,我們可以對每一筆資料新增一個變數,當資料是屬於訓練資料集時,變數值為0;反之,當資料屬於驗證資料集時,變數值為1。接著,我們把訓練資料集跟驗證資料集合併起來,當成特徵;而剛剛新增的二元變數,則作為標籤。

最後,我們用上述的特徵以及標籤,訓練一個二元分類的模型,如果模型可以順利預測標籤,代表訓練資料集跟驗證資料集有明顯的差異,所以可以視為不同的資料分布。反之,若模型預測結果很爛,代表訓練資料集跟驗證資料集太相似,根本無法區別。

二、虛擬資料集產生器

我們先定義一個可以產生虛擬資料集的function,function的輸入是資料集的大小N,輸出是具有8個特徵的資料N筆、以及對應的N個標籤。

def func_create_data(N):
e = np.random.normal(loc = 0.0, scale = 0.1, size = (N, 8))
x = np.random.normal(loc = 0.0, scale = 1.0, size = (N, 8))
y = np.zeros(N)
for index in range(len(x)):
if((x[index][0] > 1)or(x[index][1] < -1)):
y[index] = 1
return x + e, y

三、建立二元分類模型

這個範例我們使用Logistic Regression來執行二元分類,模型訓練好之後立即做預測,並且計算AUC分數。AUC接近1代表模型預測能力很好,AUC如果只是0.5左右代表模型不具有什麼預測能力。關於更多AUC分數的說明,可以參考旗標出版的「Kaggle競賽攻頂秘笈 - 揭開Grandmaster的特徵工程心法,掌握制勝的關鍵技術」。

def func_auc_score(feature, label):

model = LogisticRegression(random_state = 0).fit(feature, label)
predict = model.predict(feature)
fpr, tpr, thresholds = roc_curve(label, predict)
return auc(fpr, tpr)

四、進行Adversarial Validation

我們用兩種不同的方式來將資料分為訓練資料集,以及驗證資料集:

1、查看每一筆資料的第一個特徵,如果該值大於1,就設定Adversarial Validation時的標籤為1

2、隨機設定部分資料的Adversarial Validation時之標籤為1

很顯然方法1所分出來的訓練資料集、驗證資料集的分布並不相似,而方法2所分出來的訓練資料集、驗證資料集的分布會很相似。

為了控制兩種方式的資料集大小一致,我們會計算方法1當中,有多少資料被歸類到驗證資料集:sum(label1),因此在方法2當中,我們也會有同樣資料筆數的驗證資料集。

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
N = 1000np.random.seed(1)
x, y = func_create_data(N)
label1 = [int(row[0] > 1) for row in x]
label2 = np.concatenate((np.zeros(N — sum(label1)), np.ones(sum(label1))), axis = 0)
print("Method 1 Score:", func_auc_score(x, label1))
print("Method 2 Score:", func_auc_score(x, label2))

我們來看看程式的輸出結果:

Method 1 Score: 0.9814814814814814
Method 2 Score: 0.5

如同預期,方法2的資料分割方法,可以讓訓練資料集以及驗證資料集的資料分布幾乎相似,這也是我們期待的方法。

以後大家要訓練模型之前,記得先檢查手上的訓練資料集以及驗證資料集的分布是否符合預期喔!

重點整理

1、理想上,訓練資料集跟驗證資料集的資料分布要相似。

2、使用Adversarial Validation可以讓我們知道訓練資料集跟驗證資料集的分布是否有差異。

關於作者

Chia-Hao Li received the M.S. degree in computer science from Durham University, United Kingdom. He engages in computer algorithm, machine learning, and hardware/software codesign. He was former senior engineer in Mediatek, Taiwan. His currently research topic is the application of machine learning techniques for fault detection in the high-performance computing systems.

--

--

施威銘研究室
施威銘研究室

Written by 施威銘研究室

致力開發AI領域的圖書、創客、教具,希望培養更多的AI人才。整合各種人才,投入創客產品的開發,推廣「實作學習」,希望實踐學以致用的理想。

No responses yet