文章目錄
- 一. 為什么要劃分數據集
- 二. 數據集劃分的方法
- 1. 留出法:
- 2. 交叉驗證:將數據集劃分為訓練集,驗證集,測試集
- 3. 留一法:
- 4. 自助法:
一. 為什么要劃分數據集
為了能夠評估模型的泛化能力,可以通過實驗測試對學習器的泛化能力進行評估,進而做出選擇。因此需要使用一個 “測試集” 來測試學習器對新樣本的判別能力,以測試集上的 “測試誤差” 作為泛化誤差的近似。
一般測試集滿足:
- 能代表整個數據集
- 測試集與訓練集互斥
- 測試集與訓練集建議比例: 2比8、3比7 等
二. 數據集劃分的方法
1. 留出法:
將數據集劃分成兩個互斥的集合:訓練集,測試集
● 訓練集用于模型訓練
● 測試集用于模型驗證
● 也稱之為簡單交叉驗證
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris#加載數據集
x,y = load_iris(return_X_y=True)
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
#留出法(隨機分割)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0)
Counter(y_train), Counter(y_test)
(Counter({2: 44, 0: 39, 1: 37}), Counter({1: 13, 0: 11, 2: 6}))
#留出法(分層分割)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0,stratify=y)
Counter(y_train), Counter(y_test)
(Counter({0: 40, 1: 40, 2: 40}), Counter({0: 10, 1: 10, 2: 10}))
# 多次劃分(隨機分割)
spliter = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
for train,test in spliter.split(x,y):print('隨機多次分割:', Counter(y[test]))
隨機多次分割: Counter({1: 13, 0: 11, 2: 6})
隨機多次分割: Counter({1: 12, 2: 10, 0: 8})
隨機多次分割: Counter({1: 11, 0: 10, 2: 9})
隨機多次分割: Counter({2: 14, 1: 9, 0: 7})
隨機多次分割: Counter({2: 13, 0: 12, 1: 5})
# 多次劃分(分層分割)
spliter = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
for train,test in spliter.split(x,y):print('隨機多次分割:', Counter(y[test]))
隨機多次分割: Counter({0: 10, 1: 10, 2: 10})
隨機多次分割: Counter({2: 10, 0: 10, 1: 10})
隨機多次分割: Counter({0: 10, 1: 10, 2: 10})
隨機多次分割: Counter({1: 10, 2: 10, 0: 10})
隨機多次分割: Counter({1: 10, 2: 10, 0: 10})
2. 交叉驗證:將數據集劃分為訓練集,驗證集,測試集
K-Fold交叉驗證,將數據隨機且均勻地分成k分,如上圖所示(k為10),假設每份數據的標號為0-9
● 第一次使用標號為0-8的共9份數據來做訓練,而使用標號為9的這一份數據來進行測試,得到一個準確率
● 第二次使用標記為1-9的共9份數據進行訓練,而使用標號為0的這份數據進行測試,得到第二個準確率
● 以此類推,每次使用9份數據作為訓練,而使用剩下的一份數據進行測試
● 共進行10次訓練,最后模型的準確率為10次準確率的平均值
● 這樣可以避免了數據劃分而造成的評估不準確的問題
● 訓練集用于模型訓練
● 驗證集用于參數調整
● 測試集用于模型驗證
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from sklearn.datasets import load_iris
from collections import Counterfrom sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris#加載數據集
x,y = load_iris(return_X_y=True)
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
#隨機交叉驗證
spliter = KFold(n_splits=5, shuffle=True, random_state=0)
for tain,test in spliter.split(x,y):print('隨機交叉驗證:', Counter(y[test]))
隨機交叉驗證: Counter({1: 13, 0: 11, 2: 6})
隨機交叉驗證: Counter({2: 15, 1: 10, 0: 5})
隨機交叉驗證: Counter({0: 10, 1: 10, 2: 10})
隨機交叉驗證: Counter({0: 14, 2: 10, 1: 6})
隨機交叉驗證: Counter({1: 11, 0: 10, 2: 9})
#分層交叉驗證
spliter = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
for tain,test in spliter.split(x,y):print('隨機交叉驗證:', Counter(y[test]))
隨機交叉驗證: Counter({0: 10, 1: 10, 2: 10})
隨機交叉驗證: Counter({0: 10, 1: 10, 2: 10})
隨機交叉驗證: Counter({0: 10, 1: 10, 2: 10})
隨機交叉驗證: Counter({0: 10, 1: 10, 2: 10})
隨機交叉驗證: Counter({0: 10, 1: 10, 2: 10})
KFold:
劃分方式
:每一折的數據都是從整個數據集中均勻劃分的。例如,5 折交叉驗證意味著數據集被劃分成 5 個子集,每次驗證時選擇其中一個子集作為測試集,其余 4 個子集作為訓練集。每個樣本都會被用作一次驗證集。
沒有重復樣本:每個樣本僅會出現在一個折(訓練集或驗證集)中,不會有重復。
ShuffleSplit:
劃分方式
:ShuffleSplit 每次都會隨機選擇訓練集和測試集,且訓練集和測試集可能會有所重疊,也就是說,某些樣本可能會出現在不同的劃分中。
重復樣本:允許樣本在不同的劃分中重復出現,因此數據集的某些樣本在某次劃分中可能作為訓練集,而在另一劃分中作為測試集。
3. 留一法:
每次從訓練數據中抽取一條數據作為測試集
from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import LeavePOut
from sklearn.datasets import load_iris
from collections import Counter#加載數據集
x,y = load_iris(return_X_y=True)
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
#留一法
spliter = LeaveOneOut()
for train,test in spliter.split(x,y):print('訓練集:', len(train), '測試集:', len(test), test)
#留p法
spliter = LeavePOut(p=2)
for train,test in spliter.split(x,y):print('訓練集:', len(train), '測試集:', len(test), test)
4. 自助法:
以自助采樣(可重復采樣、有放回采樣)為基礎
每次隨機從D中抽出一個樣本,將其拷貝放入D,然后再將該樣本放回初始數據集D中,使得該樣本在下次采樣時仍有可能被抽到;
這個過程重復執行m次后,我們就得到了包含m個樣本的數據集D′,這就是自助采樣的結果。
● 在數據集D中隨機抽取m個樣本作為訓練集
● 沒被隨機抽取到的D-m條數據作為測試集
import pandas as pd# 1. 構造數據集
data = [[90, 2, 10, 40],[60, 4, 15, 45],[75, 3, 13, 46],[78, 2, 64, 22]]data = pd.DataFrame(data)
data
# 2. 產生訓練集
'''
這行代碼的作用是從 data 數據集中進行有放回的隨機抽樣,抽樣比例為 100%(即 frac=1)。這意味著每次抽樣后,數據點會被放回數據集中,因此某些數據點可能會被多次抽樣到,而有些數據點可能一次也不會被抽樣到。具體來說:frac=1 表示抽樣的比例為 100%,即抽取的數據量與原數據集相同。
replace=True 表示抽樣是有放回的,即每次抽樣后數據點會被放回數據集中,允許重復抽樣。
這樣做的結果是生成一個與原數據集大小相同的新數據集 train,其中可能包含重復的數據點。
'''
train = data.sample(frac=1, replace=True,random_state=0)
print('訓練集:\n', train)print('*' * 30)# 3. 產生測試集
test = data.loc[data.index.difference(train.index)]
print('測試集:\n', test)