机器学习算法系列之K近邻算法
本系列機器學(xué)習(xí)的文章打算從機器學(xué)習(xí)算法的一些理論知識、python實現(xiàn)該算法和調(diào)一些該算法的相應(yīng)包來實現(xiàn)。
目錄
K近鄰算法
一、K近鄰算法原理
k近鄰算法
通俗解釋
近鄰距離的度量
k值的選擇
KNN最近鄰分類算法的過程
?總結(jié)
二、利用K近鄰算法實現(xiàn)約會網(wǎng)站的匹配預(yù)測
三、sklearn實現(xiàn)鳶尾花的種類預(yù)測
K近鄰算法
一、K近鄰算法原理
k近鄰算法
k近鄰法(k-nearest neighbor)是一種基于回歸和分類的算法。k近鄰法的輸入為實例的特征向量,對應(yīng)于特征空間中的點;輸出為實例的類別,可以取多類。
通俗解釋
可以簡單粗暴的認為是:K個最近的鄰居,當(dāng)K=1時,算法便成了最近鄰算法,即尋找最近的那個鄰居。
用官方的話來說,所謂K近鄰算法,即是給定一個訓(xùn)練數(shù)據(jù)集,對新的輸入實例,在訓(xùn)練數(shù)據(jù)集中找到與該實例最鄰近的K個實例(也就是上面所說的K個鄰居),這K個實例的多數(shù)屬于某個類,就把該輸入實例分類到這個類中。
?
?
?
如上圖所示,有兩類不同的樣本數(shù)據(jù),分別用藍色的小正方形和紅色的小三角形表示,而圖正中間的那個綠色的圓所標(biāo)示的數(shù)據(jù)則是待分類的數(shù)據(jù)。也就是說,現(xiàn)在,我們不知道中間那個綠色的數(shù)據(jù)是從屬于哪一類(藍色小正方形or紅色小三角形),KNN就是解決這個問題的。
如果K=3,綠色圓點的最近的3個鄰居是2個紅色小三角形和1個藍色小正方形,少數(shù)從屬于多數(shù),基于統(tǒng)計的方法,判定綠色的這個待分類點屬于紅色的三角形一類。
如果K=5,綠色圓點的最近的5個鄰居是2個紅色三角形和3個藍色的正方形,還是少數(shù)從屬于多數(shù),基于統(tǒng)計的方法,判定綠色的這個待分類點屬于藍色的正方形一類。
?于此我們看到,當(dāng)無法判定當(dāng)前待分類點是從屬于已知分類中的哪一類時,我們可以依據(jù)統(tǒng)計學(xué)的理論看它所處的位置特征,衡量它周圍鄰居的權(quán)重,而把它歸為(或分配)到權(quán)重更大的那一類。這就是K近鄰算法的核心思想。
?
近鄰距離的度量
K近鄰算法的核心在于找到實例點的鄰居,這個時候,問題就接踵而至了,如何找到鄰居,鄰居的判定標(biāo)準(zhǔn)是什么,用什么來度量。這一系列問題便是下面要講的一些距離度量表示法。
1.歐式距離,最常見的兩點之間的距離表示方法,又稱為歐幾里得度量,
它定義于歐幾里得空間中,如點 x = (x1,...,xn) 和 y = (y1,...,yn) 之間的距離為:
二維平面上兩點a(x1,y1)與b(x2,y2)間的歐氏距離:
三維空間兩點a(x1,y1,z1)與b(x2,y2,z2)間的歐氏距離:
推廣到n維:也可以表示成向量的形式:
?
在k近鄰算法中通常用到的距離度量方視為歐式距離。
2.曼哈頓距離:在歐幾里得空間的固定直角坐標(biāo)系上兩點所形成的線段對軸產(chǎn)生的投影的距離總和。例如在平面上,坐標(biāo)(x1, y1)的點P1與坐標(biāo)(x2, y2)的點P2的曼哈頓距離為: ,要注意的是,曼哈頓距離依賴座標(biāo)系統(tǒng)的轉(zhuǎn)度,而非系統(tǒng)在座標(biāo)軸上的平移或映射。
二維平面兩點a(x1,y1)與b(x2,y2)間的曼哈頓距離:
兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的曼哈頓距離:
?
3.切比雪夫距離:
在平面幾何中,若二點p及q的直角坐標(biāo)系坐標(biāo)為(x1,y1)及(x2,y2),則切比雪夫距離為:
兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的切比雪夫距離:
這里就介紹這三種度量巨距離的方法,其他度量距離的方法還有閔可夫斯基距離、標(biāo)準(zhǔn)化歐式距離、馬氏距離等。
k值的選擇
在上面那幅圖中我們可以看到,當(dāng)k值選擇為3時,帶歸類的那個樣本就被歸類為紅色三角形一類;當(dāng)k值選擇為5時就被歸類為藍色正方形類。所以不同的k值對模型的歸類影響也會不一樣,這里需要選擇一個最恰當(dāng)?shù)膋值使得模型能夠更好的預(yù)測未知樣本。
一般而言,如果選擇較小的k值,就相當(dāng)于用較小的領(lǐng)域中的訓(xùn)練實例進行預(yù)測,“學(xué)習(xí)”近似誤差會減小,只有與輸入實例較近或者相似的訓(xùn)練實例才會對預(yù)測結(jié)果起作用,與此同時帶來的問題是“學(xué)習(xí)”的誤差估計會增大,換句話說:k值的減小就意味著整體模型會變得復(fù)雜,容易發(fā)生過擬合。
如果選擇較大的k值,就相當(dāng)于用較大的領(lǐng)域中的訓(xùn)練實例進行預(yù)測,其優(yōu)點是可以減少學(xué)習(xí)的估計誤差,但缺點是學(xué)習(xí)的近似誤差會變大。這時候,與輸入實例較遠(不相似)的訓(xùn)練實例也會起預(yù)測作用,使預(yù)測發(fā)生錯誤,且k值的增大也意味著整體的模型變得簡單。例如,當(dāng)k=n時,無論輸入什么實例,其預(yù)測結(jié)果都會是訓(xùn)練實例中最多的那一類了。完全失去了預(yù)測作用。
在實際應(yīng)用中,K值一般取一個比較小的數(shù)值,例如采用交叉驗證法(簡單來說,就是一部分樣本做訓(xùn)練集,一部分做測試集)來選擇最優(yōu)的K值。
?
KNN最近鄰分類算法的過程
K近鄰法的實現(xiàn):kd樹
實現(xiàn)k近鄰法時,主要考慮的問題是如何對訓(xùn)練數(shù)據(jù)進行快速k近鄰搜索
Kd-樹是K-dimension tree的縮寫,是對數(shù)據(jù)點在k維空間(如二維(x,y),三維(x,y,z),k維(x1,y,z..))中劃分的一種數(shù)據(jù)結(jié)構(gòu),主要應(yīng)用于多維空間關(guān)鍵數(shù)據(jù)的搜索(如:范圍搜索和最近鄰搜索)。。
首先必須搞清楚的是,k-d樹是一種空間劃分樹,說白了,就是把整個空間劃分為特定的幾個部分,然后在特定空間的部分內(nèi)進行相關(guān)搜索操作。想像一個三維空間,kd樹按照一定的劃分規(guī)則把這個三維空間劃分了多個空間,如下圖所示:
?kd樹算法構(gòu)建流程:
舉例:
6個二維數(shù)據(jù)點{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}構(gòu)建kd樹的具體步驟為:
與此同時,經(jīng)過對上面所示的空間劃分之后,我們可以看出,點(7,2)可以為根結(jié)點,從根結(jié)點出發(fā)的兩條紅粗斜線指向的(5,4)和(9,6)則為根結(jié)點的左右子結(jié)點,而(2,3),(4,7)則為(5,4)的左右孩子(通過兩條細紅斜線相連),最后,(8,1)為(9,6)的左孩子(通過細紅斜線相連)。如此,便形成了下面這樣一棵k-d樹:
?
?總結(jié)
1、k近鄰法三要素:距離度量、k值的選擇和分類決策規(guī)則.常用的距離度量是歐氏距離及更一般的Lp距離. k值小時,k近鄰模型更復(fù)雜; k值大時,k近鄰模型更簡單.k值的選擇反映了對近似誤差與估計誤差之間的權(quán)衡,通常由交叉驗證選擇最優(yōu)的k.常用的分類決策規(guī)則是多數(shù)表決,對應(yīng)于經(jīng)驗風(fēng)險最小化。
2、k近鄰模型對應(yīng)于基于訓(xùn)練數(shù)據(jù)集對特征空間的-一個劃分,k近鄰法中,當(dāng)訓(xùn)練集、距離度量、k值及分類決策規(guī)則確定后,其結(jié)果唯一-確定。
3、k近鄰法的實現(xiàn)需要考慮如何快速搜索k個最近鄰點,kd樹是一種便于對k維空間中的數(shù)據(jù)進行快速檢索的數(shù)據(jù)結(jié)構(gòu)。kd 樹是二叉樹,表示對k維空間的一個劃分,其每個結(jié)點對應(yīng)于k維空間劃分中的一個超矩形區(qū)域。利用kd樹可以省去對大部分?jǐn)?shù)據(jù)點的搜索,從而減少搜索的計算量。
二、利用K近鄰算法實現(xiàn)約會網(wǎng)站的匹配預(yù)測
背景:一個經(jīng)常使用約會網(wǎng)站尋找適合自己的對象的海倫,但是依舊沒有從中找到自己喜歡的人。經(jīng)過一番總結(jié),她發(fā)現(xiàn)自己曾經(jīng)交往過三種類型的人:不喜歡的人、魅力一般的人、極具魅力的人。此外海倫還收集了一些約會網(wǎng)站未曾記錄的數(shù)據(jù)信息。
數(shù)據(jù)信息:第一列:每年獲得的飛行常客里程數(shù);第二列:玩游戲耗時的百分比;第三列:每周消耗的奶茶升數(shù)。
第四列:喜歡程度(didntLike、smallDoses、largeDoses)
飛行常客里程數(shù):飛行常客計劃(也稱:飛行常客獎勵計劃)是航空公司給忠實乘客的一種獎勵,普遍的形式是:乘客們通過這個計劃累計自己的飛行里程,并使用這些里程來兌換免費的機票、商品和服務(wù)以及其他類似貴賓休息室或優(yōu)先值機之類的特權(quán)。
40920 8.326976 0.953952 largeDoses 14488 7.153469 1.673904 smallDoses 26052 1.441871 0.805124 didntLike 75136 13.147394 0.428964 didntLike 38344 1.669788 0.134296 didntLike 72993 10.141740 1.032955 didntLike 35948 6.830792 1.213192 largeDoses 42666 13.276369 0.543880 largeDoses 67497 8.631577 0.749278 didntLike 35483 12.273169 1.508053 largeDoses 50242 3.723498 0.831917 didntLike 63275 8.385879 1.669485 didntLike 5569 4.875435 0.728658 smallDoses 51052 4.680098 0.625224 didntLike 77372 15.299570 0.331351 didntLike 43673 1.889461 0.191283 didntLike 61364 7.516754 1.269164 didntLike 69673 14.239195 0.261333 didntLike 15669 0.000000 1.250185 smallDoses 28488 10.528555 1.304844 largeDoses 6487 3.540265 0.822483 smallDoses代碼:
# -*- coding: utf-8 -*-from matplotlib.font_manager import FontProperties import matplotlib.lines as mlines import matplotlib.pyplot as plt import time import numpy as np import operator""" 函數(shù)說明:kNN算法,分類器Parameters:inX - 用于分類的數(shù)據(jù)(測試集)dataSet - 用于訓(xùn)練的數(shù)據(jù)(訓(xùn)練集)(n*1維列向量)labels - 分類標(biāo)準(zhǔn)(n*1維列向量)k - kNN算法參數(shù),選擇距離最小的k個點Returns:sortedClassCount[0][0] - 分類結(jié)果"""def classify0(inX, dataSet, labels, k):# numpy函數(shù)shape[0]返回dataSet的行數(shù)dataSetSize = dataSet.shape[0]# 將inX重復(fù)dataSetSize次并排成一列diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet# 二維特征相減后平方(用diffMat的轉(zhuǎn)置乘diffMat)sqDiffMat = diffMat ** 2# sum()所有元素相加,sum(0)列相加,sum(1)行相加sqDistances = sqDiffMat.sum(axis=1)# 開方,計算出距離distances = sqDistances ** 0.5# argsort函數(shù)返回的是distances值從小到大的--索引值sortedDistIndicies = distances.argsort()# 定義一個記錄類別次數(shù)的字典classCount = {}# 選擇距離最小的k個點for i in range(k):# 取出前k個元素的類別voteIlabel = labels[sortedDistIndicies[i]]# 字典的get()方法,返回指定鍵的值,如果值不在字典中返回0# 計算類別次數(shù)classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1# python3中用items()替換python2中的iteritems()# key = operator.itemgetter(1)根據(jù)字典的值進行排序# key = operator.itemgetter(0)根據(jù)字典的鍵進行排序# reverse降序排序字典sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)# 返回次數(shù)最多的類別,即所要分類的類別return sortedClassCount[0][0]""" 函數(shù)說明:打開解析文件,對數(shù)據(jù)進行分類,1代表不喜歡,2代表魅力一般,3代表極具魅力Parameters:filename - 文件名Returns:returnMat - 特征矩陣classLabelVector - 分類label向量"""def file2matrix(filename):# 打開文件fr = open(filename)# 讀取文件所有內(nèi)容arrayOlines = fr.readlines()# 得到文件行數(shù)numberOfLines = len(arrayOlines)# 返回的NumPy矩陣numberOfLines行,3列returnMat = np.zeros((numberOfLines, 3))# 創(chuàng)建分類標(biāo)簽向量classLabelVector = []# 行的索引值index = 0# 讀取每一行for line in arrayOlines:# 去掉每一行首尾的空白符,例如'\n','\r','\t',' 'line = line.strip()# 將每一行內(nèi)容根據(jù)'\t'符進行切片,本例中一共有4列l(wèi)istFromLine = line.split('\t')# 將數(shù)據(jù)的前3列進行提取保存在returnMat矩陣中,也就是特征矩陣returnMat[index, :] = listFromLine[0:3]# 根據(jù)文本內(nèi)容進行分類1:不喜歡;2:一般;3:喜歡if listFromLine[-1] == 'didntLike':classLabelVector.append(1)elif listFromLine[-1] == 'smallDoses':classLabelVector.append(2)elif listFromLine[-1] == 'largeDoses':classLabelVector.append(3)index += 1# 返回標(biāo)簽列向量以及特征矩陣return returnMat, classLabelVector""" 函數(shù)說明:可視化數(shù)據(jù)Parameters:datingDataMat - 特征矩陣datingLabels - 分類LabelReturns:None"""def showdatas(datingDataMat, datingLabels):# 設(shè)置漢字格式為14號簡體字font = FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc", size=14)# 將fig畫布分隔成1行1列,不共享x軸和y軸,fig畫布的大小為(13,8)# 當(dāng)nrows=2,ncols=2時,代表fig畫布被分為4個區(qū)域,axs[0][0]代表第一行第一個區(qū)域fig, axs = plt.subplots(nrows=2, ncols=2, sharex=False, sharey=False, figsize=(13, 8))# 獲取datingLabels的行數(shù)作為label的個數(shù)# numberOfLabels = len(datingLabels)# label的顏色配置矩陣LabelsColors = []for i in datingLabels:# didntLikeif i == 1:LabelsColors.append('black')# smallDosesif i == 2:LabelsColors.append('orange')# largeDosesif i == 3:LabelsColors.append('red')# 畫出散點圖,以datingDataMat矩陣第一列為x,第二列為y,散點大小為15, 透明度為0.5axs[0][0].scatter(x=datingDataMat[:, 0], y=datingDataMat[:, 1], color=LabelsColors, s=15, alpha=.5)# 設(shè)置標(biāo)題,x軸label, y軸labelaxs0_title_text = axs[0][0].set_title(u'每年獲得的飛行常客里程數(shù)與玩視頻游戲所消耗時間占比', FontProperties=font)axs0_xlabel_text = axs[0][0].set_xlabel(u'每年獲得的飛行常客里程數(shù)', FontProperties=font)axs0_ylabel_text = axs[0][0].set_ylabel(u'玩視頻游戲所消耗時間占比', FontProperties=font)plt.setp(axs0_title_text, size=9, weight='bold', color='red')plt.setp(axs0_xlabel_text, size=7, weight='bold', color='black')plt.setp(axs0_ylabel_text, size=7, weight='bold', color='black')# 畫出散點圖,以datingDataMat矩陣第一列為x,第三列為y,散點大小為15, 透明度為0.5axs[0][1].scatter(x=datingDataMat[:, 0], y=datingDataMat[:, 2], color=LabelsColors, s=15, alpha=.5)# 設(shè)置標(biāo)題,x軸label, y軸labelaxs1_title_text = axs[0][1].set_title(u'每年獲得的飛行常客里程數(shù)與每周消費的冰淇淋公升數(shù)', FontProperties=font)axs1_xlabel_text = axs[0][1].set_xlabel(u'每年獲得的飛行常客里程數(shù)', FontProperties=font)axs1_ylabel_text = axs[0][1].set_ylabel(u'每周消費的冰淇淋公升數(shù)', FontProperties=font)plt.setp(axs1_title_text, size=9, weight='bold', color='red')plt.setp(axs1_xlabel_text, size=7, weight='bold', color='black')plt.setp(axs1_ylabel_text, size=7, weight='bold', color='black')# 畫出散點圖,以datingDataMat矩陣第二列為x,第三列為y,散點大小為15, 透明度為0.5axs[1][0].scatter(x=datingDataMat[:, 1], y=datingDataMat[:, 2], color=LabelsColors, s=15, alpha=.5)# 設(shè)置標(biāo)題,x軸label, y軸labelaxs2_title_text = axs[1][0].set_title(u'玩視頻游戲所消耗時間占比與每周消費的冰淇淋公升數(shù)', FontProperties=font)axs2_xlabel_text = axs[1][0].set_xlabel(u'玩視頻游戲所消耗時間占比', FontProperties=font)axs2_ylabel_text = axs[1][0].set_ylabel(u'每周消費的冰淇淋公升數(shù)', FontProperties=font)plt.setp(axs2_title_text, size=9, weight='bold', color='red')plt.setp(axs2_xlabel_text, size=7, weight='bold', color='black')plt.setp(axs2_ylabel_text, size=7, weight='bold', color='black')# 設(shè)置圖例didntLike = mlines.Line2D([], [], color='black', marker='.', markersize=6, label='didntLike')smallDoses = mlines.Line2D([], [], color='orange', marker='.', markersize=6, label='smallDoses')largeDoses = mlines.Line2D([], [], color='red', marker='.', markersize=6, label='largeDoses')# 添加圖例axs[0][0].legend(handles=[didntLike, smallDoses, largeDoses])axs[0][1].legend(handles=[didntLike, smallDoses, largeDoses])axs[1][0].legend(handles=[didntLike, smallDoses, largeDoses])# 顯示圖片plt.show()""" 函數(shù)說明:對數(shù)據(jù)進行歸一化Parameters:dataSet - 特征矩陣Returns:normDataSet - 歸一化后的特征矩陣ranges - 數(shù)據(jù)范圍minVals - 數(shù)據(jù)最小值"""def autoNorm(dataSet):# 獲取數(shù)據(jù)的最小值minVals = dataSet.min(0)# 獲取數(shù)據(jù)的最大值maxVals = dataSet.max(0)# 最大值和最小值的范圍ranges = maxVals - minVals# shape(dataSet)返回dataSet的矩陣行列數(shù)normDataSet = np.zeros(np.shape(dataSet))# numpy函數(shù)shape[0]返回dataSet的行數(shù)m = dataSet.shape[0]# 原始值減去最小值(x-xmin)normDataSet = dataSet - np.tile(minVals, (m, 1))# 差值處以最大值和最小值的差值(x-xmin)/(xmax-xmin)normDataSet = normDataSet / np.tile(ranges, (m, 1))# 歸一化數(shù)據(jù)結(jié)果,數(shù)據(jù)范圍,最小值return normDataSet, ranges, minVals""" 函數(shù)說明:分類器測試函數(shù)Parameters:NoneReturns:normDataSet - 歸一化后的特征矩陣ranges - 數(shù)據(jù)范圍minVals - 數(shù)據(jù)最小值"""def datingClassTest():# 打開文件名filename = "datingTestSet.txt"# 將返回的特征矩陣和分類向量分別存儲到datingDataMat和datingLabels中datingDataMat, datingLabels = file2matrix(filename)# 取所有數(shù)據(jù)的10% hoRatio越小,錯誤率越低hoRatio = 0.10# 數(shù)據(jù)歸一化,返回歸一化數(shù)據(jù)結(jié)果,數(shù)據(jù)范圍,最小值normMat, ranges, minVals = autoNorm(datingDataMat)# 獲取normMat的行數(shù)m = normMat.shape[0]# 10%的測試數(shù)據(jù)的個數(shù)numTestVecs = int(m * hoRatio)# 分類錯誤計數(shù)errorCount = 0.0for i in range(numTestVecs):# 前numTestVecs個數(shù)據(jù)作為測試集,后m-numTestVecs個數(shù)據(jù)作為訓(xùn)練集# k選擇label數(shù)+1(結(jié)果比較好)classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], \datingLabels[numTestVecs:m], 4)print("分類結(jié)果:%d\t真實類別:%d" % (classifierResult, datingLabels[i]))if classifierResult != datingLabels[i]:errorCount += 1.0print("錯誤率:%f%%" % (errorCount / float(numTestVecs) * 100))""" 函數(shù)說明:通過輸入一個人的三圍特征,進行分類輸出Parameters:NoneReturns:None"""def classifyPerson():# 輸出結(jié)果resultList = ['不喜歡', '有些喜歡', '非常喜歡']# 三維特征用戶輸入income = float(input("每年獲得的飛行常客里程數(shù):"))percentTats = float(input("玩視頻游戲所消耗時間百分比:"))milkTea = float(input("每周消費的奶茶公升數(shù):"))# 打開的文件名filename = "datingTestSet.txt"# 打開并處理數(shù)據(jù)datingDataMat, datingLabels = file2matrix(filename)# 訓(xùn)練集歸一化normMat, ranges, minVals = autoNorm(datingDataMat)# 生成NumPy數(shù)組,測試集inArr = np.array([income,percentTats , milkTea])# 測試集歸一化norminArr = (inArr - minVals) / ranges# 返回分類結(jié)果classifierResult = classify0(norminArr, normMat, datingLabels, 4)# 打印結(jié)果print("你可能%s這個人" % (resultList[classifierResult - 1]))""" 函數(shù)說明:main函數(shù)Parameters:NoneReturns:None"""def main():# 獲取程序運行時間start = time.clock()# 打開文件的名稱filename = "datingTestSet.txt"# 打開并處理數(shù)據(jù)datingDataMat, datingLabels = file2matrix(filename)# 訓(xùn)練集歸一化normDataset, ranges, minVals = autoNorm(datingDataMat)datingClassTest()# print(normDataset)# print(ranges)# print(minVals)showdatas(datingDataMat, datingLabels)classifyPerson()# print(datingDataMat)# print(datingLabels)# 創(chuàng)建數(shù)據(jù)集# group, labels = createDataSet()# 測試集# test = [100,100]# kNN分類# test_class = classify0(test, group, labels, 3)# 打印分類結(jié)果# print(test_class)end = time.clock()# 打印程序運行時間print('Running time: %f Seconds' % (end - start))if __name__ == '__main__':main()程序運行結(jié)果:
可以看到當(dāng)預(yù)測出這個對象可能海倫將會非常喜歡(畢竟條件確實比較好,hhhh)?
三、sklearn實現(xiàn)鳶尾花的種類預(yù)測
?
數(shù)據(jù)集介紹
在Sklearn機器學(xué)習(xí)包中,集成了各種各樣的數(shù)據(jù)集,包括前面的糖尿病數(shù)據(jù)集,這里引入的是鳶尾花卉(Iris)數(shù)據(jù)集,它是很常用的一個數(shù)據(jù)集。鳶尾花有三個亞屬,分別是山鳶尾(Iris-setosa)、變色鳶尾(Iris-versicolor)和維吉尼亞鳶尾(Iris-virginica)。
該數(shù)據(jù)集一共包含4個特征變量,1個類別變量。共有150個樣本,iris是鳶尾植物,這里存儲了其萼片和花瓣的長寬,共4個屬性,鳶尾植物分三類。如表所示:
#!/usr/bin/env python # -*- coding:utf-8 -*- from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split import pandas as pd import numpy as np from pandas.plotting import scatter_matrix import mglearn import matplotlib.pyplot as plt from sklearn.neighbors import KNeighborsClassifier iris_dataset = load_iris() X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0) iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names) # 利用DataFrame創(chuàng)建散點圖矩陣,按照y_train著色 grr = scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o',hist_kwds={'bins': 20}, s=60, alpha=.8, cmap=mglearn.cm3) plt.show() knn = KNeighborsClassifier(n_neighbors=3) knn.fit(X_train, y_train) X_new = np.array([[5, 2.9, 1, 0.2]]) print("X_new: {}".format(X_new)) prediction = knn.predict(X_new) print("Prediction: {}".format(prediction)) print("Predicted target name: {}".format(iris_dataset['target_names'][prediction])) # 模型評價 print("Test set score: {:.2f}".format(knn.score(X_test, y_test))) 輸出結(jié)果 X_new: [[5. 2.9 1. 0.2]] Prediction: [0] Predicted target name: ['setosa'] Test set score: 0.97可以看出預(yù)測的花的結(jié)果為'setosa'(山鳶尾),且在測試集上的準(zhǔn)確率為97%。
?
總結(jié)
以上是生活随笔為你收集整理的机器学习算法系列之K近邻算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: foxit pdf editor lin
- 下一篇: PPT插入计时器