日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

训练集、验证集和测试集的比较

發(fā)布時(shí)間:2023/12/31 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 训练集、验证集和测试集的比较 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

機(jī)器學(xué)習(xí)簡單流程:

  • 使用大量和任務(wù)相關(guān)的數(shù)據(jù)集來訓(xùn)練模型;
  • 通過模型在數(shù)據(jù)集上的誤差不斷迭代訓(xùn)練模型,得到對(duì)數(shù)據(jù)集擬合合理的模型;
  • 將訓(xùn)練好調(diào)整好的模型應(yīng)用到真實(shí)的場景中;
  • ? 我們最終的目的是將訓(xùn)練好的模型部署到真實(shí)的環(huán)境中,希望訓(xùn)練好的模型能夠在真實(shí)的數(shù)據(jù)上得到好的預(yù)測效果,換句話說就是希望模型在真實(shí)數(shù)據(jù)上預(yù)測的結(jié)果誤差越小越好。我們把模型在真實(shí)環(huán)境中的誤差叫做泛化誤差,最終的目的是希望訓(xùn)練好的模型泛化誤差越低越好。

    我們希望通過某個(gè)信號(hào)來了解模型的泛化誤差,這樣就可以指導(dǎo)我們得到泛化能力更強(qiáng)的模型:

  • 使用泛化誤差本身。這是很自然的想法,我們訓(xùn)練模型的最終目的就是希望模型的泛化誤差最低,當(dāng)然可以使用泛化誤差本身來作為檢測信號(hào)。如果泛化誤差小的話還可以接受,但是通常情況下沒有那么幸運(yùn),泛化誤差可能很大,這個(gè)時(shí)候你肯定會(huì)將部署的模型撤回,重新訓(xùn)練,你可能需要部署和訓(xùn)練之間往復(fù)很多次,這種方式雖然能夠更好的指導(dǎo)我們的模型,但是成本和效率非常的差;
  • 使用模型在數(shù)據(jù)集上訓(xùn)練的擬合程度來作為評(píng)估模型的信號(hào)。但是往往我們獲取的數(shù)據(jù)集并不是完全的干凈以及有代表性,通常我們獲取到的數(shù)據(jù)集可能很少、數(shù)據(jù)的代表性不夠、包含太多的噪聲或者是被一些無關(guān)特征污染,我們獲取到的數(shù)據(jù)集或多或少都會(huì)有這些問題,那么模型對(duì)訓(xùn)練數(shù)據(jù)集的擬合程度不能指導(dǎo)泛化誤差,也就是說訓(xùn)練的時(shí)候擬合的好并不代表模型的泛化誤差就小,你甚至可以將模型在數(shù)據(jù)集上的誤差減小到0,但是因?yàn)閷?duì)模型訓(xùn)練時(shí)候的數(shù)據(jù)集往往不干凈,所以這樣的模型并不代表泛化能力就強(qiáng)。
  • 1.訓(xùn)練集與測試集

    ?

    前面說到我們既不能通過直接將泛化誤差作為了解模型泛化能力的信號(hào),因?yàn)樵诓渴瓠h(huán)境和訓(xùn)練模型之間往復(fù),代價(jià)很高,也不能使用模型對(duì)訓(xùn)練數(shù)據(jù)集的擬合程度來作為了解模型泛化能力的信號(hào),因?yàn)槲覀儷@得的數(shù)據(jù)往往不干凈。

    更好的方式就是將數(shù)據(jù)分割成兩部分:訓(xùn)練集和測試集。我們可以使用訓(xùn)練集的數(shù)據(jù)來訓(xùn)練模型,然后用測試集上的誤差作為最終模型在應(yīng)對(duì)現(xiàn)實(shí)場景中的泛化誤差。有了測試集,我們想要驗(yàn)證模型的最終效果,只需將訓(xùn)練好的模型在測試集上計(jì)算誤差,即可認(rèn)為此誤差即為泛化誤差的近似,我們只需讓我們訓(xùn)練好的模型在測試集上的誤差最小即可。

    這里有幾點(diǎn)需要注意:

  • 通常將數(shù)據(jù)集的80%作為訓(xùn)練集,20%作為測試集;
  • 通常需要在開始構(gòu)建模型之前把數(shù)據(jù)集進(jìn)行劃分,防止數(shù)據(jù)窺探偏誤,也就是說我們避免了解太多關(guān)于測試集中的樣本特點(diǎn),防止我們認(rèn)為的挑選有助于測試集數(shù)據(jù)的模型,這樣的結(jié)果會(huì)過于樂觀,但是實(shí)際上并沒有預(yù)期的那樣優(yōu)秀;
  • 通常我們在構(gòu)建模型的時(shí)候需要將數(shù)據(jù)進(jìn)行處理,包括一些數(shù)據(jù)的清洗,數(shù)據(jù)的特征縮放(標(biāo)準(zhǔn)化或者歸一化),此時(shí)我們只需要在訓(xùn)練集上進(jìn)行這些操作,然后將其在訓(xùn)練集上得到的參數(shù)應(yīng)用到測試集中,也就是說,在工作流程中,你不能使用在測試數(shù)據(jù)集上計(jì)算的得到的任何結(jié)果。比如:我們得到的屬性中可能有缺失值,因?yàn)樵谶@些操作之前,我們已經(jīng)把數(shù)據(jù)集分成了訓(xùn)練集和測試集,通常的做法是通過計(jì)算屬性值的中位數(shù)來填充缺失值,注意此時(shí)計(jì)算屬性值的中位數(shù)是通過訓(xùn)練集上的數(shù)據(jù)進(jìn)行計(jì)算的,當(dāng)我們得到一個(gè)模型的時(shí)候,如果想要測試模型的測試誤差來近似泛化誤差的時(shí)候,可能此時(shí)的測試集也會(huì)有一些缺失值,此時(shí)對(duì)應(yīng)屬性的缺失值是通過訓(xùn)練集計(jì)算的中位數(shù)來進(jìn)行填充的;
  • 由于測試集作為對(duì)泛化誤差的近似,所以訓(xùn)練好模型,最后在測試集上近似估計(jì)模型的泛化能力。此時(shí)假設(shè)有兩個(gè)不同的機(jī)器學(xué)習(xí)模型,猶豫不決的時(shí)候,可以通過訓(xùn)練兩個(gè)模型,然后對(duì)比他們在測試數(shù)據(jù)上的泛化誤差,選擇泛化能力強(qiáng)的模型。
  • 前面說了這么多,那如何劃分?jǐn)?shù)據(jù)集為訓(xùn)練集和測試集呢?其實(shí)很簡單,可以自己編寫程序,也可以使用sklearn提供的模塊:

    import numpy as np def split_train_test(data,test_ratio):#設(shè)置隨機(jī)數(shù)種子,保證每次生成的結(jié)果都是一樣的np.random.seed(42)#permutation隨機(jī)生成0-len(data)隨機(jī)序列shuffled_indices = np.random.permutation(len(data))#test_ratio為測試集所占的百分比test_set_size = int(len(data) * test_ratio)test_indices = shuffled_indices[:test_set_size]train_indices = shuffled_indices[test_set_size:]#iloc選擇參數(shù)序列中所對(duì)應(yīng)的行return data.iloc[train_indices],data.iloc[test_indices]#測試 train_set,test_set = split_train_test(data,0.2) print(len(train_set), "train +", len(test_set), "test")

    通過sklearn實(shí)現(xiàn):

    from sklearn.model_selection import train_test_split #data:需要進(jìn)行分割的數(shù)據(jù)集 #random_state:設(shè)置隨機(jī)種子,保證每次運(yùn)行生成相同的隨機(jī)數(shù) #test_size:將數(shù)據(jù)分割成訓(xùn)練集的比例 train_set, test_set = train_test_split(data, test_size=0.2, random_state=42)

    前面介紹的兩種分割數(shù)據(jù)集的方式都是采用純隨機(jī)的采樣方式,這種方式對(duì)于大量數(shù)據(jù)集以及對(duì)于目標(biāo)值分布均勻的情況是可行的。比如對(duì)于分類任務(wù),我們訓(xùn)練一個(gè)二值分類器,可能數(shù)據(jù)中包含大量的正例樣本,僅僅包含10%的反例樣本,此時(shí)的標(biāo)簽分布很不均勻,如果我們通過隨機(jī)采樣的方式,極端情況下可能將正例樣本都劃分到訓(xùn)練集上,而反例樣本恰好都分到測試集,這樣訓(xùn)練出來的模型,效果一定不會(huì)太好,所以我們需要采用分層采樣的方式進(jìn)行劃分?jǐn)?shù)據(jù)集,也就是說保證訓(xùn)練集中既包含一定比例的正例樣本又要包含一定比例的負(fù)例樣本。

    幸運(yùn)的是sklearn提供了我們分層抽樣的函數(shù),在這之前先看看官方提供的例子:

    from sklearn.model_selection import StratifiedShuffleSplit X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]]) y = np.array([0, 0, 1, 1]) split = StratifiedShuffleSplit(n_splits=3, test_size=0.5, random_state=0) print(split ) # doctest: +ELLIPSIS# StratifiedShuffleSplit(n_splits=3, random_state=0, ...) for train_index, test_index in split.split(X, y):print("TRAIN:", train_index, "TEST:", test_index)X_train, X_test = X[train_index], X[test_index]y_train, y_test = y[train_index], y[test_index]""" StratifiedShuffleSplit(n_splits=3, random_state=0, test_size=0.5,train_size=None) TRAIN: [1 2] TEST: [3 0] TRAIN: [0 2] TEST: [1 3] TRAIN: [0 2] TEST: [3 1] """

    通過上面的例子我們可以了解使用分層進(jìn)行劃分?jǐn)?shù)據(jù)集的大概流程,以及各個(gè)參數(shù)的含義:

    • n_splits:分割迭代的次數(shù),如果我們要?jiǎng)澐钟?xùn)練集和測試集的話,將其設(shè)置為1即可;
    • test_size:分割測試集的比例;
    • random_state:設(shè)置隨機(jī)種子;

    下面通過兩種方式對(duì)原始的mnist數(shù)據(jù)集進(jìn)行劃分,首先要準(zhǔn)備數(shù)據(jù)集:

    from sklearn.datasets import fetch_mldata #我將最原始的mnist數(shù)據(jù)集下載到當(dāng)前路徑下,指定data_home mnist = fetch_mldata('MNIST original',data_home=r"./") x_data = mnist["data"].reshape((mnist["data"].shape[0],-1)) y_data = mnist["target"].reshape((mnist["target"].shape[0],-1)) print(x_data.shape) #(70000, 784) print(y_data.shape) #(70000, 1)

    使用隨機(jī)采樣的方式分割數(shù)據(jù)集:

    #使用隨機(jī)采樣方式劃分?jǐn)?shù)據(jù)集 from sklearn.model_selection import train_test_split import numpy as npdata = np.hstack((x_data,y_data)) #先將數(shù)據(jù)集進(jìn)行拼接,要不然我們只針對(duì)樣本進(jìn)行采樣的話,會(huì)找不到對(duì)應(yīng)的標(biāo)簽的 train_set,test_set = train_test_split(data,test_size = 0.2,random_state = 42) print(len(train_set),len(test_set))""" 56000 14000 """
    • 使用分層采樣的方式分割數(shù)據(jù)集:
    from sklearn.model_selection import StratifiedShuffleSplitsplit = StratifiedShuffleSplit(n_splits = 1,test_size = 0.2,random_state = 42)#根據(jù)mnist["target"]來進(jìn)行分層采樣 for train_index,test_index in split.split(data[:,:-1],data[:,-1]):train_set = data[train_index,:]test_set = data[test_index,:]print(len(train_set),len(test_set))""" 56000 14000 """

    如果想要知道抽取的各個(gè)樣本的比例,你可以將數(shù)據(jù)轉(zhuǎn)換成DataFrame對(duì)象(當(dāng)然在處理數(shù)據(jù)的開始你也可以將數(shù)據(jù)轉(zhuǎn)換為DataFrame方便操作):

    #將分割后的訓(xùn)練數(shù)據(jù)轉(zhuǎn)換為DataFrame #這里的參數(shù)data可以是分割之后的訓(xùn)練集或者測試集 train_data = pd.DataFrame(train_set) #快速查看對(duì)數(shù)據(jù)的描述 train_data.info() #查看各個(gè)類別的比例 print(train_data[784].value_counts() / len(train_data))

    2.驗(yàn)證集

    前面說到我們將數(shù)據(jù)集劃分為訓(xùn)練集和測試集,我們讓模型在訓(xùn)練集上進(jìn)行訓(xùn)練,然后在測試集上來近似模型的泛化能力。我們?nèi)绻胍暨x不同的模型的話,可以讓兩個(gè)模型分別在訓(xùn)練集上訓(xùn)練,然后將兩個(gè)訓(xùn)練好的模型分別在測試集上進(jìn)行測試,由于我們把測試集上的誤差近似近似為泛化誤差,所以我們自然可以選擇在測試集上誤差小的模型作為最終我們要選擇的泛化能力強(qiáng)的模型。

    但是我們要做的不僅是不同的模型與模型之間的對(duì)比,很多時(shí)候我們需要對(duì)模型本身進(jìn)行選擇,假如我們有兩個(gè)模型,線性模型和神經(jīng)網(wǎng)絡(luò)模型,我們知道神經(jīng)網(wǎng)絡(luò)的泛化能力要比線性模型要強(qiáng),我們選擇了神經(jīng)網(wǎng)絡(luò)模型,但是神經(jīng)網(wǎng)絡(luò)中還有很多的需要人工進(jìn)行選擇的參數(shù),比如神經(jīng)網(wǎng)絡(luò)的層數(shù)和每層神經(jīng)網(wǎng)絡(luò)的神經(jīng)元個(gè)數(shù)以及正則化的一些參數(shù)等等,我們將這些參數(shù)稱為超參數(shù)。這些參數(shù)不同選擇對(duì)模型最終的效果也很重要,我們在開發(fā)模型的時(shí)候總是需要調(diào)節(jié)這些超參數(shù)。

    現(xiàn)在我們需要調(diào)節(jié)這些超參數(shù)來使得模型泛化能力最強(qiáng)。我們使用測試集來作為泛化誤差估計(jì),而我們最終的目的就是選擇泛化能力強(qiáng)的模型,那么我們可以直接通過模型在測試集上的誤差來調(diào)節(jié)這些參數(shù)不就可以了。可能模型在測試集上的誤差為0,但是你拿著這樣的模型去部署到真實(shí)場景中去使用的話,效果可能會(huì)非常差。

    這一現(xiàn)象叫做信息泄露。我們使用測試集作為泛化誤差的近似,所以不到最后是不能將測試集的信息泄露出去的,就好比考試一樣,我們平時(shí)做的題相當(dāng)于訓(xùn)練集,測試集相當(dāng)于最終的考試,我們通過最終的考試來檢驗(yàn)我們最終的學(xué)習(xí)能力,將測試集信息泄露出去,相當(dāng)于學(xué)生提前知道了考試題目,那最后再考這些提前知道的考試題目,當(dāng)然代表不了什么,你在最后的考試中得再高的分?jǐn)?shù),也不能代表你學(xué)習(xí)能力強(qiáng)。而如果通過測試集來調(diào)節(jié)模型,相當(dāng)于不僅知道了考試的題目,學(xué)生還都學(xué)會(huì)怎么做這些題了(因?yàn)槲覀兛隙〞?huì)人為的讓模型在測試集上的誤差最小,因?yàn)檫@是你調(diào)整超參數(shù)的目的),那再拿這些題考試的話,人人都有可能考滿分,但是并沒有起到檢測學(xué)生學(xué)習(xí)能力的作用。原來我們通過測試集來近似泛化誤差,也就是通過考試來檢驗(yàn)學(xué)生的學(xué)習(xí)能力,但是由于信息泄露,此時(shí)的測試集即考試無任何意義,現(xiàn)實(shí)中可能學(xué)生的能力很差。所以,我們在學(xué)習(xí)的時(shí)候,老師會(huì)準(zhǔn)備一些小測試來幫助我們查缺補(bǔ)漏,這些小測試也就是要說的驗(yàn)證集。我們通過驗(yàn)證集來作為調(diào)整模型的依據(jù),這樣不至于將測試集中的信息泄露。

    也就是說我們將數(shù)據(jù)劃分訓(xùn)練集、驗(yàn)證集和測試集。在訓(xùn)練集上訓(xùn)練模型,在驗(yàn)證集上評(píng)估模型,一旦找到的最佳的參數(shù),就在測試集上最后測試一次,測試集上的誤差作為泛化誤差的近似。關(guān)于驗(yàn)證集的劃分可以參考測試集的劃分,其實(shí)都是一樣的,這里不再贅述。

    吳恩達(dá)老師的視頻中,如果當(dāng)數(shù)據(jù)量不是很大的時(shí)候(萬級(jí)別以下)的時(shí)候?qū)⒂?xùn)練集、驗(yàn)證集以及測試集劃分為6:2:2;若是數(shù)據(jù)很大,可以將訓(xùn)練集、驗(yàn)證集、測試集比例調(diào)整為98:1:1;但是當(dāng)可用的數(shù)據(jù)很少的情況下也可以使用一些高級(jí)的方法,比如留出方,K折交叉驗(yàn)證等。

    ?

    ?

    ?

    ?

    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的训练集、验证集和测试集的比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。