Julia 機器學習 --- k-折交叉驗證

目錄

k-折交叉驗證(k-fold crossValidation)

主要目的:

Julia 中代碼實現

KFold

StratifiedKFold

LOOCV(留一交叉驗證)

交叉驗證的函數


k-折交叉驗證(k-fold crossValidation)

在機器學習中,將數據集A分爲訓練集(training set)B和測試集(test set)C,在樣本量不充足的情況下,爲了充分利用數據集對算法效果進行測試。對一組n個樣本進行k-折交叉驗證,這些樣本被隨機分成k個大小几乎相同的不相交驗證集。這將生成長度約爲n*(1-1/k)的k個訓練子集,每次將其中一個包作爲測試集,剩下k-1個包作爲訓練集進行訓練.,交叉驗證法評估結果的穩定性和保真性在很大程度上取決於k的取值.k最常用的取值是10,其他常用的k值有5 20等。

主要目的:

通過多次訓練,得出偏差和方差,來衡量一個模型評估方法的好壞。

Error = Bias^2 + Variance+Noise

Bias(偏差):反映的是模型在樣本上的輸出與真實值之間的誤差,即模型本身的精準度,即算法本身的擬合能力。

Variance(方差):反映的是模型每一次輸出結果與模型輸出期望之間的誤差,即模型的穩定性。反應預測的波動情況。

Noise(噪聲):這就簡單了,就不是你想要的真正數據,你可以想象爲來破壞你實驗的元兇和造成你可能過擬合的原因之一,至於爲什麼是過擬合的原因,因爲模型過度追求Low Bias會導致訓練過度,對測試集判斷表現優秀,導致噪聲點也被擬合進去了。

Julia 中代碼實現

針對K -折差驗證,Julia  目前常用的兩個包分別是:MLBase.jl or ScikitLearn.jl,想要搞清楚拆分數據的模式,然後再看驗證方法。

KFold

劃分數據集的原理:根據n_split直接進行劃分k個子集,每個子集均做一次測試集,其餘的作爲訓練集。交叉驗證重複k次,每次選擇一個子集作爲測試集,並將k次的平均交叉驗證識別正確率作爲結果
Julia原生的函數中,MLBase庫有一個Kfold函數,可以用於交叉驗證,這裏給出部分僞代碼:

# 對於DataFrame 無法直接拆分數據集,需要使用其他方式
a = collect(Kfold(size(houses)[1], 5))
# 選用數據集
row = a[1]
houses[row,:]

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

 

StratifiedKFold

劃分數據集的原理:它是分層採樣,確保訓練集,劃分後的訓練集和驗證集中類別分佈儘量和原數據集一樣

實現方式一:

#Symbol相當於佔位符,但必須與數據的length相等 ,:b 或者:a的所佔比例對結果影響不大,但是數量都必須大於K
index_row = [i for i = 1:size(houses)[1]]
index_a = [:a for i = 1:size(houses)[1]*0.5]
index_b = [:b for i = 1:size(houses)[1]*0.5]
index = vcat(index_a,index_b)
rows = collect(StratifiedKfold(index, 10))

# 選用數據集
row = rows[1]
houses[row,:]

實現方式二:

#更傾向於選擇連續的數據,而不是隨機先擇,可能跟y 的生成方式有關
using ScikitLearn
f(i) = ifelse(i<size(houses)[1]*0.75, 1, 2)
y = [f(i) for i in 1:size(houses)[1]]
folds = ScikitLearn.CrossValidation.StratifiedKFold(y, n_folds=10)

 

LOOCV(留一交叉驗證)

留一交叉驗證是一個極端的例子,如果數據集D的大小爲N,那麼用N-1條數據進行訓練,用剩下的一條數據作爲驗證,用一條數據作爲驗證的壞處就是可能EvalEval​和EoutEout​相差很大,所以在留一交叉驗證裏,每次從D中取一組作爲驗證集,直到所有樣本都作過驗證集,共計算N次,最後對驗證誤差求平均,得到Eloocv(H,A),這種方法稱之爲留一法交叉驗證。

什麼時候使用LOOCV:LOOCV


rows = collect(LOOCV(floor(size(houses)[1])))
# 選用數據集
row = rows[1]
houses[row,:]

 

其它模式參考:折交叉驗證模式

 

交叉驗證的函數

實現方式一:

#自己寫
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 MLBase

# functions
compute_center(X::Matrix{Float64}) = vec(mean(X, 2))
compute_rmse(c::Vector{Float64}, X::Matrix{Float64}) =
    sqrt(mean(sum(abs2(X .- c),1)))

# data
const n = 200
const data = [2., 3.] .+ randn(2, n)

# cross validation
scores = cross_validate(
    inds -> compute_center(data[:, inds]),        # training function
    (c, inds) -> compute_rmse(c, data[:, inds]),  # evaluation function
    n,              # total number of samples
    Kfold(n, 5))    # cross validation plan: 5-fold

# get the mean and std of the scores
(m, s) = mean_and_std(scores)

實現方式二:

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

 

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