官术网_书友最值得收藏!

1.7 模型驗(yàn)證

在訓(xùn)練完模型之后,需要對(duì)模型進(jìn)行評(píng)價(jià),決定是否采用訓(xùn)練后的模型。本書(shū)前面的例子都是直接在訓(xùn)練數(shù)據(jù)上驗(yàn)證模型,這種方法存在一個(gè)很?chē)?yán)重的問(wèn)題:模型有可能過(guò)擬合。

什么情況下會(huì)出現(xiàn)過(guò)擬合呢?過(guò)擬合常常出現(xiàn)在以下3種情況下:

  • 數(shù)據(jù)有噪聲;
  • 數(shù)據(jù)集過(guò)小;
  • 模型太復(fù)雜。

在解決過(guò)擬合問(wèn)題之前,需要有一個(gè)判斷過(guò)擬合的依據(jù),就是使用訓(xùn)練集之外的數(shù)據(jù)進(jìn)行驗(yàn)證。

在sklearn中,有兩種常用的驗(yàn)證方法:留出驗(yàn)證法和交叉驗(yàn)證法。

留出驗(yàn)證法的操作方式是在訓(xùn)練之前,從總數(shù)據(jù)集中按一定規(guī)則(或隨機(jī))抽取一部分?jǐn)?shù)據(jù)作為驗(yàn)證數(shù)據(jù)集,然后在模型訓(xùn)練完成之后,在驗(yàn)證集上對(duì)模型的預(yù)測(cè)效果進(jìn)行驗(yàn)證。

如果模型在訓(xùn)練集上的效果非常好,但是在驗(yàn)證集上的效果很差,就說(shuō)明模型出現(xiàn)了過(guò)擬合現(xiàn)象。

sklearn中的留出驗(yàn)證法可以通過(guò)sklearn.model_selection.train_test_split函數(shù)實(shí)現(xiàn)。下面是一個(gè)模型過(guò)擬合的例子(此例使用Jupyter Notebook編寫(xiě)):

In:
    import numpy as np
    from sklearn.model_selection import train_test_split
    # 導(dǎo)入線性模型和多項(xiàng)式特征構(gòu)造模塊
    from sklearn import  linear_model
    from sklearn.preprocessing import  PolynomialFeatures
    from sklearn.metrics import r2_score
    import matplotlib.pyplot as plt
    %matplotlib inline

接下來(lái)需要生成20個(gè)樣本點(diǎn),并加入一些隨機(jī)擾動(dòng),生成數(shù)據(jù)的代碼如下:

In:
    # 樣本數(shù)量
    n_samples = 20
    x = np.array([i+2 for i in range(n_samples)]) * 4
    # 在log函數(shù)曲線上加入隨機(jī)噪聲
    y = 3 * np.log(x) + np.random.randint(0,3,n_samples)
    plt.scatter(x,y)

生成的樣本如圖1-16所示。

圖 1-16 生成數(shù)據(jù)

然后對(duì)數(shù)據(jù)集進(jìn)行劃分,留出一部分驗(yàn)證集,其中test_size是驗(yàn)證集在總數(shù)據(jù)集中的占比:

In:
    x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.3)

下面使用二項(xiàng)式擬合的方式來(lái)擬合這個(gè)模型。在sklearn中,二項(xiàng)式擬合的實(shí)現(xiàn)方法是先將訓(xùn)練特征轉(zhuǎn)換為二項(xiàng)式特征,然后再使用線性回歸模型進(jìn)行擬合,相關(guān)代碼如下:

In:
    def poly_fit(degree):
        poly_reg =PolynomialFeatures(degree=degree)
        # 轉(zhuǎn)換成二次特征
        x_ploy_train = poly_reg.fit_transform(x_train.reshape(-1,1))
        # 對(duì)x_test進(jìn)行同樣的轉(zhuǎn)換
        x_ploy_test = poly_reg.transform(x_test.reshape(-1,1))
        clf = linear_model.LinearRegression()
        clf.fit(x_ploy_train,y_train.reshape(-1,1))
        # 創(chuàng)建子圖,繪制訓(xùn)練集上的預(yù)測(cè)結(jié)果
        plt.subplot(121)
        y_train_pred = clf.predict(x_ploy_train)
        sorted_indices = np.argsort(x_train)
        plt.plot(x_train[sorted_indices],y_train_pred[sorted_indices])
        plt.scatter(x_train,y_train)
        # 創(chuàng)建子圖,繪制驗(yàn)證集上的預(yù)測(cè)結(jié)果
        plt.subplot(122)
        y_test_pred = clf.predict(x_ploy_test)
        # 同時(shí)對(duì)x_test和y_test_pred進(jìn)行排序
        sorted_indices = np.argsort(x_test)
        plt.plot(x_test[sorted_indices],y_test_pred[sorted_indices])
        plt.scatter(x_test,y_test)
        # 計(jì)算r2_score
        print("Train R2 score",r2_score(y_train_pred,y_train))
        print("Test R2 score",r2_score(y_test_pred,y_test))

然后逐步提高多項(xiàng)式的次數(shù),觀察模型效果與多項(xiàng)式次數(shù)之間的關(guān)系。二次多項(xiàng)式擬合代碼如下,結(jié)果如圖1-17所示:

In:
    poly_fit(2)
Out:
    Train R2 score 0.8102748526150807
    Test R2 score 0.7661602866338544

圖 1-17 二次多項(xiàng)式擬合結(jié)果

五次多項(xiàng)式擬合代碼如下,結(jié)果如圖1-18所示:

In:
    poly_fit(5)
Out:
    Train R2 score 0.9087433750748772
    Test R2 score 0.8326903541105737

圖 1-18 五次多項(xiàng)式擬合結(jié)果

十次多項(xiàng)式擬合代碼如下,結(jié)果如圖1-19所示:

In:
    poly_fit(10)
Out:
    Train R2 score 0.9176237285551411
    Test R2 score -0.13339572778788056

圖 1-19 十次多項(xiàng)式擬合結(jié)果

上述案例使用train_test_split將數(shù)據(jù)集劃分為兩個(gè)部分,訓(xùn)練集和驗(yàn)證集。然后在訓(xùn)練集上進(jìn)行模型訓(xùn)練,訓(xùn)練完成后,分別計(jì)算訓(xùn)練集和驗(yàn)證集上的模型指標(biāo)。

結(jié)果發(fā)現(xiàn),隨著模型復(fù)雜度的提升(多項(xiàng)式特征次數(shù)越來(lái)越高),模型在訓(xùn)練集上的表現(xiàn)(R2 Score)越來(lái)越好,在驗(yàn)證集上的效果卻是先變好再變壞。這就是模型過(guò)擬合的表現(xiàn)。

交叉驗(yàn)證法可以理解為留出驗(yàn)證法的升級(jí)版,以sklearn中的KFold檢驗(yàn)為例,其算法步驟如下。

(1) 將數(shù)據(jù)集劃分為n個(gè)互斥子集。

(2) 以其中一個(gè)子集作為驗(yàn)證集,其他子集作為訓(xùn)練集,訓(xùn)練模型。

(3) 選擇另一個(gè)子集作為驗(yàn)證集,其他子集作為訓(xùn)練集,再訓(xùn)練模型。

(4) 如此進(jìn)行n次訓(xùn)練和測(cè)試,得到n個(gè)結(jié)果。

在發(fā)現(xiàn)模型過(guò)擬合后,可以嘗試通過(guò)如下幾個(gè)方法解決過(guò)擬合的問(wèn)題:

  • 重新清洗數(shù)據(jù);
  • 增加數(shù)據(jù)量;
  • 采用正則化方法;
  • 選擇合適的模型。
主站蜘蛛池模板: 常州市| 阿克陶县| 南丹县| 滨海县| 平南县| 嵩明县| 祥云县| 鹤峰县| 阜康市| 东兰县| 保亭| 贵港市| 汾西县| 西青区| 隆昌县| 韶山市| 准格尔旗| 新源县| 安乡县| 周至县| 杭锦旗| 衡南县| 岳池县| 琼结县| 安多县| 揭阳市| 肃宁县| 繁峙县| 偏关县| 溧水县| 苏州市| 广东省| 青浦区| 进贤县| 凭祥市| 余干县| 鹤岗市| 辛集市| 英德市| 嵊泗县| 临沭县|