| Class | Content |
|---|---|
| layout | post |
| title | 簡述機器學(xué)習(xí)中模型的評估方法 |
| categories | Blog |
| description | 模型評估方法主要用于對模型的泛化誤差進行評估進而選擇最優(yōu)模型,主要的方法有留出法、S折交叉驗證法、自助法 |
| keywords | 留出法 交叉驗證法 自助法,以及對應(yīng)的代碼 |
1. 前言
機器學(xué)習(xí)的模型選擇指如何從假設(shè)空間中選擇泛化能力最大的模型,增加訓(xùn)練數(shù)據(jù)集、加正則項都能有效地抑制過擬合現(xiàn)象,而在實際應(yīng)用中數(shù)據(jù)是不充足的,為了選擇最優(yōu)的模型還可以通過交叉驗證方法。
交叉驗證的思想:重復(fù)使用給定的數(shù)據(jù),把給定的數(shù)據(jù)切分為訓(xùn)練集和測試集,在此基礎(chǔ)上反復(fù)地進行訓(xùn)練、測試以及模型選擇。
當(dāng)然,如果樣本數(shù)量充足,可以隨機地把數(shù)據(jù)切分成三部分:訓(xùn)練集用來訓(xùn)練模型,驗證集用于模型選擇合調(diào)參,測試集對最終模型的評估。
2. 主要方法
1. 留出法(簡單交叉驗證)
方法:隨機將樣本分為測試集和訓(xùn)練集,然后用訓(xùn)練集訓(xùn)練模型,得到訓(xùn)練模型之后,在測試集上評價各個模型的測試誤差,再選擇測試誤差最小的模型。
Note:
a. 訓(xùn)練集和測試集的劃分盡量保持?jǐn)?shù)據(jù)分布的一致性,避免因為數(shù)據(jù)劃分過程引入額外的偏差,例如在多分類時至少保證樣本的類別比例相似,從采樣的角度來看待數(shù)據(jù)劃分,采樣方式被稱為“分層采樣”。
b. 使用留出法一般采用若干次隨機劃分、重復(fù)實驗評估取平均值,單次使用留出法結(jié)果往往不夠穩(wěn)定。
def simple_cross(item, label, k):
"""
對每類標(biāo)簽隨機抽取相同的個數(shù)構(gòu)造成測試集,樣本中剩余的數(shù)據(jù)為訓(xùn)練集,要求數(shù)據(jù)為數(shù)據(jù)框結(jié)構(gòu),且標(biāo)簽的column為"Label"
:param item: sample data
:param label:data type of list. 標(biāo)簽名稱列表,eg label=[1,2,3,4,5,6]
:param k: sample number of each label. 每類標(biāo)簽的數(shù)量
:return: train and test data
"""
label_indexs, all_indexs = {}, []
for _i in label:
label_indexs[_i] = []
for index in item.index:
label_indexs[item.ix[index, "Label"]].append(index)
for value in label_indexs.values():
all_indexs.extend(random.sample(value, k=k))
test_data = item.ix[all_indexs, ]
train_data = item.drop(all_indexs)
return train_data, test_data
2. S折交叉驗證
方法:隨機將樣本拆分成S個互不相交大小相同的子集,然后用S-1個子集作為訓(xùn)練集訓(xùn)練模型,用剩余的子集測試模型,對S中選擇重復(fù)進行,最終選出S次測評中的平均測試誤差最小的模型。
Note:
a. 這種方法用得最多,而交叉驗證評估結(jié)果的穩(wěn)定性很大程度取決于S.
b. 與留出法類似,劃分為S折存在多種方式,所以為了減小樣本劃分不同而引入的誤差,通常隨機使用不同的劃分重復(fù)P次,即為P次S折交叉驗證
def S_cross(item, S):
"""
將樣本數(shù)據(jù)分為K-折,再將訓(xùn)練集和測試集組合成k組返回.train_test為list類型以元組形式表示
例如[(test1,train1),(test2,train2),(test3,train),(test4.train4)],注意獲取S組訓(xùn)練集和測試集
:param item: sample data
:return: S-折 train and test data
"""
item = shuffle(item)
k = math.floor(len(item) / S)
train_test = []
item_indexs = [item.index[i:i + k, ] for i in range(0, len(item.index)-k, k)]
for test_index in item_indexs:
train_test.append((item.loc[test_index], item.drop(test_index)))
return train_test
3. 留一法
方法:它是S折交叉驗證的特殊情況,S=N,其中N為數(shù)據(jù)容量,劃分樣本方式唯一。
注:
a. 數(shù)據(jù)缺乏時使用,當(dāng)數(shù)據(jù)集很大時,計算開銷很大。
b. 由于測試集只有一個樣本,所以模型因樣本規(guī)模不同而導(dǎo)致的估計偏差比前兩種小。
4. 自助法
方法:以自助采樣為基礎(chǔ),對m個樣本數(shù)據(jù)隨機挑選1個,放回后再隨機挑選1個,重復(fù)m次,這樣得到了與樣本規(guī)模一樣大小的訓(xùn)練集,測試集中有一部分樣本多次出現(xiàn),有一部分樣本不出現(xiàn),可以做一個簡單估計,樣本在m次采樣中始終沒有被采樣的,即大約36.8%的樣本未出現(xiàn)在訓(xùn)練集中,未出現(xiàn)在訓(xùn)練集中的樣本組合成測試集。
Note:
a. 自助法在數(shù)據(jù)較小,難以劃分測試集和訓(xùn)練集時有用,從初始數(shù)據(jù)集中產(chǎn)生多個不同的訓(xùn)練集,這對集成學(xué)習(xí)等方法有很多好處。
b.缺點:自助法產(chǎn)生的數(shù)據(jù)集改變了初始數(shù)據(jù)集的分布,引入估計誤差。
def bootstraping(item):
"""
自助法采樣.對數(shù)據(jù)進行M=len(item.index)有放回采樣.最后得到M個訓(xùn)練集,未被采樣到的作為測試集
:param item:sample data
:return:訓(xùn)練集和測試集
"""
train_indexs = np.random.choice(item.index, size=len(item.index), replace=True)
train_data = item.loc[train_indexs, ]
test_data = item.drop(list(set(item.index) - set(train_indexs)))
return train_data, test_data
總結(jié)
劃分訓(xùn)練集和測試是機器學(xué)習(xí)的基礎(chǔ),在這些劃分方法中最常用的就是S折交叉驗證,為了以后使用方便,我附帶了實現(xiàn)函數(shù).
如有疑問,聯(lián)系dengwenjun818@gmail.com