训练集与测试集数据分布不一致
簡介
數(shù)據(jù)質(zhì)量的高低是決定使用機(jī)器學(xué)習(xí)算法獲得預(yù)測結(jié)果質(zhì)量高低的重要因素,在很多常見任務(wù)中,數(shù)據(jù)質(zhì)量的作用遠(yuǎn)大于模型的作用,本文討論數(shù)據(jù)預(yù)處理時(shí)會(huì)遇到的一個(gè)常見問題:訓(xùn)練集與測試集數(shù)據(jù)分布不一致。
什么是訓(xùn)練集與測試集數(shù)據(jù)分布不一致?
一個(gè)具體的例子,比如我現(xiàn)在要預(yù)測泰坦尼克號(hào)乘客存活率(Kaggle 上的經(jīng)典題,已經(jīng)被各路選手將準(zhǔn)確率刷爆了),如果訓(xùn)練集的輸入特征中,“性別” 這一特征多數(shù)是男性,而在測試集里,“性別” 這一特征多數(shù)是女性,這便是訓(xùn)練集與測試集上,某特征其數(shù)據(jù)分布不均。
訓(xùn)練集和測試集分布不一致也被稱作數(shù)據(jù)集偏移 (Dataset Shift),導(dǎo)致這種問題有兩個(gè)常見原因:
樣本選擇偏差 (Sample Selection Bias): 訓(xùn)練集是通過有偏方法得到的,例如非均勻選擇 (Non-uniform Selection),導(dǎo)致訓(xùn)練集無法很好表征的真實(shí)樣本空間。
環(huán)境不平穩(wěn) (Non-stationary Environments): 當(dāng)訓(xùn)練集數(shù)據(jù)的采集環(huán)境跟測試集不一致時(shí)會(huì)出現(xiàn)該問題,一般是由于時(shí)間或空間的改變引起的。
先討論樣本選擇偏差,在有監(jiān)督學(xué)習(xí)里,樣本會(huì)分為特征數(shù)據(jù) (feature) 與目標(biāo)變量 (label),樣本選擇偏差也會(huì)分分為兩種情況:
沒有考慮數(shù)據(jù)中不同特征的分布問題,如前面舉例的預(yù)測泰坦尼克號(hào)乘客存活率問題,訓(xùn)練集的性別特征中,男性比例大,而測試集的性別特征中,女性比例大。
沒有考慮數(shù)據(jù)中目標(biāo)變量分布問題,從而會(huì)出現(xiàn):訓(xùn)練集類別 A 數(shù)據(jù)量遠(yuǎn)多于類別 B,而測試集相反的情況。
樣本選擇偏差會(huì)導(dǎo)致訓(xùn)練好的模型在測試集上魯棒性很差,因?yàn)橛?xùn)練集沒有很好覆蓋整個(gè)樣本空間。
接著討論環(huán)境不平穩(wěn)帶來的數(shù)據(jù)偏移,最典型的就是在時(shí)序數(shù)據(jù)中,用歷史時(shí)序數(shù)據(jù)預(yù)測未來時(shí)序,未來突發(fā)事件很可能帶來時(shí)序的不穩(wěn)定表現(xiàn),這便帶來了分布差異。
環(huán)境因素不僅限于時(shí)間和空間,還有數(shù)據(jù)采集設(shè)備、標(biāo)注人員等。
校驗(yàn)數(shù)據(jù)分布
如何判斷訓(xùn)練集與測試集數(shù)據(jù)分布是否不一致呢?
通常使用核密度估計(jì) (kernel density estimation, KDE) 分布圖和 KS 校驗(yàn)這兩種方法來判斷。
KDE 分布圖
在討論 KDE 分布圖之前,先考慮一下使用概率密度直方圖來判斷數(shù)據(jù)分布的問題。
概率密度直方圖是用數(shù)據(jù)集中不同數(shù)據(jù)出現(xiàn)的次數(shù)來表示其概率,需注意這種假設(shè)不一定成立。
要對(duì)比訓(xùn)練集和測試集數(shù)據(jù)的分布,我們可以通過繪制相應(yīng)的概率密度直方圖,然后直觀的判斷直方圖的差異,但通過直方圖判斷數(shù)據(jù)分布的會(huì)有兩個(gè)缺陷:
1. 受 bin 寬度影響大
2. 不平滑
而 KDE 分布圖相比于直方圖,它受 bin 影響更小,繪圖呈現(xiàn)更平滑,易于對(duì)比數(shù)據(jù)分布,下圖便是直方圖和核密度估計(jì)的一個(gè)對(duì)比:
在進(jìn)一步討論 KDE 前,先討論一下核函數(shù),核函數(shù)定義一個(gè)用于生成 PDF (概率分布函數(shù),Probability Distribution Function) 的曲線,不同于將值放入離散 bins 中,核函數(shù)對(duì)每個(gè)樣本值都創(chuàng)建一個(gè)獨(dú)立的概率密度曲線,然后加和這些平滑曲線,最終得到一個(gè)平滑連續(xù)的概率分布曲線。
“核” 在不同的語境下的含義是不同的,在 “非參數(shù)估計(jì)”(即不知道數(shù)據(jù)分布情況) 的語境下,“核” 是一個(gè)函數(shù),用來提供權(quán)重。例如高斯函數(shù) (Gaussian) 就是一個(gè)常用的核函數(shù)。
KDE 在數(shù)學(xué)上還有挺多細(xì)節(jié),但在實(shí)現(xiàn)上,通過 seaborn 庫便可以輕松實(shí)現(xiàn),代碼如下:
import?numpy?as?np import?seaborn?as?sns import?matplotlib.pyplot?as?plt#?創(chuàng)建樣例特征 train_mean,?train_cov?=?[0,?2],?[(1,?.5),?(.5,?1)] test_mean,?test_cov?=?[0,?.5],?[(1,?1),?(.6,?1)] #??np.random.multivariate_normal?從多變量正態(tài)分布中隨機(jī)抽取樣本 #?多正態(tài)分布是一維正態(tài)分布向高維的推廣。這樣的分布是由它的平均值和協(xié)方差矩陣來確定的。 #?這些參數(shù)類似于一維正態(tài)分布的均值(平均或“中心”)和方差(標(biāo)準(zhǔn)差或“寬度”的平方)。 train_feat,?_?=?np.random.multivariate_normal(train_mean,?train_cov,?size=50).T test_feat,?_?=?np.random.multivariate_normal(test_mean,?test_cov,?size=50).T#?繪KDE對(duì)比分布 sns.kdeplot(train_feat,?shade?=?True,?color='r',?label?=?'train') sns.kdeplot(test_feat,?shade?=?True,?color='b',?label?=?'test') plt.xlabel('Feature') plt.legend() plt.show()注意,上述代碼中,train_feat 參數(shù)是一維的(即單獨(dú)某個(gè)特征的分布,多個(gè)多特征,需要繪制多個(gè)KDE分布圖)。效果如圖所示:
從上圖可知,訓(xùn)練集與測試集分布差異不大,可以繼續(xù)模型訓(xùn)練等操作,如果分布差異較大,比如下圖這種,就需要對(duì)原始數(shù)據(jù)進(jìn)行處理了。
KS 檢驗(yàn)
KDE 是使用 PDF 來對(duì)比,而 KS 檢驗(yàn)是基于 CDF (累計(jì)分布函數(shù) Cumulative Distribution Function) 來檢驗(yàn)兩個(gè)數(shù)據(jù)分布是否一致,它也是非參數(shù)檢驗(yàn)方法。
KS 檢驗(yàn)是基于累計(jì)分布函數(shù),用于檢驗(yàn)一個(gè)分布是否符合某種理論分布或比較兩個(gè)經(jīng)驗(yàn)分布是否有顯著差異。
KS 檢驗(yàn)一般返回兩個(gè)值:
第一個(gè)值表示兩個(gè)分布之間的最大距離,值越小即這兩個(gè)分布的差距越小,分布也就越一致。
第二個(gè)值是 p 值,用來判定假設(shè)檢驗(yàn)結(jié)果的一個(gè)參數(shù),p 值越大,越不能拒絕原假設(shè)(待檢驗(yàn)的兩個(gè)分布是同分布),即兩個(gè)分布越是同分布。
通過 scipy 庫可以快速實(shí)現(xiàn) KS 檢驗(yàn),代碼如下:
from?traceback?import?print_tb import?numpy?as?np from?scipy?import?statstrain_mean,?train_cov?=?[0,?2],?[(1,?.5),?(.5,?1)] test_mean,?test_cov?=?[0,?.5],?[(1,?1),?(.6,?1)]train_feat,?_?=?np.random.multivariate_normal(train_mean,?train_cov,?size=50).T test_feat,?_?=?np.random.multivariate_normal(test_mean,?test_cov,?size=50).Tresult?=?stats.ks_2samp(train_feat,?test_feat) print(result)#?打印結(jié)果: #?KstestResult(statistic=0.18,?pvalue=0.3959398631708505)若 KS 統(tǒng)計(jì)值小且 p 值大,則可以接受 KS 檢驗(yàn)的原假設(shè),即兩個(gè)數(shù)據(jù)分布一致。
上面樣例數(shù)據(jù)的統(tǒng)計(jì)值較低,p 值大于 10% 但不是很高,因此反映分布略微不一致。如果p 值 < 0.01,建議拒絕原假設(shè),p 值越大,越傾向于原假設(shè)成立。
分類器對(duì)抗驗(yàn)證
所謂對(duì)抗驗(yàn)證,就是構(gòu)建一個(gè)分類模型去分類訓(xùn)練集和測試集,如果分類模型可以清楚的分類,則說明訓(xùn)練集和測試集的分布有明顯差異,反之分布差異不大。
分類模型可以直接使用 sklearn 中提供了幾種常見分類器來實(shí)現(xiàn),比如 SVM。
具體步驟如下:
訓(xùn)練集和測試集合并,同時(shí)新增標(biāo)簽Is_Test去標(biāo)記訓(xùn)練集樣本為 0,測試集樣本為 1。
構(gòu)建分類器 (例如?SVM、LGB、XGB 等) 去訓(xùn)練混合后的數(shù)據(jù)集 (可采用交叉驗(yàn)證的方式),擬合目標(biāo)標(biāo)簽Is_Test。
輸出交叉驗(yàn)證中最優(yōu)的 AUC 分?jǐn)?shù)。AUC 越大 (越接近 1),越說明訓(xùn)練集和測試集分布不一致。
結(jié)尾
本文的方法雖然基于訓(xùn)練數(shù)據(jù)與測試數(shù)據(jù)進(jìn)行討論,但同樣可以用于訓(xùn)練數(shù)據(jù)與預(yù)測數(shù)據(jù)的分布檢測上,在模型訓(xùn)練測試階段,我們會(huì)將已有的數(shù)據(jù)劃分為訓(xùn)練數(shù)據(jù)與測試數(shù)據(jù),當(dāng)模型通過測試后,通常會(huì)合并訓(xùn)練數(shù)據(jù)與測試數(shù)據(jù),用所有數(shù)據(jù)進(jìn)行訓(xùn)練,獲得最終的模型,然后上線使用。
如果上線后效果不好,數(shù)據(jù)分布問題依舊要考慮,通常,我們會(huì)收集線上的待預(yù)測數(shù)據(jù),將待預(yù)測數(shù)據(jù)的特征分與訓(xùn)練數(shù)據(jù)的特征分布進(jìn)行比較,依舊使用本文提及的方法,如果分布差異大,則說明,訓(xùn)練數(shù)據(jù)無法代表待預(yù)測數(shù)據(jù),當(dāng)前模型是沒有實(shí)用價(jià)值的。
數(shù)據(jù)預(yù)處理是多數(shù)機(jī)器學(xué)習(xí)任務(wù)的核心,反倒是模型,因?yàn)楹芏喑墒斓膶?shí)現(xiàn),反而不是啥大問題。最近在整理自己過去的機(jī)器學(xué)習(xí)筆記,后續(xù)會(huì)將有價(jià)值的部分輸出到公眾號(hào)中。
本文相關(guān)參考:
訓(xùn)練 / 測試集分布不一致解法總結(jié)
Python 可視化神器 Seaborn 入門系列 (一)——kdeplot 和 distplot?
密度估計(jì)(kernel density estimation)
總結(jié)
以上是生活随笔為你收集整理的训练集与测试集数据分布不一致的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模块说明模板
- 下一篇: 1100个商务企业宣传通用PPT模板免费