python 留一交叉驗(yàn)證的實(shí)例
python 留一交叉驗(yàn)證
基本原理
K折交叉驗(yàn)證
簡(jiǎn)單來說,K折交叉驗(yàn)證就是:
- 把數(shù)據(jù)集劃分成K份,取出其中一份作為測(cè)試集,另外的K - 1份作為訓(xùn)練集。
- 通過訓(xùn)練集得到回歸方程,再把測(cè)試集帶入該回歸方程,得到預(yù)測(cè)值。
- 計(jì)算預(yù)測(cè)值與真實(shí)值的差值的平方,得到平方損失函數(shù)(或其他的損失函數(shù))。
- 重復(fù)以上過程,總共得到K個(gè)回歸方程和K個(gè)損失函數(shù),其中損失函數(shù)最小的回歸方程就是最優(yōu)解。
留一交叉驗(yàn)證
留一交叉驗(yàn)證是K折交叉驗(yàn)證的特殊情況,即:將數(shù)據(jù)集劃分成N份,N為數(shù)據(jù)集總數(shù)。就是只留一個(gè)數(shù)據(jù)作為測(cè)試集,該特殊情況稱為“留一交叉驗(yàn)證”。
代碼實(shí)現(xiàn)
'''留一交叉驗(yàn)證''' import numpy as np # K折交叉驗(yàn)證 data = [[12, 1896], [11, 1900], [11, 1904], [10.8, 1908], [10.8, 1912], [10.8, 1920], [10.6, 1924], [10.8, 1928], [10.3, 1932], [10.3, 1936], [10.3, 1948], [10.4, 1952], [10.5, 1956], [10.2, 1960], [10.0, 1964], [9.95, 1968], [10.14, 1972], [10.06, 1976], [10.25, 1980], [9.99, 1984], [9.92, 1988], [9.96, 1992], [9.84, 1996], [9.87, 2000], [9.85, 2004], [9.69, 2008]] length = len(data) # 得到訓(xùn)練集和測(cè)試集 def Get_test_train(length, data, i): test_data = data[i] # 測(cè)試集 train_data = data[:] train_data.pop(i) # 訓(xùn)練集 return train_data, test_data # 得到線性回歸直線 def Get_line(train_data): time = [] year = [] average_year_time = 0 average_year_year = 0 for i in train_data: time.append(i[0]) year.append(i[1]) time = np.array(time) year = np.array(year) average_year = sum(year) / length # year拔 average_time = sum(time) / length # time拔 for i in train_data: average_year_time = average_year_time + i[0] * i[1] average_year_year = average_year_year + i[1] ** 2 average_year_time = average_year_time / length # (year, time)拔 average_year_year = average_year_year / length # (year, year)拔 # 線性回歸:t = w0 + w1 * x w1 = (average_year_time - average_year * average_time) / (average_year_year - average_year * average_year) w0 = average_time - w1 * average_year return w0, w1 # 得到損失函數(shù) def Get_loss_func(w0, w1, test_data): time_real = test_data[0] time_predict = eval('{} + {} * {}'.format(w0, w1, test_data[1])) loss = (time_predict - time_real) ** 2 dic['t = {} + {}x'.format(w0, w1)] = loss return dic if __name__ == '__main__': dic = {} # 存放建為回歸直線,值為損失函數(shù)的字典 for i in range(length): train_data, test_data = Get_test_train(length, data, i) w0, w1 = Get_line(train_data) Get_loss_func(w0, w1, test_data) dic = Get_loss_func(w0, w1, test_data) min_loss = min(dic.values()) best_line = [k for k, v in dic.items() if v == min_loss][0] print('最佳回歸直線:', best_line) print('最小損失函數(shù):', min_loss)
留一法交叉驗(yàn)證 Leave-One-Out Cross Validation
交叉驗(yàn)證法,就是把一個(gè)大的數(shù)據(jù)集分為 k 個(gè)小數(shù)據(jù)集,其中 k−1 個(gè)作為訓(xùn)練集,剩下的 1 11 個(gè)作為測(cè)試集,在訓(xùn)練和測(cè)試的時(shí)候依次選擇訓(xùn)練集和它對(duì)應(yīng)的測(cè)試集。這種方法也被叫做 k 折交叉驗(yàn)證法(k-fold cross validation)。最終的結(jié)果是這 k 次驗(yàn)證的均值。
此外,還有一種交叉驗(yàn)證方法就是 留一法(Leave-One-Out,簡(jiǎn)稱LOO),顧名思義,就是使 k kk 等于數(shù)據(jù)集中數(shù)據(jù)的個(gè)數(shù),每次只使用一個(gè)作為測(cè)試集,剩下的全部作為訓(xùn)練集,這種方法得出的結(jié)果與訓(xùn)練整個(gè)測(cè)試集的期望值最為接近,但是成本過于龐大。
我們用SKlearn庫(kù)來實(shí)現(xiàn)一下LOO
from sklearn.model_selection import LeaveOneOut # 一維示例數(shù)據(jù) data_dim1 = [1, 2, 3, 4, 5] # 二維示例數(shù)據(jù) data_dim2 = [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5]] loo = LeaveOneOut() # 實(shí)例化LOO對(duì)象 # 取LOO訓(xùn)練、測(cè)試集數(shù)據(jù)索引 for train_idx, test_idx in loo.split(data_dim1): # train_idx 是指訓(xùn)練數(shù)據(jù)在總數(shù)據(jù)集上的索引位置 # test_idx 是指測(cè)試數(shù)據(jù)在總數(shù)據(jù)集上的索引位置 print("train_index: %s, test_index %s" % (train_idx, test_idx)) # 取LOO訓(xùn)練、測(cè)試集數(shù)據(jù)值 for train_idx, test_idx in loo.split(data_dim1): # train_idx 是指訓(xùn)練數(shù)據(jù)在總數(shù)據(jù)集上的索引位置 # test_idx 是指測(cè)試數(shù)據(jù)在總數(shù)據(jù)集上的索引位置 train_data = [data_dim1[i] for i in train_idx] test_data = [data_dim1[i] for i in test_idx] print("train_data: %s, test_data %s" % (train_data, test_data))
data_dim1的輸出:
train_index: [1 2 3 4], test_index [0]
train_index: [0 2 3 4], test_index [1]
train_index: [0 1 3 4], test_index [2]
train_index: [0 1 2 4], test_index [3]
train_index: [0 1 2 3], test_index [4]train_data: [2, 3, 4, 5], test_data [1]
train_data: [1, 3, 4, 5], test_data [2]
train_data: [1, 2, 4, 5], test_data [3]
train_data: [1, 2, 3, 5], test_data [4]
train_data: [1, 2, 3, 4], test_data [5]
data_dim2的輸出:
train_index: [1 2 3 4], test_index [0]
train_index: [0 2 3 4], test_index [1]
train_index: [0 1 3 4], test_index [2]
train_index: [0 1 2 4], test_index [3]
train_index: [0 1 2 3], test_index [4]train_data: [[2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5]], test_data [[1, 1, 1, 1]]
train_data: [[1, 1, 1, 1], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5]], test_data [[2, 2, 2, 2]]
train_data: [[1, 1, 1, 1], [2, 2, 2, 2], [4, 4, 4, 4], [5, 5, 5, 5]], test_data [[3, 3, 3, 3]]
train_data: [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [5, 5, 5, 5]], test_data [[4, 4, 4, 4]]
train_data: [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]], test_data [[5, 5, 5, 5]]
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python Selenium網(wǎng)頁(yè)自動(dòng)化利器使用詳解
這篇文章主要為大家介紹了使用Python Selenium實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12如何利用python實(shí)現(xiàn)列表嵌套字典取值
這篇文章主要介紹了如何利用python實(shí)現(xiàn)列表嵌套字典取值,首先通過將列表backup_unit_id全部提取出來,確定需要取值的對(duì)象展開文章內(nèi)容,感興趣的朋友可以看一下2022-06-06基于python計(jì)算滾動(dòng)方差(標(biāo)準(zhǔn)差)talib和pd.rolling函數(shù)差異詳解
這篇文章主要介紹了基于python計(jì)算滾動(dòng)方差(標(biāo)準(zhǔn)差)talib和pd.rolling函數(shù)差異詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-06-06python3操作redis實(shí)現(xiàn)List列表實(shí)例
本文主要介紹了python3操作redis實(shí)現(xiàn)List列表實(shí)例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Django+Bootstrap實(shí)現(xiàn)計(jì)算器的示例代碼
本文主要介紹了Django+Bootstrap實(shí)現(xiàn)計(jì)算器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11