吶你們要的算法(一)No.17

我是小蕉萍恕。

今天跟大家分享一下,機器學習中最簡單的算法之一车要,KNN近鄰算法允粤,這是一個有監(jiān)督的分類學習算法。

啥玩意叫有監(jiān)督呢?就是作為訓練的每個樣本都是有標記的类垫,比如樣本1是A類绳姨,樣本2是B類,這樣的有標記的樣本阔挠。而什么叫分類呢?輸出結(jié)果是離散的脑蠕,可窮盡的购撼,就叫分類。

KNN近鄰算法的核心思想是:

近朱者赤谴仙,近墨者黑迂求,選K而取其最大可能。

從哪開始聊呢晃跺?先從算法的核心過程開始吧揩局。

準備基本數(shù)據(jù)集 -> 計算待測試樣本整個數(shù)據(jù)集所有數(shù)據(jù)的距離 -> 根據(jù)距離進行排序 ->獲取前K個樣本,將他們的標簽進行統(tǒng)計 -> 獲取頻次最大的標簽作為結(jié)果輸出

舉個栗子:我想知道我現(xiàn)在最可能處于哪個小區(qū)掀虎,我們假設(shè)小區(qū)都一樣大凌盯。

我得到了一批小區(qū)的GPS定位經(jīng)緯度 -> 我得到了我自己的GPS經(jīng)緯度 -> 計算出我跟所有這些小區(qū)的距離,然后排序一下 ?-> 拿到前K個距離的樣本烹玉,對他們的小區(qū)名稱進行統(tǒng)計 -> bingo驰怎,頻次最大的那個小區(qū)就可能是我的小區(qū)了。

聽起來蠻簡單的二打,但是在實際操作過程中會遇到幾個問題县忌。如果基礎(chǔ)樣本數(shù)太多,該如何計算出所有的距離继效?如果不是空間距離症杏,比如是兩個文本,如何衡量兩個實體之間的距離瑞信?取K個樣本厉颤,那么K取多少對于結(jié)果比較好?

這些是我們作為使用者需要去考慮的事情凡简,模型本身不考慮這個東西走芋。就開放性地把問題拋出來吧,大家都思考思考潘鲫。

用一個識別手寫數(shù)字的例子來分享一下這個算法吧翁逞,代碼自己寫的,但是例子是書上的溉仑,輕噴挖函。首先我們的數(shù)據(jù)長下面這樣子,32*32的1024個像素的圖片浊竟,都是手寫的怨喘。

這是數(shù)字1


這是數(shù)字0


先定義一個函數(shù)津畸,參數(shù)inX是要用來計算的向量,dataSet是測試數(shù)據(jù)集必怜,labels是與dataSet一一對應(yīng)的標簽值肉拓,k是我們想獲取的前k個樣本的數(shù)值。

defclassify0(inX, dataSet, labels, k):

#獲得數(shù)據(jù)集的行數(shù)

dataSetSize = dataSet.shape[0]

#渲染出一個矩陣梳庆,行數(shù)跟dataSet行數(shù)一樣暖途,每一行都是要計算的圖片

diffMat = tile(inX, (dataSetSize,1)) - dataSet

#然后計算出(Xn - Xi)^2 每個維度的坐標的相見的值

#這里使用的是歐拉距離來衡量兩個圖片之間的距離

sqDiffMat = diffMat**2

#每一個值相加,再進行開方膏执,得到N維空間的距離sqDistances = sqDiffMat.sum(axis=1)

distances = sqDistances**0.5

#根據(jù)距離進行降序排序驻售,獲取前K個標簽進行頻次統(tǒng)計,然后取最大的那個sortedDistIndicies = distances.argsort()

classCount={}

foriinrange(k):

voteIlabel = labels[sortedDistIndicies[i]]

classCount[voteIlabel] = classCount.get(voteIlabel,0) +1

sortedClassCount =sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)

returnsortedClassCount[0][0]

嘛更米,核心的分類算法就這樣實現(xiàn)完了欺栗,不難,好好看看應(yīng)該能看懂征峦,最好自己寫一遍迟几。算法的主要思想就是把我們要計算的問題轉(zhuǎn)變成能衡量距離的向量,然后計算向量之間的距離栏笆,用近朱者赤的觀點來進行標簽選擇瘤旨。

下面是一點工具類。這個函數(shù)是將一個文件轉(zhuǎn)變成向量的工具竖伯,因為我們這里是文本所以直接用遍歷的方式存哲,這里比較原始,可以使用numpy等工具來進行矩陣的渲染七婴。

defimg2Vector(fileName):

returnVect = zeros((1,1024))

fr =open(fileName)

foriinrange(32):

lineStr = fr.readline()

forjinrange(32):

returnVect[0,32*i+j] =int(lineStr[j])

returnreturnVect

如果是真正的圖片祟偷,我們可以用img庫來進行轉(zhuǎn)換,轉(zhuǎn)換完的矩陣會有三個通道打厘,RGB修肠,而且每個通道的每個像素都0-255。有幾百萬像素就有幾百萬的像素點户盯。

我們有一堆文本來訓練和測試這個模型嵌施。下面是測試方法,我就不細說了莽鸭。公眾號回復吗伤,"KNN",所有的東西都下載去玩一玩硫眨,超好玩足淆。我寫完都震驚了一下,原來識別手寫體,最簡單的還能這樣識別巧号,還有這種操作W迳荨!



defhandWriterClassTest():

hwLabels = []

traningFileList = listdir('trainingDigits')

m =len(traningFileList)

traningMat = zeros((m,1024))

foriinrange(m):

fileNameStr = traningFileList[i]

fileStr = fileNameStr.split('.')[0]

classNumStr =int(fileStr.split('_')[0])

hwLabels.append(classNumStr)

traningMat[i,:] = img2Vector('trainingDigits/%s'% fileNameStr)

testFileList = listdir('testDigits')

errorCount =0.0

mTest =len(testFileList)

foriinrange(mTest):

fileNameStr = testFileList[i]

fileStr = fileNameStr.split('.')[0]

classNumStr =int(fileStr.split('_')[0])

vectorUnderTest= img2Vector('testDigits/%s'% fileNameStr)

classiFierResult = classify0(vectorUnderTest, traningMat, hwLabels,3)

print"the classifier came back with:%d , the real answer is: %d"% (classiFierResult,classNumStr)

if(classiFierResult != classNumStr):

errorCount +=1.0

print"\nthe total numer of Error is: % d ,the error rate is: %f"% (errorCount,(errorCount/float(mTest)))

測試的結(jié)果準確度大概在98.8%這樣子丹鸿,在這個數(shù)據(jù)集上效果還是不錯的越走,作為一個入門級算法。好了有什么好玩的大家再一次分享吧靠欢。什么你問歐拉距離是什么廊敌??是他是他就是他掺涛。


好了就醬~各位親,賞了我是看不到是誰的喔疼进,最好留言一下薪缆,我好好好答謝一下。

感謝各位大大日成」悖互舔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拣帽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嚼锄,更是在濱河造成了極大的恐慌减拭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件区丑,死亡現(xiàn)場離奇詭異拧粪,居然都是意外死亡,警方通過查閱死者的電腦和手機沧侥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門可霎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宴杀,你說我怎么就攤上這事癣朗。” “怎么了旺罢?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵旷余,是天一觀的道長。 經(jīng)常有香客問我扁达,道長正卧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任跪解,我火速辦了婚禮穗酥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己砾跃,他們只是感情好骏啰,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抽高,像睡著了一般判耕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翘骂,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天壁熄,我揣著相機與錄音,去河邊找鬼碳竟。 笑死草丧,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的莹桅。 我是一名探鬼主播昌执,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诈泼!你這毒婦竟也來了懂拾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤铐达,失蹤者是張志新(化名)和其女友劉穎岖赋,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓮孙,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡唐断,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杭抠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栗涂。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖祈争,靈堂內(nèi)的尸體忽然破棺而出斤程,到底是詐尸還是另有隱情,我是刑警寧澤菩混,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布忿墅,位于F島的核電站,受9級特大地震影響沮峡,放射性物質(zhì)發(fā)生泄漏疚脐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一邢疙、第九天 我趴在偏房一處隱蔽的房頂上張望棍弄。 院中可真熱鬧望薄,春花似錦、人聲如沸呼畸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛮原。三九已至卧须,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間儒陨,已是汗流浹背花嘶。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蹦漠,地道東北人椭员。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像笛园,于是被迫代替她去往敵國和親隘击。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容