Julia 機器學習 ---- 訓練集和測試集的拆分函數

如果只有一個數據集,在機器學習的過程中,一般會將原始數據集分割爲訓練數據集和測試數據集,訓練集 用於訓練模型的子集。測試集 - 用於測試訓練後模型的子集。但要確保測試集滿足以下兩個條件:

  • 規模足夠大,可產生具有統計意義的結果。
  • 能代表整個數據集。換言之,挑選的測試集的特徵應該與訓練集的特徵相同。

在Julia中也提供了一些拆分數據集的方法,這裏給出簡單的代碼示例。

 

1、流出法

留出法(hold-out)直接將數據集D劃分爲兩個互斥的集合,其中一個集合作爲訓練集S,另一個作爲測試集T。在S上訓練出模型後,用T來評估其測試誤差,作爲對泛化誤差的估計。 需要注意的是,訓練/測試集的劃分要儘可能保持數據分佈的一致性,避免因數據劃分過程引入額外的偏差而對最終結果產生影響,常見做法是將大約2/3-4/5的樣本用於訓練,剩餘樣本用於測試。

實現方式一:

#爲“測試集”和“訓練集”,3/4 用於訓練,1/4用於測試
using Lathe.preprocess: TrainTestSplit
train, test = TrainTestSplit(df,.75)

實現方式二:

#定義一個布爾變量來將數據拆分爲訓練集和測試集
train = rand(Bernoulli(0.75), nrow(iris)) .== 1
features = collect(Matrix(iris[:, 1:4]))
#訓練數據集
features[train,:]
#測試數據集
features[.!train,:]

實現方式三:

using ScikitLearn
@sk_import model_selection: train_test_split
@sk_import datasets: load_iris

# 加載並返回鳶尾花數據集 (scikit-learn自帶的數據集)
iris = load_iris()  # 返回datasets.base.Bunch類型(字典格式)
iris["target"]
# 劃分數據集train_test_split() 第一個參數表示特徵值,第二個參數表示目標值,test_size表示測試集所佔的百分比(推薦0.25)
x_train, x_test, y_train, y_test = train_test_split(iris["data"], iris["target"], test_size=0.25)  # 劃分是按比例隨機劃分
# 返回值 x_train表示訓練集的特徵值,x_test表示測試集的特徵值,y_train表示訓練集的目標值,y_test表示測試集的目標值

2、交叉驗證法

交叉驗證法(cross validation)先將數據集D劃分爲k個大小相似的互斥子集.每個子集Di都儘可能保持數據分佈的一致性,即從D中通過分層採樣得到。然後,每次用k-1個子集的並集作爲訓練集,餘下的那個子集作爲測試集;這樣就可以獲得k組訓練/測試集,從而可進行k次訓練和測試,最終返回的是這k個 測試結果的均值。顯然,交叉驗證法評估結果的穩定性和保真性在很大程度上取決於k的取值,爲強調這一點,通常把交叉驗證法成爲"k折交叉驗證"(k-fold cross validation).k最常用的取值是10,其他常用的k值有5 20等。

   與留出法相似,將數據集D劃分爲k個子集同樣存在多種劃分方式。爲減小因樣本劃分不同而引入的偏差,k折交叉驗證通常要隨機使用不同的劃分重複p次,最終的評估結果是這p次k折交叉驗證結果的均值,例如常見的有"10次10折交叉驗證"

  假定數據集D中包含m個樣本,若令k=m,則得到了交叉驗證法的一個特例:留一法(Leave One Out).顯然,留一法不受隨機樣本劃分方式的影響。因爲m個樣本只有唯一的方式劃分爲m個子集(每個子集包含一個樣本);留一法中被實際評估的模型與期望評估的用D訓練出的模型很相似。因此,留一法的評估結果往往被認爲比較準確。然而 留一法也有其缺陷:在數據集比較大時,訓練m個模型的計算開銷可能時難以忍受的(例如數據集包含1百萬個樣本,則需要訓練1百萬個模型),而這還是在未考慮算法調參的情況下。另外,留一法的估計結果也未必永遠比其他評估方法準確;“沒有免費的午餐”定義對實驗評估方法同樣使用。

實現方式一:

Julia原生的函數中,MLBase庫有一個Kfold函數,可以用於交叉驗證,這裏給出部分僞代碼:

function cross_validation(train,k, learn)
    a = collect(Kfold(size(train)[1], k))
    for i in 1:k
        row = a[i]
        temp_train = train[row,:]
        temp_test = train[setdiff(1:end, row),:]
        #機器學習的函數learn 具體執行邏輯
    end
end

詳細的實現可以參考:交叉驗證示例

實現方式二:

using ScikitLearn
using PyCall

@sk_import model_selection  : cross_val_score
@sk_import datasets: load_iris
@sk_import svm: SVC

#加載並返回鳶尾花數據集 (scikit-learn自帶的數據集)
iris = load_iris()  # 返回
svc = SVC(kernel="linear", C=1)
scores = cross_val_score(svc, iris["data"], iris["target"], cv=5)
# 5-element Array{Float64,1}:
#  0.9666666666666667
#  1.0
#  0.9666666666666667
#  0.9666666666666667
#  1.0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章