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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

机器学习笔记1(K-近邻算法)

發(fā)布時(shí)間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习笔记1(K-近邻算法) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

人生苦短,我用Python

K-近鄰算法:簡(jiǎn)單來說,K-近鄰算法就是采用測(cè)量不同特征值之間的距離方法進(jìn)行分類

  • 優(yōu)點(diǎn):精度高、對(duì)異常值不敏感、無數(shù)據(jù)輸入假定
  • 缺點(diǎn):計(jì)算復(fù)雜度高、空間復(fù)雜度高
  • 適用范圍:數(shù)值型、標(biāo)稱型

工作原理:

存在一個(gè)樣本數(shù)據(jù)集合,也稱作訓(xùn)練樣本集,并且樣本集中每個(gè)數(shù)據(jù)都存在標(biāo)簽,即我們知道樣本集中每一個(gè)數(shù)據(jù)與所屬分類的對(duì)應(yīng)關(guān)系。輸入沒有標(biāo)簽的新數(shù)據(jù)后,將新數(shù)據(jù)的每個(gè)特征與樣本集中數(shù)據(jù)對(duì)應(yīng)的特征進(jìn)行比較,然后算法提取樣本集中特征最相似的數(shù)據(jù)(最近鄰)的分類標(biāo)簽。一般來說,我們只選擇樣本集中前K個(gè)最相似的數(shù)據(jù),這就是K-近鄰算法中K的出處,通常K是不大于20的整數(shù)。最后,選擇K個(gè)最相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類,作為新數(shù)據(jù)的分類。

K-近鄰算法的一般流程:

  • 收集數(shù)據(jù):可以使用任何方法。
  • 準(zhǔn)備數(shù)據(jù):距離計(jì)算所需要的數(shù)值,最好是結(jié)構(gòu)化的數(shù)據(jù)格式。
  • 分析數(shù)據(jù):可以使用任何方法。
  • 訓(xùn)練算法:此步驟不適用于K-近鄰算法。
  • 測(cè)試算法:計(jì)算錯(cuò)誤率。
  • 使用算法:首先需要輸入樣本數(shù)據(jù)和結(jié)構(gòu)化的輸出結(jié)果,然后運(yùn)行K-近鄰算法判定輸入數(shù)據(jù)分別屬于哪個(gè)分類,最后應(yīng)用對(duì)計(jì)算出的分類執(zhí)行后續(xù)的處理。
  • 實(shí)施KNN分類算法--偽代碼

    對(duì)未知類別屬性的數(shù)據(jù)集中的每個(gè)點(diǎn)依次執(zhí)行以下操作:

  • 計(jì)算已知類別數(shù)據(jù)集中的點(diǎn)與當(dāng)前點(diǎn)之間的距離;
  • 按照距離遞增次序排序;
  • 選取與當(dāng)前點(diǎn)距離最小的K個(gè)點(diǎn);
  • 確定前K個(gè)點(diǎn)所在類別的出現(xiàn)頻率;
  • 返回前K個(gè)點(diǎn)出現(xiàn)頻率最高的類別作為當(dāng)前點(diǎn)的預(yù)測(cè)分類;
  • 計(jì)算兩個(gè)向量點(diǎn)之間的距離公式--歐式距離公式:

    例如:點(diǎn)(0,0)與(1,2)之間的距離計(jì)算為:

    sqrt((1-0)**2+(2-0)**2)

    代碼實(shí)現(xiàn):

    import numpy as np import operator """ def CreateDataSet():group=np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels=['A','A','B','B']return group,labels print(CreateDataSet()) """ """ inX--用于分類的輸入向量 dataSet--輸入的訓(xùn)練樣本集 labels--標(biāo)簽向量 k--用于選擇最近鄰居的數(shù)目 其中標(biāo)簽向量的元素?cái)?shù)目和矩陣dataSet的行數(shù)相同 """ def classify(inX,dataSet,labels,k):dataSetSize=dataSet.shape[0] #獲得訓(xùn)練樣本集的行數(shù)#將輸入向量在列方向重復(fù)一次,在行方向上dataSize次,并與訓(xùn)練樣本集dataSet相減diffMat=np.tile(inX,(dataSetSize,1))-dataSetprint("diffMat:")print(diffMat)#將相減后的集合進(jìn)行平方運(yùn)算sqDiffMat=diffMat**2print("sqDiffMat:")print(sqDiffMat)#對(duì)平方后的集合進(jìn)行相加運(yùn)算--按行相加sqDistances=sqDiffMat.sum(axis=1)print("sqDistances:")print(sqDistances)#對(duì)相加后的數(shù)據(jù)開平方,得到輸入向量與每個(gè)訓(xùn)練樣本集之間的距離值distances=np.sqrt(sqDistances)print("distances")print(distances)#返回?cái)?shù)組從小到大的索引值--排序sortedDistIndicies=np.argsort(distances)print("sortedDistIndicies")print(sortedDistIndicies)classCount={}for i in range(k):voteIlabel=labels[sortedDistIndicies[i]]print("voteIlabel"+str(i))print(voteIlabel)classCount[voteIlabel]=classCount.get(voteIlabel,0)+1print("classCount"+str(i))print(classCount)sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)print("sortedClassCount:")print(sortedClassCount)return sortedClassCount[0][0]if __name__=='__main__':#訓(xùn)練樣本集group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])#標(biāo)簽向量labels = ['A', 'A', 'B', 'B']#輸入向量inX=[0,0]#用于選擇最近鄰居的數(shù)目k=3result=classify(inX,group,labels,k)print(result)""" 輸出值: diffMat: [[-1. -1.1][-1. -1. ][ 0. 0. ][ 0. -0.1]] sqDiffMat: [[ 1. 1.21][ 1. 1. ][ 0. 0. ][ 0. 0.01]] sqDistances: [ 2.21 2. 0. 0.01] distances [ 1.48660687 1.41421356 0. 0.1 ] sortedDistIndicies [2 3 1 0] voteIlabel0 B classCount0 {'B': 1} voteIlabel1 B classCount1 {'B': 2} voteIlabel2 A classCount2 {'B': 2, 'A': 1} sortedClassCount: [('B', 2), ('A', 1)] BProcess finished with exit code 0 """復(fù)制代碼

    測(cè)試結(jié)果:

    輸入[0,0],經(jīng)過測(cè)試后,返回的結(jié)果是B,也就是說[0,0]這個(gè)輸入向量通過K-近鄰算法分類后歸為B類


    示例:使用K-近鄰算法改進(jìn)約會(huì)網(wǎng)站的配對(duì)效果

  • 收集數(shù)據(jù):提供文本文件
  • 準(zhǔn)備數(shù)據(jù):使用Python解析文本文件
  • 分析數(shù)據(jù):使用Matplotlib畫二維擴(kuò)散圖
  • 訓(xùn)練算法:此步驟不適用與K-近鄰算法
  • 測(cè)試算法:使用海倫提供的部分?jǐn)?shù)據(jù)作為測(cè)試樣本
  • 測(cè)試樣本和非測(cè)試的區(qū)別在于:測(cè)試樣本是已經(jīng)完成分類的數(shù)據(jù),如果預(yù)測(cè)分類與實(shí)際類別不同,則標(biāo)記為一個(gè)錯(cuò)誤。
  • 使用算法:產(chǎn)生簡(jiǎn)單的命令行程序,然后可以輸入一些特征數(shù)據(jù)以判斷對(duì)方是否是自己喜歡的類型
  • 準(zhǔn)備數(shù)據(jù):從文本文件中解析數(shù)據(jù)

    文本樣本數(shù)據(jù)特征:

    • 每年獲得的飛行常客里程數(shù)
    • 玩視頻游戲所耗時(shí)間的百分比
    • 每周消費(fèi)的冰淇淋公升數(shù)

    將文本記錄轉(zhuǎn)換為numpy數(shù)據(jù)的解析程序:

    def file2matrix(filename):# 打開文件fr = open(filename, 'r', encoding='utf-8')# 按行讀取數(shù)據(jù)arrayOLines = fr.readlines()# 獲取數(shù)據(jù)的行數(shù)numberOfLines = len(arrayOLines)# 創(chuàng)建以0填充的矩陣returnMat = np.zeros((numberOfLines, 3))print(returnMat)classLabelVector = []index = 0for line in arrayOLines:print(line)# 截取掉所有回車字符line = line.strip()print(line)# 以'\t'將line分割成一個(gè)元素列表listFromLine = line.split('\t')# 選取前三個(gè)元素,存儲(chǔ)到特征矩陣中returnMat[index, :] = listFromLine[0:3]# 選取最后一個(gè)元素存儲(chǔ)到標(biāo)簽向量中classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector datingDataMat,datingLabels=file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt') fig=plt.figure() plt.title('K-') plt.xlabel('fly') plt.ylabel('consume') ax=fig.add_subplot(111)ax.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*np.array(datingLabels),15.0*np.array(datingLabels)) plt.show()復(fù)制代碼

    特別說明:代碼中的資源文件可以在此處下載:LiuGuoJiang/machinelearninginaction

    解析文本數(shù)據(jù)并用散點(diǎn)圖展示:


    準(zhǔn)備數(shù)據(jù):歸一化數(shù)值

    任選樣本數(shù)據(jù)中一行數(shù)據(jù),計(jì)算距離時(shí),因?yàn)轱w行常客里程數(shù)比較大,所以對(duì)最后計(jì)算結(jié)果影響過大,所以需要對(duì)數(shù)據(jù)做歸一化處理。如將取值范圍處理為0~1或者-1~1之間。下面的公式可以將任意取值范圍的特征值轉(zhuǎn)化為0~1區(qū)間內(nèi)的值:

    newValue=(oldValue-min)/(max-min)

    • 其中min和max分別是數(shù)據(jù)集中的最小特征值和最大特征值。

    歸一化特征值函數(shù):

    def autoNorm(dataSet):#選取列的最小值minVals=dataSet.min(0)#選取列的最大值maxVals=dataSet.max(0)#列的最大值與最小值做減法ranges=maxVals-minVals#normDataSet=np.zeros([dataSet.shape[0],dataSet.shape[1]])print(normDataSet)#取出dataSet的行數(shù)m=dataSet.shape[0]#np.tile(minVals,(m,1))將minVals在 列上重復(fù)一次,在行上重復(fù)m次normDataSet=dataSet-np.tile(minVals,(m,1)) #(oldValue-min)normDataSet=normDataSet/np.tile(ranges,(m,1)) #(oldValue-min)/(max-min)return normDataSet,ranges,minValsnormDataSet,ranges,minVals=autoNorm(datingDataMat) print(normDataSet)復(fù)制代碼

    測(cè)試算法:機(jī)器學(xué)習(xí)算法一個(gè)很重要的工作就是評(píng)估算法的正確率,通常我們只提供已有數(shù)據(jù)的90%作為訓(xùn)練樣本來訓(xùn)練分類器,而使用其余的10%數(shù)據(jù)去測(cè)試分類器,檢測(cè)分類器的正確率。10%數(shù)據(jù)應(yīng)該是隨機(jī)選擇的。

    分類器的測(cè)試代碼:

    def datingClassUnitTest():hoRatio=0.10datingDataMat, datingLabels = file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')print(datingDataMat)normDataSet, ranges, minVals = autoNorm(datingDataMat)print(normDataSet)m=normDataSet.shape[0]numTestVecs=int(m*hoRatio)print("numTestVecs")print(numTestVecs)errorCount=0.0for i in range(numTestVecs):classifierResult=classify(normDataSet[i,:],normDataSet[numTestVecs:m,:],datingLabels[numTestVecs:m],3)print("the classfier came back with:{},the real answer is:{}".format(classifierResult,datingLabels[i]))if (classifierResult!=datingLabels[i]):errorCount+=1.0print("the total error rate is:{}".format(errorCount/float(numTestVecs)))the classfier came back with:3,the real answer is:3 the classfier came back with:2,the real answer is:2 the classfier came back with:1,the real answer is:1 ......... the classfier came back with:1,the real answer is:1 the classfier came back with:3,the real answer is:3 the classfier came back with:3,the real answer is:3 the classfier came back with:2,the real answer is:2 the classfier came back with:1,the real answer is:1 the classfier came back with:3,the real answer is:1 the total error rate is:0.05復(fù)制代碼

    分類器處理數(shù)據(jù)集的錯(cuò)誤率是5%,即代表此分類器可以幫助對(duì)象判定分類。

    編寫可以讓用戶輸入自己需要判斷的輸入向量,通過該分類器幫助用戶判斷屬于哪一分類:

    def classifyPerson():resultList = ['not at all', 'in small doses', 'in large doses']percentTats = float(input( \"percentage of time spent playing video games?"))ffMiles = float(input("frequent flier miles earned per year?"))iceCream = float(input("liters of ice cream consumed per year?"))datingDataMat, datingLabels = file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')normDataSet, ranges, minVals = autoNorm(datingDataMat)inArr = np.array([ffMiles, percentTats, iceCream, ])classifierResult = classify((inArr - \minVals) / ranges, normDataSet, datingLabels, 3)print("You will probably like this person: {}".format(resultList[classifierResult - 1])) if __name__=='__main__':classifyPerson()""" return: percentage of time spent playing video games?10 frequent flier miles earned per year?10000 liters of ice cream consumed per year?0.5 You will probably like this person: in small doses """復(fù)制代碼

    總結(jié):

  • 定義K-近鄰算法程序。
  • 定義將文本數(shù)據(jù)集處理成二維數(shù)組的函數(shù),便于處理。
  • 為消除某一特征數(shù)值過大對(duì)結(jié)果判定的影響,定義歸一化數(shù)值函數(shù),公式:(oldValue-min)/(max-min)
  • 定義測(cè)試算法函數(shù),用于測(cè)試分類器的錯(cuò)誤率是否滿足使用要求。
  • 定義可以讓用戶輸入的代碼,輸入輸入向量,用于判定分類

  • 總結(jié)

    以上是生活随笔為你收集整理的机器学习笔记1(K-近邻算法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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