日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【白话机器学习】算法理论+实战之K近邻算法

發(fā)布時(shí)間:2025/3/8 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【白话机器学习】算法理论+实战之K近邻算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者1. 寫(xiě)在前面

如果想從事數(shù)據(jù)挖掘或者機(jī)器學(xué)習(xí)的工作,掌握常用的機(jī)器學(xué)習(xí)算法是非常有必要的,在這簡(jiǎn)單的先捋一捋, 常見(jiàn)的機(jī)器學(xué)習(xí)算法:

  • 監(jiān)督學(xué)習(xí)算法:邏輯回歸,線性回歸,決策樹(shù),樸素貝葉斯,K近鄰,支持向量機(jī),集成算法Adaboost等

  • 無(wú)監(jiān)督算法:聚類(lèi),降維,關(guān)聯(lián)規(guī)則, PageRank等

為了詳細(xì)的理解這些原理,曾經(jīng)看過(guò)西瓜書(shū),統(tǒng)計(jì)學(xué)習(xí)方法,機(jī)器學(xué)習(xí)實(shí)戰(zhàn)等書(shū),也聽(tīng)過(guò)一些機(jī)器學(xué)習(xí)的課程,但總感覺(jué)話語(yǔ)里比較深?yuàn)W,讀起來(lái)沒(méi)有耐心,并且理論到處有,而實(shí)戰(zhàn)最重要, 所以在這里想用最淺顯易懂的語(yǔ)言寫(xiě)一個(gè)白話機(jī)器學(xué)習(xí)算法理論+實(shí)戰(zhàn)系列

個(gè)人認(rèn)為,理解算法背后的idea和使用,要比看懂它的數(shù)學(xué)推導(dǎo)更加重要。idea會(huì)讓你有一個(gè)直觀的感受,從而明白算法的合理性,數(shù)學(xué)推導(dǎo)只是將這種合理性用更加嚴(yán)謹(jǐn)?shù)恼Z(yǔ)言表達(dá)出來(lái)而已,打個(gè)比方,一個(gè)梨很甜,用數(shù)學(xué)的語(yǔ)言可以表述為糖分含量90%,但只有親自咬一口,你才能真正感覺(jué)到這個(gè)梨有多甜,也才能真正理解數(shù)學(xué)上的90%的糖分究竟是怎么樣的。如果算法是個(gè)梨,本文的首要目的就是先帶領(lǐng)大家咬一口。另外還有下面幾個(gè)目的:

  • 檢驗(yàn)自己對(duì)算法的理解程度,對(duì)算法理論做一個(gè)小總結(jié)

  • 能開(kāi)心的學(xué)習(xí)這些算法的核心思想, 找到學(xué)習(xí)這些算法的興趣,為深入的學(xué)習(xí)這些算法打一個(gè)基礎(chǔ)。

  • 每一節(jié)課的理論都會(huì)放一個(gè)實(shí)戰(zhàn)案例,能夠真正的做到學(xué)以致用,既可以鍛煉編程能力,又可以加深算法理論的把握程度。

  • 也想把之前所有的筆記和參考放在一塊,方便以后查看時(shí)的方便。

學(xué)習(xí)算法的過(guò)程,獲得的不應(yīng)該只有算法理論,還應(yīng)該有樂(lè)趣和解決實(shí)際問(wèn)題的能力!

今天是白話機(jī)器學(xué)習(xí)算法理論+實(shí)戰(zhàn)的第七篇 之K近鄰算法,這應(yīng)該是諸多機(jī)器學(xué)習(xí)算法中最容易理解或者操作的一個(gè)算法了吧,但是別看它簡(jiǎn)單,但是很實(shí)用的。因?yàn)樗瓤梢杂脕?lái)做分類(lèi),也可以用來(lái)做回歸,易于實(shí)現(xiàn),無(wú)需估計(jì)參數(shù),無(wú)需訓(xùn)練。當(dāng)然也有一些缺點(diǎn),比如計(jì)算量比較大,分析速度較慢,樣本不均衡問(wèn)題不太好用,也無(wú)法給出數(shù)據(jù)的內(nèi)在含義,是一種懶散學(xué)習(xí)法。?當(dāng)然,KNN也可以用于推薦算法,雖然現(xiàn)在很多推薦系統(tǒng)的算法會(huì)使用 TD-IDF、協(xié)同過(guò)濾、Apriori 算法,不過(guò)針對(duì)數(shù)據(jù)量不大的情況下,采用 KNN 作為推薦算法也是可行的。

這么簡(jiǎn)單,并且作用還很大的算法我們應(yīng)該立刻把握住,所以這節(jié)課,我們就來(lái)學(xué)習(xí)KNN的計(jì)算原理,并且用KNN來(lái)實(shí)現(xiàn)一個(gè)實(shí)戰(zhàn)案例,我們開(kāi)始吧。

大綱如下:

  • 如果根據(jù)打斗和接吻的次數(shù)來(lái)劃分電影的類(lèi)型?(我們引出KNN)

  • KNN的工作原理(近朱者赤,近墨者黑)

  • 如何用KNN做回歸?(簡(jiǎn)單介紹一下)

  • 用KNN實(shí)現(xiàn)書(shū)寫(xiě)數(shù)字的識(shí)別(手寫(xiě)數(shù)字識(shí)別可是深度學(xué)習(xí)界的Hellow world,在這里先帶你認(rèn)識(shí)一下)

OK, let's go!

2. K近鄰算法?我們依然從一個(gè)電影的分類(lèi)開(kāi)始

KNN 的英文叫 K-Nearest Neighbor,應(yīng)該算是數(shù)據(jù)挖掘算法中最簡(jiǎn)單的一種。雖然簡(jiǎn)單,但是很實(shí)用, 老規(guī)矩,既然白話,還是先從例子開(kāi)始,讓你再次體會(huì)算法來(lái)源生活

假設(shè)有下面這幾部電影,我給你統(tǒng)計(jì)了電影中的打斗次數(shù)、接吻次數(shù), 當(dāng)然其他的也可以統(tǒng)計(jì),但是沒(méi)顧得上,如下表所示:我們很容易理解《戰(zhàn)狼》《紅海行動(dòng)》《碟中諜 6》是動(dòng)作片,《前任 3》《春嬌救志明》《泰坦尼克號(hào)》是愛(ài)情片。(如果不理解,自己去看電影吧,還能找個(gè)放松的接口)

但是假設(shè)我目前有一部新電影, 叫做《速度與激情9》,我也統(tǒng)計(jì)了一下打斗次數(shù)和接吻次數(shù), 這應(yīng)該劃分到愛(ài)情還是動(dòng)作呢??你會(huì)說(shuō),這還不簡(jiǎn)單,我直接就知道是范·迪塞爾男神主演的動(dòng)作片。但是機(jī)器不知道啊, 機(jī)器可不管你男神還是女神,你得讓機(jī)器明白這種分類(lèi)規(guī)則,讓機(jī)器去分類(lèi)啊, 那你應(yīng)該用什么方法呢?

我們可以把打斗次數(shù)看成 X 軸,接吻次數(shù)看成 Y 軸,然后在二維的坐標(biāo)軸上,對(duì)這幾部電影進(jìn)行標(biāo)記,如下圖所示。對(duì)于《速度與激情》,坐標(biāo)為 (x,y),我們需要看下離電影 A 最近的都有哪些電影,這些電影中的大多數(shù)屬于哪個(gè)分類(lèi),那么電影 A 就屬于哪個(gè)分類(lèi)。

嗯嗯,這才是你教機(jī)器做的東西呢,其實(shí)這就是K近鄰了啊,好理解吧,就是新的一部電影過(guò)來(lái)了,看他和哪個(gè)鄰居挨得近,鄰居是哪一類(lèi),它就是哪一類(lèi)啦。

但是,具體還有些細(xì)節(jié)需要我們知道,下面就真的看看原理吧。

3. K近鄰的工作原理

簡(jiǎn)單的一句話就可以說(shuō)明KNN的工作原理“近朱者赤,近墨者黑”。

K近鄰算法的過(guò)程是給定一個(gè)訓(xùn)練數(shù)據(jù)集,對(duì)新輸入的實(shí)例,在訓(xùn)練數(shù)據(jù)集中找到與該實(shí)例最鄰近的K個(gè)實(shí)例, 這K個(gè)實(shí)例的多數(shù)屬于某個(gè)類(lèi), 就把該輸入實(shí)例分為這個(gè)類(lèi)。看上面這個(gè)圖:有兩類(lèi)不同的樣本數(shù)據(jù), 分別用藍(lán)色的正方形和紅色的三角形表示, 而正中間的綠色圓表示待分類(lèi)數(shù)據(jù) 下面我們根據(jù)K近鄰思想給綠色圓點(diǎn)分類(lèi):

  • 如果k=3, 綠色圓點(diǎn)的最近鄰的3個(gè)點(diǎn)是2個(gè)紅色三角和1個(gè)藍(lán)色小正方形, 少數(shù)服從多數(shù), 基于統(tǒng)計(jì)的方法,判定綠色的這個(gè)待分類(lèi)點(diǎn)屬于紅色三角形一類(lèi)

  • 如果k=5, 綠色圓點(diǎn)的最近鄰的5個(gè)點(diǎn)是2個(gè)紅色三角和3個(gè)藍(lán)色小正方形,還是少數(shù)服從多數(shù), 基于統(tǒng)計(jì)的方法,判定這個(gè)待分類(lèi)點(diǎn)屬于藍(lán)色的正方形一類(lèi)

從上面例子可以看出, k近鄰算法的思想非常簡(jiǎn)單, 對(duì)新來(lái)的點(diǎn)如何歸類(lèi)?【只要找到離它最近的k個(gè)實(shí)例, 哪個(gè)類(lèi)別最多即可】

所以,KNN的工作原理大致分為三步:

  • 計(jì)算待分類(lèi)物體與其他物體之間的距離;

  • 統(tǒng)計(jì)距離最近的 K 個(gè)鄰居;

  • 對(duì)于 K 個(gè)最近的鄰居,它們屬于哪個(gè)分類(lèi)最多,待分類(lèi)物體就屬于哪一類(lèi)。

  • 但是下面就引出了2個(gè)問(wèn)題:

    • 怎么度量距離,鎖定最近的K個(gè)鄰居?(不同的度量方法可能導(dǎo)致K個(gè)鄰居不同)

    • 怎么確定這個(gè)K值(K值不同,最后的結(jié)果可能不同,像上面那樣)

    下面就來(lái)破了這倆問(wèn)題。

    首先先說(shuō)第二個(gè)問(wèn)題, K值如何選擇?

    你能看出整個(gè) KNN 的分類(lèi)過(guò)程,K 值的選擇還是很重要的

    • 如果 K 值比較小,就相當(dāng)于未分類(lèi)物體與它的鄰居非常接近才行。這樣產(chǎn)生的一個(gè)問(wèn)題就是,如果鄰居點(diǎn)是個(gè)噪聲點(diǎn),那么未分類(lèi)物體的分類(lèi)也會(huì)產(chǎn)生誤差,這樣 KNN 分類(lèi)就會(huì)產(chǎn)生過(guò)擬合。就比如下面這個(gè)情況(K=1, 綠色點(diǎn)為分類(lèi)點(diǎn)):上面這種情況K=1,直接把綠色點(diǎn)分到橙色那一類(lèi)了,但是橙色點(diǎn)是個(gè)噪聲點(diǎn)啊。

    • 如果 K 值比較大,相當(dāng)于距離過(guò)遠(yuǎn)的點(diǎn)也會(huì)對(duì)未知物體的分類(lèi)產(chǎn)生影響,雖然這種情況的好處是魯棒性強(qiáng),但是不足也很明顯,會(huì)產(chǎn)生欠擬合情況,也就是沒(méi)有把未分類(lèi)物體真正分類(lèi)出來(lái)。就比如下面這個(gè)情況:上面這種情況K=N, 那么無(wú)論輸入實(shí)例是什么,都將簡(jiǎn)單的預(yù)測(cè)它屬于在訓(xùn)練實(shí)例中最多的類(lèi),這時(shí)相當(dāng)于壓根沒(méi)有訓(xùn)練模型, 完全忽略訓(xùn)練數(shù)據(jù)實(shí)例中大量的有用信息,是不可取的。

    那么K值如何確定呢??呵呵,不好意思,這個(gè)值沒(méi)法事先而定,需要不斷的實(shí)踐,一次次的嘗試。工程上,我們一般采用交叉驗(yàn)證的方式選取K值。

    交叉驗(yàn)證的思路就是,把樣本集中的大部分樣本作為訓(xùn)練集,剩余的小部分樣本用于預(yù)測(cè),來(lái)驗(yàn)證分類(lèi)模型的準(zhǔn)確性。所以在 KNN 算法中,我們一般會(huì)把 K 值選取在較小的范圍內(nèi),同時(shí)在驗(yàn)證集上準(zhǔn)確率最高的那一個(gè)最終確定作為 K 值。

    再說(shuō)第二個(gè)問(wèn)題, 距離如何計(jì)算?

    在 KNN 算法中,還有一個(gè)重要的計(jì)算就是關(guān)于距離的度量。兩個(gè)樣本點(diǎn)之間的距離代表了這兩個(gè)樣本之間的相似度。距離越大,差異性越大;距離越小,相似度越大。

    度量距離有下面的五種方式:

    • 歐式距離歐氏距離是我們最常用的距離公式,也叫做歐幾里得距離。在二維空間中,兩點(diǎn)的歐式距離就是:同理,我們也可以求得兩點(diǎn)在n維空間中的距離:

    • 曼哈頓距離曼哈頓距離在幾何空間中用的比較多。曼哈頓距離等于兩個(gè)點(diǎn)在坐標(biāo)系上絕對(duì)軸距總和。用公式表示就是:以下圖為例,綠色的直線代表兩點(diǎn)之間的歐式距離,而紅色和黃色的線為兩點(diǎn)的曼哈頓距離。感受一下兩者的不同:

    • 閔可夫斯基距離閔可夫斯基距離不是一個(gè)距離,而是一組距離的定義。對(duì)于 n 維空間中的兩個(gè)點(diǎn) x(x1,x2,…,xn) 和 y(y1,y2,…,yn) , x 和 y 兩點(diǎn)之間的閔可夫斯基距離為:其中 p 代表空間的維數(shù),當(dāng) p=1 時(shí),就是曼哈頓距離;當(dāng) p=2 時(shí),就是歐氏距離;當(dāng) p→∞時(shí),就是切比雪夫距離。下面給出了不同的p值情況下,與原來(lái)Lp距離為1的點(diǎn)的圖形,直觀感受一下p值的不同,距離的變化:

    • 切比雪夫距離那么切比雪夫距離怎么計(jì)算呢?二個(gè)點(diǎn)之間的切比雪夫距離就是這兩個(gè)點(diǎn)坐標(biāo)數(shù)值差的絕對(duì)值的最大值,用數(shù)學(xué)表示就是:max(|x1-y1|,|x2-y2|)。

    • 余弦距離余弦距離實(shí)際上計(jì)算的是兩個(gè)向量的夾角,是在方向上計(jì)算兩者之間的差異,對(duì)絕對(duì)數(shù)值不敏感。在興趣相關(guān)性比較上,角度關(guān)系比距離的絕對(duì)值更重要,因此余弦距離可以用于衡量用戶對(duì)內(nèi)容興趣的區(qū)分度。比如我們用搜索引擎搜索某個(gè)關(guān)鍵詞,它還會(huì)給你推薦其他的相關(guān)搜索,這些推薦的關(guān)鍵詞就是采用余弦距離計(jì)算得出的。所以搜索推薦中,余弦距離會(huì)常用。

    其中前三種距離是 KNN 中最常用的距離。

    好了,解答了這個(gè)問(wèn)題,也就弄明白了KNN的原理了吧。是不是想迫不及待的實(shí)戰(zhàn)了?先別慌,還有點(diǎn)東西得介紹一下。

    4. KD樹(shù)

    關(guān)于KD樹(shù)的知識(shí),我在這不會(huì)介紹太多,涉及的數(shù)學(xué)公式有點(diǎn)多,但得介紹一下這個(gè)東西,我們不需要對(duì) KD 樹(shù)的數(shù)學(xué)原理了解太多,你只需要知道它是一個(gè)二叉樹(shù)的數(shù)據(jù)結(jié)構(gòu),方便存儲(chǔ) K 維空間的數(shù)據(jù)就可以了。而且在 sklearn 中,我們直接可以調(diào)用 KD 樹(shù),很方便。

    其實(shí)從上文你也能看出來(lái),KNN 的計(jì)算過(guò)程是大量計(jì)算樣本點(diǎn)之間的距離。為了減少計(jì)算距離次數(shù),提升 KNN 的搜索效率,人們提出了 KD 樹(shù)(K-Dimensional 的縮寫(xiě))。KD 樹(shù)是對(duì)數(shù)據(jù)點(diǎn)在 K 維空間中劃分的一種數(shù)據(jù)結(jié)構(gòu)。在 KD 樹(shù)的構(gòu)造中,每個(gè)節(jié)點(diǎn)都是 k 維數(shù)值點(diǎn)的二叉樹(shù)。既然是二叉樹(shù),就可以采用二叉樹(shù)的增刪改查操作,這樣就大大提升了搜索效率。

    嗯,關(guān)于KD樹(shù),就說(shuō)這么多,在實(shí)戰(zhàn)之前,再說(shuō)一下,KNN如何做回歸吧,畢竟后面的實(shí)戰(zhàn)是個(gè)分類(lèi)任務(wù),之前既然說(shuō)了KNN能夠做回歸,你可別說(shuō)我撒謊。

    5. KNN做回歸

    KNN 不僅可以做分類(lèi),還可以做回歸。首先講下什么是回歸。在開(kāi)頭電影這個(gè)案例中,如果想要對(duì)未知電影進(jìn)行類(lèi)型劃分,這是一個(gè)分類(lèi)問(wèn)題。首先看一下要分類(lèi)的未知電影,離它最近的 K 部電影大多數(shù)屬于哪個(gè)分類(lèi),這部電影就屬于哪個(gè)分類(lèi)。

    如果是一部新電影,已知它是愛(ài)情片,想要知道它的打斗次數(shù)、接吻次數(shù)可能是多少,這就是一個(gè)回歸問(wèn)題。

    那KNN如何做回歸呢?

    對(duì)于一個(gè)新電影 X(就假設(shè)《速度與激情》,我男神演的動(dòng)作片吧)。我們要預(yù)測(cè)它的某個(gè)屬性值,比如打斗次數(shù),具體特征屬性和數(shù)值如下所示。此時(shí),我們會(huì)先計(jì)算待測(cè)點(diǎn)(新電影 X)到已知點(diǎn)的距離,選擇距離最近的 K 個(gè)點(diǎn)。假設(shè) K=3,此時(shí)最近的 3 個(gè)點(diǎn)(電影)分別是《戰(zhàn)狼》,《紅海行動(dòng)》和《碟中諜 6》,那么它的打斗次數(shù)就是這 3 個(gè)點(diǎn)的該屬性值的平均值,即 (100+95+105)/3=100 次。

    好了,這就是KNN了,沒(méi)有什么特別要交代的了,下面實(shí)戰(zhàn)吧。

    6. KNN:如何對(duì)手寫(xiě)數(shù)字進(jìn)行識(shí)別?

    還是老規(guī)矩,先看看通過(guò)sklearn用這個(gè)工具。

    6.1 如何在sklearn中使用KNN?

    在 Python 的 sklearn 工具包中有 KNN 算法。KNN 既可以做分類(lèi)器,也可以做回歸。

    • 如果是做分類(lèi),你需要引用:from sklearn.neihbors import KNeighborsClassifier

    • 如果是回歸, 需要引用:from sklearn.neighbors import KNeighborsRegressor

    如何在sklearn中創(chuàng)建KNN分類(lèi)器呢?

    KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30), 看一下這幾個(gè)參數(shù):

    • n_neighbors:即 KNN 中的 K 值,代表的是鄰居的數(shù)量。K 值如果比較小,會(huì)造成過(guò)擬合。如果 K 值比較大,無(wú)法將未知物體分類(lèi)出來(lái)。一般我們使用默認(rèn)值 5。

    • weights:是用來(lái)確定鄰居的權(quán)重,有三種方式:

    • weights=uniform,代表所有鄰居的權(quán)重相同;

    • weights=distance,代表權(quán)重是距離的倒數(shù),即與距離成反比;

    • 自定義函數(shù),你可以自定義不同距離所對(duì)應(yīng)的權(quán)重。大部分情況下不需要自己定義函數(shù)。

    • algorithm:用來(lái)規(guī)定計(jì)算鄰居的方法,它有四種方式:

    • algorithm=auto,根據(jù)數(shù)據(jù)的情況自動(dòng)選擇適合的算法,默認(rèn)情況選擇 auto;

    • algorithm=kd_tree,也叫作 KD 樹(shù),是多維空間的數(shù)據(jù)結(jié)構(gòu),方便對(duì)關(guān)鍵數(shù)據(jù)進(jìn)行檢索,不過(guò) KD 樹(shù)適用于維度少的情況,一般維數(shù)不超過(guò) 20,如果維數(shù)大于 20 之后,效率反而會(huì)下降;

    • algorithm=ball_tree,也叫作球樹(shù),它和 KD 樹(shù)一樣都是多維空間的數(shù)據(jù)結(jié)果,不同于 KD 樹(shù),球樹(shù)更適用于維度大的情況;

    • algorithm=brute,也叫作暴力搜索,它和 KD 樹(shù)不同的地方是在于采用的是線性掃描,而不是通過(guò)構(gòu)造樹(shù)結(jié)構(gòu)進(jìn)行快速檢索。當(dāng)訓(xùn)練集大的時(shí)候,效率很低。

    • 4.leaf_size:代表構(gòu)造 KD 樹(shù)或球樹(shù)時(shí)的葉子數(shù),默認(rèn)是 30,調(diào)整 leaf_size 會(huì)影響到樹(shù)的構(gòu)造和搜索速度。

    創(chuàng)建完 KNN 分類(lèi)器之后,我們就可以輸入訓(xùn)練集對(duì)它進(jìn)行訓(xùn)練,這里我們使用 fit() 函數(shù),傳入訓(xùn)練集中的樣本特征矩陣和分類(lèi)標(biāo)識(shí),會(huì)自動(dòng)得到訓(xùn)練好的 KNN 分類(lèi)器。然后可以使用 predict() 函數(shù)來(lái)對(duì)結(jié)果進(jìn)行預(yù)測(cè),這里傳入測(cè)試集的特征矩陣,可以得到測(cè)試集的預(yù)測(cè)分類(lèi)結(jié)果。

    6.2 如何在sklearn中使用KNN?

    手寫(xiě)數(shù)字?jǐn)?shù)據(jù)集是個(gè)非常有名的用于圖像識(shí)別的數(shù)據(jù)集。數(shù)字識(shí)別的過(guò)程就是將這些圖片與分類(lèi)結(jié)果 0-9 一一對(duì)應(yīng)起來(lái)。完整的手寫(xiě)數(shù)字?jǐn)?shù)據(jù)集 MNIST 里面包括了 60000 個(gè)訓(xùn)練樣本,以及 10000 個(gè)測(cè)試樣本。如果你學(xué)習(xí)深度學(xué)習(xí)的話,MNIST 基本上是你接觸的第一個(gè)數(shù)據(jù)集。

    我們用 sklearn 自帶的手寫(xiě)數(shù)字?jǐn)?shù)據(jù)集做 KNN 分類(lèi),你可以把這個(gè)數(shù)據(jù)集理解成一個(gè)簡(jiǎn)版的 MNIST 數(shù)據(jù)集,它只包括了 1797 幅數(shù)字圖像,每幅圖像大小是 8*8 像素。

    還是先劃分一下流程:整個(gè)訓(xùn)練過(guò)程基本上都會(huì)包括三個(gè)階段:

  • 數(shù)據(jù)加載:我們可以直接從 sklearn 中加載自帶的手寫(xiě)數(shù)字?jǐn)?shù)據(jù)集;

  • 準(zhǔn)備階段:在這個(gè)階段中,我們需要對(duì)數(shù)據(jù)集有個(gè)初步的了解,比如樣本的個(gè)數(shù)、圖像長(zhǎng)什么樣、識(shí)別結(jié)果是怎樣的。你可以通過(guò)可視化的方式來(lái)查看圖像的呈現(xiàn)。通過(guò)數(shù)據(jù)規(guī)范化可以讓數(shù)據(jù)都在同一個(gè)數(shù)量級(jí)的維度。另外,因?yàn)橛?xùn)練集是圖像,每幅圖像是個(gè) 8*8 的矩陣,我們不需要對(duì)它進(jìn)行特征選擇,將全部的圖像數(shù)據(jù)作為特征值矩陣即可;

  • 分類(lèi)階段:通過(guò)訓(xùn)練可以得到分類(lèi)器,然后用測(cè)試集進(jìn)行準(zhǔn)確率的計(jì)算。

  • 好了,下面我們開(kāi)始吧:

    • 首先,導(dǎo)入包,這里導(dǎo)入了很多算法包,是因?yàn)榧热贿@次項(xiàng)目比較簡(jiǎn)單,都那么我們就對(duì)比一下之前的幾種方法,看看效果。

    import numpy as np import pandas as pd import matplotlib.pyplot as pltfrom sklearn.datasets import load_digits from sklearn.preprocessing import MinMaxScaler, StandardScaler from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.svm import SVC from sklearn.naive_bayes import MultinomialNB from sklearn.neighbors import KNeighborsClassifier from sklearn.ensemble import AdaBoostClassifier from sklearn.metrics import accuracy_score
    • 加載數(shù)據(jù)集并探索

    # 加載數(shù)據(jù) digits = load_digits() data = digits.data # 數(shù)據(jù)探索 print(data.shape) # 查看第一幅圖像 print(digits.images[0]) # 第一幅圖像代表的數(shù)字含義 print(digits.target[0]) # 將第一幅圖像顯示出來(lái) plt.gray() plt.imshow(digits.images[0]) plt.show()# 結(jié)果如下:(1797, 64) [[ 0. 0. 5. 13. 9. 1. 0. 0.][ 0. 0. 13. 15. 10. 15. 5. 0.][ 0. 3. 15. 2. 0. 11. 8. 0.][ 0. 4. 12. 0. 0. 8. 8. 0.][ 0. 5. 8. 0. 0. 9. 8. 0.][ 0. 4. 11. 0. 1. 12. 7. 0.][ 0. 2. 14. 5. 10. 12. 0. 0.][ 0. 0. 6. 13. 10. 0. 0. 0.]] 0

    我們對(duì)原始數(shù)據(jù)集中的第一幅進(jìn)行數(shù)據(jù)可視化,可以看到圖像是個(gè) 8*8 的像素矩陣,上面這幅圖像是一個(gè)“0”,從訓(xùn)練集的分類(lèi)標(biāo)注中我們也可以看到分類(lèi)標(biāo)注為“0”。

    • 分割數(shù)據(jù)集并規(guī)范化 klearn 自帶的手寫(xiě)數(shù)字?jǐn)?shù)據(jù)集一共包括了 1797 個(gè)樣本,每幅圖像都是 8*8 像素的矩陣。因?yàn)椴](méi)有專(zhuān)門(mén)的測(cè)試集,所以我們需要對(duì)數(shù)據(jù)集做劃分,劃分成訓(xùn)練集和測(cè)試集。因?yàn)?KNN 算法和距離定義相關(guān),我們需要對(duì)數(shù)據(jù)進(jìn)行規(guī)范化處理,采用 Z-Score 規(guī)范化,代碼如下:

    # 分割數(shù)據(jù),將25%的數(shù)據(jù)作為測(cè)試集,其余作為訓(xùn)練集(你也可以指定其他比例的數(shù)據(jù)作為訓(xùn)練集) train_x, test_x, train_y, test_y = train_test_split(data1, target1, test_size=0.25)# 采用z-score規(guī)范化 ss = StandardScaler() train_ss_scaled = ss.fit_transform(train_x) test_ss_scaled = ss.transform(test_x)# 采用0-1歸一化 mm = MinMaxScaler() train_mm_scaled = mm.fit_transform(train_x) test_mm_scaled = mm.transform(test_x)

    這里之所以用了0-1歸一化,是因?yàn)槎囗?xiàng)式樸素貝葉斯分類(lèi)這個(gè)模型,傳入的數(shù)據(jù)不能有負(fù)數(shù)。因?yàn)?Z-Score 會(huì)將數(shù)值規(guī)范化為一個(gè)標(biāo)準(zhǔn)的正態(tài)分布,即均值為 0,方差為 1,數(shù)值會(huì)包含負(fù)數(shù)。因此我們需要采用 Min-Max 規(guī)范化,將數(shù)據(jù)規(guī)范化到[0,1]范圍內(nèi)。

    • 建立模型,并進(jìn)行比較:這里構(gòu)造五個(gè)分類(lèi)器, 分別是K近鄰,SVM, 多項(xiàng)式樸素貝葉斯, 決策樹(shù)模型, AdaBoost模型。并分別看看他們的效果
      PS: 注意, 在做多項(xiàng)式樸素貝葉斯的時(shí)候,傳入的數(shù)據(jù)不能有負(fù)數(shù),由于Z-Score會(huì)將值歸一化一個(gè)標(biāo)準(zhǔn)的正態(tài)分布,會(huì)包含負(fù)數(shù),所以不能有這個(gè),采用MinMax歸一化到[0-1]范圍即可。

    models = {} models['knn'] = KNeighborsClassifier() models['svm'] = SVC() models['bayes'] = MultinomialNB() models['tree'] = DecisionTreeClassifier() models['ada'] = AdaBoostClassifier(base_estimator=models['tree'], learning_rate=0.1)for model_key in models.keys():if model_key == 'knn' or model_key == 'svm' or model_key == 'ada':model = models[model_key]model.fit(train_ss_scaled, train_y)predict = model.predict(test_ss_scaled)print(model_key, "準(zhǔn)確率:", accuracy_score(test_y, predict))else:model = models[model_key]model.fit(train_mm_scaled, train_y)predict = model.predict(test_mm_scaled)print(model_key, "準(zhǔn)確率: ", accuracy_score(test_y, predict))

    輸出結(jié)果:你能看出來(lái) KNN 的準(zhǔn)確率還是不錯(cuò)的,和 SVM 不相上下。并且竟然比AdaBoost效果都要好,而讓我納悶的是決策樹(shù)和AdaBoost怎么效果這么差,不可思議。后來(lái)我發(fā)現(xiàn)了,原來(lái)是樣本數(shù)量的問(wèn)題,我們最多數(shù)據(jù)集才1000多照片,數(shù)量太少了,AdaBoost的作用發(fā)揮不出來(lái),所以我記性了數(shù)據(jù)的擴(kuò)增,復(fù)制了三遍原來(lái)的數(shù)據(jù):

    data1 = np.vstack((data, data, data)) target1 = np.hstack((target, target, target))

    變成了5000多張數(shù)據(jù),然后再進(jìn)行測(cè)試,結(jié)果就是AdaBoost和tree的效果提升了,甚至可以和SVM效果媲美了:

    7. 總結(jié)

    好了,到這里就基本結(jié)束了,KNN不算太難,所以篇幅可能少了一些,但KNN還是挺好用的一個(gè)算法, 下面簡(jiǎn)單的總結(jié)一下:

    首先,就是通過(guò)電影分類(lèi)的例子,體會(huì)了一下什么是KNN,然后寫(xiě)了一下KNN的工作原理,主要問(wèn)題就是K值怎么選取?距離怎么衡量?

    然后,兩個(gè)小插曲KD樹(shù)和KNN做回歸。

    最后就是手寫(xiě)數(shù)字識(shí)別的實(shí)戰(zhàn),這個(gè)當(dāng)然也比較簡(jiǎn)單,然后就是對(duì)比了這幾個(gè)算法的效果。KNN在里面表現(xiàn)不錯(cuò),SVM算法處理這種問(wèn)題還是不錯(cuò),樣本較多的時(shí)候,集成的方式還是占據(jù)一定的優(yōu)勢(shì)。在這個(gè)過(guò)程中你應(yīng)該對(duì)數(shù)據(jù)探索、數(shù)據(jù)可視化、數(shù)據(jù)規(guī)范化、模型訓(xùn)練和結(jié)果評(píng)估的使用過(guò)程有了一定的體會(huì)。在數(shù)據(jù)量不大的情況下,使用 sklearn 還是方便的。

    參考:

    • http://note.youdao.com/noteshare?id=e753340eab85bb24b34ee45812b47ea1&sub=FE026DF879B7400F8DB196C8DE931238

    • http://note.youdao.com/noteshare?id=7ac08cc7ebdde0854ac3281923aeb5c0&sub=8072C6A29A3D4B00BB5316FFF676C1E2

    • http://note.youdao.com/noteshare?id=3e2f7f6d1147058dd4ca93bf03d0c338&sub=1686C728DD194617BDA9DFFF60049421

    個(gè)人公眾號(hào):AI蝸牛車(chē) 保持謙遜、保持自律、保持進(jìn)步往期精彩回顧適合初學(xué)者入門(mén)人工智能的路線及資料下載機(jī)器學(xué)習(xí)在線手冊(cè)深度學(xué)習(xí)在線手冊(cè)AI基礎(chǔ)下載(pdf更新到25集)本站qq群1003271085,加入微信群請(qǐng)回復(fù)“加群”獲取一折本站知識(shí)星球優(yōu)惠券,請(qǐng)回復(fù)“知識(shí)星球”喜歡文章,點(diǎn)個(gè)在看

    總結(jié)

    以上是生活随笔為你收集整理的【白话机器学习】算法理论+实战之K近邻算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。