首頁>技術>

問題引出

之前我們使用K近鄰演算法嘗試尋找使用者年齡與預估薪資之間的某種相關性,以及他們是否有購買SUV的決定。主要程式碼如下:

在有一個問題,上面的n_neighbors(k值)為什麼是5,其他值可不可以?效果會怎麼樣?如何知道哪個k值的效果相對較好?這就需要用到交叉驗證。

交叉驗證有什麼用,為什麼要用它?

關於它有什麼用,經過瀏覽相關網頁獲得了以下兩點總結:

在資料集很小的時候防止過擬合。找到合適的模型引數。

看到這裡,不知道你對為什麼要用交叉驗證有沒有明白一點點,說白了就是我們手頭上的資料量太小,直接對資料量小的資料集進行訓練集和測試集的劃分,最後的效果即使很好,也不能確定後面部署上線的結果會一樣好,因為模型效果表現僅僅侷限於我們那少得可憐的資料集上。

假如我們有很多很多的資料,不要問多少,反正就是很多的那種,我個人覺得我們可以直接暴力的通過下面方式來找到KNN的最優k值:

這樣,在我們有大量資料前提下,我們就可以大致確定哪個k值最優了,或者直接做深度學習。

但是,現實中,我們往往很難收集到大量的資料,這種情況下,我們只好從我們那少得可憐的資料集下手了,也就是說,我們要在資料量少的情況下,儘量通過交叉驗證來找到一組好的模型引數,讓其在看到未知引數的情況也一樣好,這樣也就防止了模型訓練的效果好,看到未知資料不好的過擬合情況。

如何交叉驗證?

簡單來說就是對資料集進行重新劃分,不再像之前那樣只是簡單將資料集劃分訓練集和測試集。關於如何重新劃分資料集,網上主要有兩種方式。

1、先將資料集劃分為訓練集和測試集,再對訓練集劃分為子訓練集和子測試集,如下圖:

2、直接將資料集劃分如下所示:

關於上面的兩個方法,看到網路上絕大多數都是第一種方式,我是這麼認為的,既然交叉驗證只是用來找到合適的模型引數,到最後我們要驗證找的合適的模型引數是否合適,那麼我們還是需要通過給模型看看它沒有看過的資料來驗證,所以我也支援第一種方法。

還有一點要說明的是,從上面的圖中可以看出,交叉驗證的時候同時訓練十個模型(訓練集和測試集都不一樣),然後將結果取求和平均。到這裡我又有一個疑惑,為什麼是10個,不是5個,接著我又瀏覽一些網站,發現一點:大家普遍用5個或者是10個。我後面會選5個的。不要問為什麼,因為如果我用10個你也會問我同意的問題。

動手擼程式碼

又到開心又快樂的擼程式碼(我信你鬼)環節,對了,上面和接下來要做的都是基於sklearn的K近鄰演算法做的。為了更加深刻了解機器學習的敲程式碼步驟,下面將盡量從頭開始做起。

案例描述

一家汽車公司剛剛推出了他們新型的豪華SUV,我們嘗試預測哪些使用者會購買這種全新SUV。資料集是從某社交網路中收集的使用者資訊。這些資訊涉及使用者ID、性別、年齡以及預估薪資,最後一列用來表示使用者是否購買。我們將建立一種模型來預測使用者是否購買這種SUV,該模型基於兩個變數,分別是年齡和預計薪資。我們嘗試尋找使用者年齡與預估薪資之間的某種相關性,以及他們是否有購買SUV的決定。

匯入常用相關庫

匯入資料集

將資料集劃分成為訓練集和測試集

資料標準化

運用訓練集來做交叉驗證,從而找到最優k值

我們因為要同時觀察訓練集的子訓練集和測試集效果隨著k的增加而變化情況,所以這裡直接用 sklearn.model_selection 中的 vlidation_curve 來完成。

從上圖我們可以看到最優的k值在7。

用找到的k值做模型訓練

用測試集測試結果

到這裡就結束了。最後要記住交叉驗證不是用來提高模型準確率的,而是用來找到合適的模型引數,在資料集很小的時候防止過擬合。

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 如何通過 SSH 在遠端 Linux 系統上執行命令