“k 近法”在算法層面理解容易,可以從使用“k 近鄰法”處理分類問(wèn)題入手赶诊,解釋機(jī)器學(xué)習(xí)中的各種概念和一般流程侣滩。
k 近鄰法的基本思想
“k 近鄰法” 幾乎是所有機(jī)器學(xué)習(xí)算法中最簡(jiǎn)單的算法木西,它用于分類的核心思想就是“物以類聚乐埠,人以群分”,即未標(biāo)記樣本的類別由距離其最近的 個(gè)鄰居投票來(lái)決定禽篱。
(圖片來(lái)自周志華《機(jī)器學(xué)習(xí)》第 10 章第 1 節(jié))
有監(jiān)督學(xué)習(xí)、分類學(xué)習(xí)谆级、回歸
有監(jiān)督學(xué)習(xí)的數(shù)據(jù)包含了“特征”和“標(biāo)簽”。根據(jù)這些數(shù)據(jù)對(duì)新的數(shù)據(jù)的分類進(jìn)行預(yù)測(cè)或預(yù)測(cè)讼积,如果待預(yù)測(cè)的目標(biāo)變量是離散值肥照,那么這一類問(wèn)題稱之為“分類問(wèn)題”;如果待預(yù)測(cè)的目標(biāo)變量是連續(xù)值勤众,那么這一類問(wèn)題稱之為“回歸”問(wèn)題舆绎。
評(píng)估算法時(shí)不能使用在訓(xùn)練過(guò)程中出現(xiàn)過(guò)的數(shù)據(jù)
這一點(diǎn)很像我們以前學(xué)習(xí)的時(shí)候,常常會(huì)買一本練習(xí)冊(cè)做題们颜,如果這本練習(xí)冊(cè)沒(méi)有參考答案吕朵,你就不知道自己做對(duì)與否猎醇。而真正檢驗(yàn)?zāi)銓W(xué)習(xí)水平的大型考試,例如期中考試努溃、期末考試硫嘶、中考、高考都是重新出題梧税,如果使用以前出現(xiàn)過(guò)的題目沦疾,則不能檢驗(yàn)?zāi)銓W(xué)習(xí)的真實(shí)水平,因?yàn)槟阌锌赡苁怯涀×藛?wèn)題的解法第队,而沒(méi)有理解它哮塞。
這就是分離訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集的必要性。因此采集到的所有帶標(biāo)簽的樣本凳谦,應(yīng)該分離一部分用于測(cè)試忆畅。那么評(píng)估算法應(yīng)該采用什么指標(biāo)呢?
評(píng)估算法好壞的指標(biāo)
一般地尸执,“ 近鄰法”用于分類問(wèn)題使用“準(zhǔn)確率”作為指標(biāo)家凯。但是在數(shù)據(jù)分布不平衡的時(shí)候,就不能使用準(zhǔn)確率了剔交,而應(yīng)該使用精準(zhǔn)率肆饶、召回率、混淆矩陣等岖常,甚至應(yīng)該看看 auc驯镊。
超參數(shù)
超參數(shù)是算法執(zhí)行之前認(rèn)為定義的〗甙埃“ 近鄰法” 中的
就是一個(gè)超參數(shù)板惑,它決定了模型的復(fù)雜度。
“ 近鄰法” 還有其它超參數(shù)偎快,使用的距離的定義是歐氏距離還是閔式距離冯乘,閔式距離的參數(shù)
是多少,投票的時(shí)候是“平票”還是“加權(quán)投票”晒夹。
模型的復(fù)雜度裆馒、過(guò)擬合、欠擬合
越小丐怯,模型就越復(fù)雜喷好。極端情況下
,新來(lái)的預(yù)測(cè)數(shù)據(jù)的類別取決于訓(xùn)練樣本中離他最近的那個(gè)樣本的類別读跷,如果這個(gè)樣本恰好是標(biāo)記錯(cuò)誤的樣本梗搅,預(yù)測(cè)就可能發(fā)生錯(cuò)誤,因?yàn)樗床坏礁鄶?shù)據(jù),就有可能過(guò)擬合无切,學(xué)習(xí)到的不是樣本數(shù)據(jù)的一般規(guī)律荡短。
越大,模型就越簡(jiǎn)單哆键。極端情況下
等于所有訓(xùn)練樣本的個(gè)數(shù)掘托,此時(shí)每新來(lái)一個(gè)數(shù)據(jù)做預(yù)測(cè)的時(shí)候,就直接把訓(xùn)練樣本中出現(xiàn)最多的類別數(shù)返回就行了洼哎,這樣的模型過(guò)于簡(jiǎn)單烫映,以致于失去了算法真正的意義,所有的預(yù)測(cè)數(shù)據(jù)都返回同一個(gè)值噩峦,對(duì)數(shù)據(jù)不能很好的預(yù)測(cè)锭沟,這是欠擬合。
網(wǎng)格搜索與交叉驗(yàn)證
網(wǎng)格搜索其實(shí)就是暴力搜索识补,把我們認(rèn)為可能合理的超參數(shù)和超參數(shù)的組合輸入算法族淮。而評(píng)價(jià)一組超參數(shù)的好壞一定不能使用測(cè)試數(shù)據(jù)集,一般的做法是從訓(xùn)練數(shù)據(jù)集中再分離出一部分?jǐn)?shù)據(jù)用于驗(yàn)證超參數(shù)的好壞凭涂,并且這種驗(yàn)證超參數(shù)好壞的做法要使用不同的訓(xùn)練數(shù)據(jù)集的子集重復(fù)多次祝辣,這就是交叉驗(yàn)證。
交叉驗(yàn)證用于選擇超參數(shù)切油,由于分離數(shù)據(jù)集其實(shí)帶有一定的隨機(jī)性蝙斜,把所有的數(shù)據(jù)集都看一遍,多次取平均的做法澎胡,比起一次性隨機(jī)地使用訓(xùn)練數(shù)據(jù)集的一部分子集作為測(cè)試數(shù)據(jù)集要靠譜孕荠。
網(wǎng)格搜索中就用到了交叉驗(yàn)證,通過(guò)框架被封裝了起來(lái)攻谁,不用我們手動(dòng)實(shí)現(xiàn)稚伍。
數(shù)據(jù)標(biāo)準(zhǔn)化
數(shù)據(jù)標(biāo)準(zhǔn)化是我剛開始接觸學(xué)習(xí)機(jī)器學(xué)習(xí)算法的時(shí)候經(jīng)常被忽略的。由于 k 近鄰法使用距離作為度量戚宦,數(shù)據(jù)在量綱上的統(tǒng)一是十分重要的个曙,數(shù)據(jù)標(biāo)準(zhǔn)化則可以避免計(jì)算出來(lái)的距離被量綱大的特征所主導(dǎo)。
后面我們可以看到數(shù)據(jù)標(biāo)準(zhǔn)化在梯度下降中也發(fā)揮很大的作用受楼,還有 SVM垦搬、K-means 這些距離度量的算法,都要求我們對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化艳汽。
例如:《機(jī)器學(xué)習(xí)實(shí)戰(zhàn)》提供的例子猴贰。
在數(shù)據(jù)標(biāo)準(zhǔn)化這件事上,還要注意:訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集一定都使用相同的標(biāo)準(zhǔn)化方式骚灸,即訓(xùn)練數(shù)據(jù)集的標(biāo)準(zhǔn)化方式糟趾,請(qǐng)看下面的公式慌植。
測(cè)試數(shù)據(jù)集在標(biāo)準(zhǔn)化的時(shí)候甚牲,一定也要使用“訓(xùn)練數(shù)據(jù)集”的平均值和“訓(xùn)練數(shù)據(jù)集”的標(biāo)準(zhǔn)差义郑,而不能使用測(cè)試數(shù)據(jù)集的。
原因其實(shí)很簡(jiǎn)單:
1丈钙、標(biāo)準(zhǔn)化其實(shí)可以視為算法的一部分非驮,既然數(shù)據(jù)集都減去了一個(gè)數(shù),然后除以一個(gè)數(shù)雏赦,這兩個(gè)數(shù)對(duì)于所有的數(shù)據(jù)來(lái)說(shuō)劫笙,就要一視同仁;
2星岗、訓(xùn)練數(shù)據(jù)集其實(shí)很少填大,在預(yù)測(cè)新樣本的時(shí)候,新樣本就更少得可憐俏橘,如果新樣本就一個(gè)數(shù)據(jù)允华,它的均值就是它自己,標(biāo)準(zhǔn)差是 0 寥掐,這根本就不合理靴寂。
k 近鄰算法的三要素
1、超參數(shù): 召耘;
2百炬、距離的定義(例如:歐氏距離);
3污它、決策的規(guī)則(例如:投票表決剖踊,或者加權(quán)投票)。
手寫 k 近鄰法的核心代碼
Python 代碼:
distances = [np.linalg.norm(point - X) for point in X_train]
print("打印每個(gè)點(diǎn)距離待測(cè)點(diǎn)的距離:")
for index, distance in enumerate(distances):
print("[{}] {}".format(index, np.round(distance, 2)))
sorted_index = np.argsort(distances)
print(y_train[sorted_index])
k = 6
topK = y_train[sorted_index][:k]
print(topK)
from collections import Counter
votes = Counter(topK)
mc = votes.most_common(n=1)
print(mc)
print("根據(jù)投票得出的點(diǎn) X 的標(biāo)簽為:", mc[0][0])
通過(guò) k 近鄰法了解機(jī)器學(xué)習(xí)項(xiàng)目的執(zhí)行流程
使用 iris 鳶尾花數(shù)據(jù)集轨蛤。
1蜜宪、分割訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集;
2祥山、只用訓(xùn)練數(shù)據(jù)集 fit
得到均值和標(biāo)準(zhǔn)差圃验;
3、分別對(duì)訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集進(jìn)行 transform
缝呕,注意:這里只需要傳入 X_train 和 y_train 就可以了澳窑,不用傳入標(biāo)簽;
4供常、使用 k 近鄰法進(jìn)行評(píng)分摊聋,注意:傳入的特征矩陣一定要經(jīng)過(guò)數(shù)據(jù)標(biāo)準(zhǔn)化。
k? 近鄰法的特點(diǎn)
在整理這部分內(nèi)容的時(shí)候栈暇,發(fā)現(xiàn)優(yōu)點(diǎn)和缺點(diǎn)其實(shí)要在一定的前提下討論麻裁,所以就干脆放在一起,說(shuō)一說(shuō) k 近鄰法的特點(diǎn)。
k 近鄰法是一個(gè)懶惰學(xué)習(xí)的算法煎源,沒(méi)有顯式的學(xué)習(xí)過(guò)程色迂,即沒(méi)有它沒(méi)有訓(xùn)練的步驟,是一個(gè)基于記憶的學(xué)習(xí)算法手销。
k 近鄰法是一種在線學(xué)習(xí)技術(shù)歇僧,新數(shù)據(jù)可以直接加入數(shù)據(jù)集而不必進(jìn)行重新訓(xùn)練,但與此同時(shí)在線學(xué)習(xí)計(jì)算量大锋拖,對(duì)內(nèi)存的需求也較大诈悍。基本的 k 近鄰法每預(yù)測(cè)一個(gè)“點(diǎn)”的分類都會(huì)重新進(jìn)行一次全局運(yùn)算兽埃,對(duì)于樣本容量大的數(shù)據(jù)集計(jì)算量比較大侥钳。k 近鄰法的優(yōu)化實(shí)現(xiàn):kd 樹,即給訓(xùn)練數(shù)據(jù)建立樹結(jié)構(gòu)一樣的索引柄错,期望快速找到 個(gè)鄰居慕趴,以防止線性掃描。
“多數(shù)表決”規(guī)則等價(jià)于“經(jīng)驗(yàn)風(fēng)險(xiǎn)最小化”鄙陡,即算法在訓(xùn)練數(shù)據(jù)集上“風(fēng)險(xiǎn)”最小冕房。
對(duì)異常值和噪聲有較高的容忍度,在算距離的時(shí)候趁矾,異常值和噪聲離待預(yù)測(cè)的點(diǎn)的距離會(huì)比較遠(yuǎn)耙册,且個(gè)數(shù)較少,就不會(huì)參與最終結(jié)果的投票毫捣。
近鄰算法天生就支持多分類详拙,類似還有決策樹、樸素貝葉斯分類蔓同,它們區(qū)別于感知機(jī)饶辙、邏輯回歸、SVM 這類原生只用于二分類問(wèn)題的算法斑粱。
維度災(zāi)難
在高維空間中計(jì)算距離的時(shí)候弃揽,就會(huì)變得非常遠(yuǎn)前酿。
樣本不平衡時(shí)绽慈,預(yù)測(cè)偏差會(huì)比較大。
值大小的選擇得依靠經(jīng)驗(yàn)或者交叉驗(yàn)證得到念搬,不能自己拍腦門隨便指定一個(gè)尚揣。
增加鄰居的權(quán)重涌矢,距離越近,權(quán)重越高快骗,參數(shù):weights
娜庇。
當(dāng)數(shù)據(jù)采樣不均勻的時(shí)候塔次,使用一定半徑內(nèi)的點(diǎn),該算法可以取得更好的性能名秀,可以參考 from sklearn.neighbors import RadiusNeighborsClassifier
俺叭。
k 近鄰法還可以用于回歸,找最近的鄰居泰偿,然后計(jì)算它們的平均值就可以了。
參考資料
[1] 李航. 統(tǒng)計(jì)學(xué)習(xí)方法(第 2 版蜈垮,第 3 章“ 近鄰法”). 北京:清華大學(xué)出版社耗跛,2019.
說(shuō)明:介紹了 kd 樹攒发,并給出了例子羔砾。
[2] 周志華. 機(jī)器學(xué)習(xí)(第 10 章第 1 節(jié)). 北京:清華大學(xué)出版社.
說(shuō)明:只簡(jiǎn)單介紹了思想趾访,并給出了 k 近鄰算法雖簡(jiǎn)單但預(yù)測(cè)效果在一定情況下比最優(yōu)貝葉斯估計(jì)強(qiáng)的結(jié)論(我的這個(gè)概括待推敲),沒(méi)有《統(tǒng)計(jì)學(xué)習(xí)方法》介紹詳細(xì)。
[3] [美] Peter Harrington 著匣砖,李銳变隔,李鵬,曲亞?wèn)| 等 譯.機(jī)器學(xué)習(xí)實(shí)戰(zhàn)(第 2 章).北京:人民郵電出版社.
說(shuō)明:想吐槽一下這本書在這一章節(jié)給出的示例代碼柑爸,很簡(jiǎn)單的一個(gè)算法譬圣,它給出的代碼變得很復(fù)雜,其實(shí)并不利于理解 k 近鄰算法的基本思想飘庄。
(本節(jié)完)
以下為草稿切揭,我自己留著備用哼审,讀者可以忽略,歡迎大家批評(píng)指正孕豹。
想說(shuō)一說(shuō)“k 近鄰算法”在機(jī)器學(xué)習(xí)中的地位
“k 近鄰算法” 可以說(shuō)是最容易理解的機(jī)器學(xué)習(xí)算法涩盾,所以可以用“k 近鄰算法”來(lái)作為入門機(jī)器學(xué)習(xí)算法的基本流程的最好材料,因?yàn)槲覀冊(cè)诶斫馑惴ㄉ喜豁氁ㄌ鄷r(shí)間励背。
下面簡(jiǎn)單說(shuō)說(shuō)春霍,“k 近鄰算法” 給我們帶來(lái)了什么。
- 超參數(shù):k 就是一個(gè)超參數(shù)叶眉,這是我們得根據(jù)經(jīng)驗(yàn)址儒,在算法運(yùn)行之前指定的芹枷;
- 數(shù)據(jù)集分離:我們不能使用所有的樣本訓(xùn)練數(shù)據(jù),我們還要評(píng)估算法的性能莲趣,即使是同一個(gè)算法鸳慈,不同的超參數(shù)還須要評(píng)估好壞,因此喧伞,必須從數(shù)據(jù)集中分離出一部分?jǐn)?shù)據(jù)走芋,進(jìn)行算法好壞,超參數(shù)選擇的驗(yàn)證潘鲫;
- 評(píng)估算法好壞的準(zhǔn)則:k 近鄰算法用于分類問(wèn)題翁逞,一個(gè)最容易理解的評(píng)價(jià)指標(biāo)就是準(zhǔn)確率(或者錯(cuò)誤率,因?yàn)殄e(cuò)誤率=1-準(zhǔn)確率)次舌;
- 交叉驗(yàn)證:交叉驗(yàn)證用于選擇超參數(shù),比起簡(jiǎn)單地那一部分?jǐn)?shù)據(jù)作為測(cè)試數(shù)據(jù)集要靠譜兽愤,因?yàn)榉蛛x數(shù)據(jù)集帶有一定隨機(jī)性彼念;
- 網(wǎng)格搜索:其實(shí)就是暴力搜索,把我們認(rèn)為可能合理的超參數(shù)和超參數(shù)的組合輸入算法浅萧,而在其中評(píng)估算法好壞逐沙,超參數(shù)的選擇也用到了交叉驗(yàn)證的過(guò)程;
- 數(shù)據(jù)標(biāo)準(zhǔn)化:這一步是一開始學(xué)習(xí)機(jī)器學(xué)習(xí)算法的時(shí)候經(jīng)常被忽略的洼畅,后面我們可以看到數(shù)據(jù)標(biāo)準(zhǔn)化在梯度下降中也發(fā)揮很大的作用吩案;
- 模型復(fù)雜度:理解下面這句話
的值越小,模型越復(fù)雜帝簇,
的值越大徘郭,模型越簡(jiǎn)單,因?yàn)?
如果和訓(xùn)練數(shù)據(jù)集一樣大的話丧肴,其實(shí)我們每個(gè)預(yù)測(cè)數(shù)據(jù)都只能預(yù)測(cè)為一個(gè)類別残揉,即訓(xùn)練數(shù)據(jù)集中數(shù)量最多的那個(gè)類別;
- 決策邊界:這是分類問(wèn)題的一個(gè)重要且簡(jiǎn)單的概念芋浮。
算法執(zhí)行的步驟
1抱环、選擇 和距離的度量;
2纸巷、計(jì)算待標(biāo)記的數(shù)據(jù)樣本和數(shù)據(jù)集中每個(gè)樣本的距離镇草,取距離最近的 個(gè)樣本。待標(biāo)記的數(shù)據(jù)樣本所屬的類別瘤旨,就由這
個(gè)距離最近的樣本投票產(chǎn)生梯啤。
k 近鄰算法的訓(xùn)練過(guò)程,即是利用訓(xùn)練數(shù)據(jù)集存哲,對(duì)特征向量空間進(jìn)行劃分
說(shuō)明:從這張圖中条辟,你可以看到?jīng)Q策邊界黔夭。
-
近鄰算法是一個(gè)懶惰學(xué)習(xí)的算法,沒(méi)有顯式的學(xué)習(xí)過(guò)程羽嫡,即沒(méi)有它沒(méi)有訓(xùn)練的步驟本姥,是一個(gè)基于記憶的學(xué)習(xí)算法;
- “多數(shù)表決”規(guī)則等價(jià)于“經(jīng)驗(yàn)風(fēng)險(xiǎn)最小化”(我們的算法在訓(xùn)練數(shù)據(jù)集上“風(fēng)險(xiǎn)”最泻伎谩)婚惫;
-
近鄰算法的優(yōu)化實(shí)現(xiàn):kd 樹,即是給訓(xùn)練數(shù)據(jù)建立樹結(jié)構(gòu)一樣的索引魂爪,期望快速找到
個(gè)鄰居先舷,以防止線性掃描。
近鄰算法的應(yīng)用領(lǐng)域
文本分類滓侍、模式識(shí)別蒋川、聚類分析,多分類領(lǐng)域撩笆。
近鄰算法的優(yōu)點(diǎn)
-
近鄰算法是一種在線技術(shù)捺球,新數(shù)據(jù)可以直接加入數(shù)據(jù)集而不必進(jìn)行重新訓(xùn)練;
-
近鄰算法理論簡(jiǎn)單夕冲,容易實(shí)現(xiàn)氮兵;
- 準(zhǔn)確性高:對(duì)異常值和噪聲有較高的容忍度;
-
近鄰算法天生就支持多分類歹鱼,區(qū)別與感知機(jī)泣栈、邏輯回歸、SVM弥姻。
近鄰算法的缺點(diǎn)
基本的
近鄰算法每預(yù)測(cè)一個(gè)“點(diǎn)”的分類都會(huì)重新進(jìn)行一次全局運(yùn)算南片,對(duì)于樣本容量大的數(shù)據(jù)集計(jì)算量比較大;
維度災(zāi)難:在高維空間中計(jì)算距離的時(shí)候庭敦,就會(huì)變得非常遠(yuǎn)铃绒;
樣本不平衡時(shí),預(yù)測(cè)偏差比較大螺捐,例如:某一類的樣本比較少颠悬,而其它類樣本比較多;
值大小的選擇得依靠經(jīng)驗(yàn)或者交叉驗(yàn)證得到定血。
的選擇可以使用交叉驗(yàn)證赔癌,也可以使用網(wǎng)格搜索(其實(shí)是一件事情,網(wǎng)格搜索里面其實(shí)就是用的交叉驗(yàn)證)澜沟;
的值越大灾票,模型的偏差越大,對(duì)噪聲數(shù)據(jù)越不敏感茫虽,當(dāng)
的值很大的時(shí)候刊苍,可能造成模型欠擬合既们;
的值越小,模型的方差就會(huì)越大正什,當(dāng)
的值很小的時(shí)候啥纸,就會(huì)造成模型的過(guò)擬合。
從
近鄰算法說(shuō)開
- 增加鄰居的權(quán)重婴氮,距離越近斯棒,權(quán)重越高,參數(shù):weights主经;
維基百科最近鄰居法詞條中是這樣介紹的:
無(wú)論是分類還是回歸荣暮,衡量鄰居的權(quán)重都非常有用,使較近鄰居的權(quán)重比較遠(yuǎn)鄰居的權(quán)重大罩驻。例如穗酥,一種常見的加權(quán)方案是給每個(gè)鄰居權(quán)重賦值為
,其中
是到鄰居的距離惠遏。
使用一定半徑內(nèi)的點(diǎn)砾跃,當(dāng)數(shù)據(jù)采樣不均勻的時(shí)候,該算法可以取得更好的性能:
from sklearn.neighbors import RadiusNeighborsClassifier
爽哎;近鄰算法還可以用于回歸蜓席,找最近的鄰居器一,計(jì)算它們的平均值就可以了课锌。