本文主要介紹一個被普遍使用的機器學習分類算法,K-nearest neighbors(KNN),中文叫K近鄰算法。 算法
k近鄰算法是一種基本分類和迴歸方法。性能優化
KNN實際上也能夠用於迴歸問題,不過在工業界使用得比較普遍的仍是分類問題網絡
KNN的核心思想也很是簡單,若是一個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,好比下圖,當K=3時,節點會被預測屬於紅色橢圓類。有點「近朱者赤,近墨者黑」的感受。 app
算法的原理很是簡單,但這其中隱藏了一些值得被探討的點:機器學習
下面咱們一一來解決與KNN相關的一些問題ide
一些機器學習共通的內容(Feature engineering、Imbalance Data、Normalization留待後續博客詳細介紹)。性能
超參數是在開始學習過程以前設置值的參數,而不是經過訓練獲得的參數數據。好比:學習
- 訓練神經網絡的學習速率。
- 學習速率
- 用於支持向量機的C和sigma超參數。
- K最近鄰的K。
KNN中,K越大則類與類的分界會越平緩,K越小則會越陡峭。當K越小時整個模型的錯誤率(Error Rate)會越低(固然過擬合的可能就越大)。測試
擴展閱讀:過擬合大數據
因爲KNN通常用於分類,因此K通常是奇數才方便投票
通常狀況下,K與模型的validation error(模型應用於驗證數據的錯誤)的關係以下圖所示。
K越小則模型越過擬合,在驗證數據上表現確定通常,而若是K很大則對某個數據的預測會把不少距離較遠的數據也放入預測,致使預測發生錯誤。因此咱們須要針對某一個問題選擇一個最合適的K值,來保證模型的效果最好。本文僅介紹一種「交叉驗證法」,在機器學習裏,一般來講咱們不能將所有用於數據訓練模型,不然咱們將沒有數據集對該模型進行驗證,從而評估咱們的模型的預測效果。爲了解決這一問題,有以下經常使用的方法:
The Validation Set Approach指的是最簡單的,也是很容易就想到的。咱們能夠把整個數據集分紅兩部分,一部分用於訓練,一部分用於驗證,這也就是咱們常常提到的訓練集(training set)和驗證集(Validation set)
然而咱們都知道,當用於模型訓練的數據量越大時,訓練出來的模型一般效果會越好。因此訓練集和測試集的劃分意味着咱們沒法充分利用咱們手頭已有的數據,因此獲得的模型效果也會受到必定的影響。
基於這樣的背景有人就提出了交叉驗證法(Cross-Validation)。
這裏簡單介紹下k-fold cross-validation,指的是將全部訓練數據折成k份,以下圖是當折數k=5時的狀況。
咱們分別使用這5組訓練-驗證數據獲得KNN超參數K爲某個值的時候,好比K=1的5個準確率,而後將其準確率取平均數獲得超參數K爲1時的準確率。而後咱們繼續去計算K=3 K=5 K=7時的準確率,而後咱們就能選擇到一個準確率最高的超參K了。K近鄰算法的核心在於找到實例點的鄰居,那麼鄰居的斷定標準是什麼,用什麼來度量?這在機器學習領域其實就是去找兩個特徵向量的類似性。機器學習中描述兩個特徵向量間類似性的距離公式有不少:
本文簡要介紹一部分算法,後續會有博客詳細介紹
常見的兩點之間或多點之間的距離表示法
曼哈頓距離指的是在向量在各座標軸上投影的距離總和,想象你在曼哈頓要從一個十字路口開車到另一個十字路口,駕駛距離是兩點間的直線距離嗎?顯然不是,除非你能穿越大樓。而實際駕駛距離就是這個「曼哈頓距離」,此即曼哈頓距離名稱的來源, 同時,曼哈頓距離也稱爲城市街區距離(City Block distance)。
由印度統計學家馬哈拉諾比斯(P. C. Mahalanobis)提出,表示數據的協方差距離。是一種有效的計算兩個未知樣本集的類似度的方法。 與歐氏距離不一樣的是它考慮到各類特性之間的聯繫(例如:一條關於身高的信息會帶來一條關於體重的信息,由於二者是有關聯的),而且是尺度無關的(scale-invariant),即獨立於測量尺度。 若是協方差矩陣爲單位矩陣,那麼馬氏距離就簡化爲歐氏距離。
從原理中很容易知道,最基本的KNN算法的時間複雜度是O(N),由於對於某一個數據,必須計算它必須與模型中的全部點的距離。有沒有辦法優化這部分性能呢?這裏主要說下兩個方法。
K-d trees are a wonderful invention that enable 𝑂(𝑘log𝑛) (expected) lookup times for the 𝑘 nearest points to some point 𝑥. This is extremely useful, especially in cases where an 𝑂(𝑛) lookup time is intractable already.
其算法的核心思想是分而治之,即將整個空間劃分爲幾個小部分。
詳情能夠看How does a k-d tree find the K nearest neighbors?
注意K-D樹對於數據緯度d來講是指數級的複雜度,因此只適合用在數據緯度較小的狀況。
因此LSH不能保證必定準確
那麼怎麼插入才能保證距離近的節點大機率插入同一個bucket中呢?詳情不過多介紹,我找到一篇以document類似度爲例的一篇文章,讀者能夠詳細瞭解。
在一些狀況下明明數據離某一個點特別近,但有另外兩個同類的點離得很遠但被K包含在內了,這種狀況把數據劃爲這兩個點的同類是否是不太合理。
例以下圖,當K=3時,紅點會被投票選舉成Offer類,但實際上這個點可能更加適合分類爲No Offer。
爲了解決這一問題有一種方法Distance-weighted nearest neighbor。其核心思想是讓距離近的點能夠獲得更大的權重。
stats.stackexchange.com/questions/4…
www.datascience.com/blog/imbala…
www.analyticsvidhya.com/blog/2018/0…
towardsdatascience.com/understandi…