《机器学习实战》chapter02 K-近邻算法(KNN)
生活随笔
收集整理的這篇文章主要介紹了
《机器学习实战》chapter02 K-近邻算法(KNN)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2.2 示例:使用K-近鄰算法改進約會網站的配結果
1、數據:機器學習實戰源碼及數據集
密碼:6irz
2、準備數據
# 將文本轉換成Numpy矩陣 def fileToMatrix(filename):# 打開文件fr = open(filename)arrayOfLines = fr.readlines()numberOfLines = len(arrayOfLines)# 構建一個全零矩陣用來存儲特征信息returnMat = zeros((numberOfLines, 3))# 構建一個標簽數組用來存儲特征對應的類別標簽classLabelVector = []index = 0for line in arrayOfLines:line = line.strip()listFromLine = line.split('\t')# 復制特征信息returnMat[index, :] = listFromLine[0:3]# 復制類別標簽classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector# 歸一化數據 def autoNorm(dataSet):# min(0)每一列中的最小值, min(1)每一行中的最小值minValues = dataSet.min(0)# max(0)每一列中的最大值maxValues = dataSet.max(0)# 取值范圍ranges = maxValues - minValues# 初始化矩陣normDataSet = mat(zeros(shape(dataSet)))# print(normDataSet)# 返回dataset的行數m = dataSet.shape[0]normDataSet = dataSet - tile(minValues, (m, 1))normDataSet = normDataSet / tile(ranges, (m, 1))return normDataSet, ranges, minValues3、分析數據
- 這里用到了上一部分的fileToMatrix函數進行數據轉換
- matplotlib包
可以自行設置橫縱坐標軸表示的數據,即scatter()的前兩個參數,如下
5、測試算法
# !/usr/bin/env python # -*- coding: utf-8 -*-from chapter2.KNN import *# 分類器針對約會網站分類 def datingClass():hoRatio = 0.10datingDataMat, datingLabels = fileToMatrix("datingTestSet2.txt")normMat, ranges, minValues = autoNorm(datingDataMat)m = normMat.shape[0]numTestVecs = int(m * hoRatio)errorCount = 0.0for i in range(numTestVecs):classifierResult = classfiy0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]))if(classifierResult != datingLabels[i]):errorCount += 1.0print("the total error rate is : %f" % (errorCount / float(numTestVecs)))datingClass()另外附上完整的KNN.py文件(Python3)
from numpy import * import operator# 構造分類器,用于分類的inX, 訓練的樣本集dataSet, 標簽向量labels, 最近鄰居數目k def classfiy0(inX, dataSet, labels, k):# shape[0]返回行數, shape[1]返回列數dataSetSize = dataSet.shape[0]"""1、把當前數據復制成訓練集大小,以便同訓練集中每一個數據比較"""# tile(A, n)將A數組重復n次, 這里是列數不變,行數變dataSetSize行# 跟dataset做差,即與每一個訓練數據做差(求距離)diffMat = tile(inX, (dataSetSize, 1)) - dataSet# 分別對每一個數據平方sqdiffMat = diffMat**2# 將矩陣的每一行向量相加sqDistance = sqdiffMat.sum(axis=1)# 平方根distances = sqDistance**0.5"""2、將比較結果排序"""# 返回從小到大排序后的索引值sortedDistIndicies = distances.argsort()"""3、統計最近k個值的類別"""# 新建字典,保存最近的K個值分別是什么類別classCount = {}for i in range(k):# 獲取第i個值的類別voteIlabel = labels[sortedDistIndicies[i]]# 統計每個得數目classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1"""4、對統計結果拍序"""sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)"""5、返回在這K個值中,出現次數最多的類別"""return sortedClassCount[0][0]# 將文本轉換成Numpy矩陣 def fileToMatrix(filename):# 打開文件fr = open(filename)arrayOfLines = fr.readlines()numberOfLines = len(arrayOfLines)# 構建一個全零矩陣用來存儲特征信息returnMat = zeros((numberOfLines, 3))# 構建一個標簽數組用來存儲特征對應的類別標簽classLabelVector = []index = 0for line in arrayOfLines:line = line.strip()listFromLine = line.split('\t')# 復制特征信息returnMat[index, :] = listFromLine[0:3]# 復制類別標簽classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector# 歸一化數據 def autoNorm(dataSet):# min(0)每一列中的最小值, min(1)每一行中的最小值minValues = dataSet.min(0)# max(0)每一列中的最大值maxValues = dataSet.max(0)# 取值范圍ranges = maxValues - minValues# 初始化矩陣normDataSet = mat(zeros(shape(dataSet)))# print(normDataSet)# 返回dataset的行數m = dataSet.shape[0]normDataSet = dataSet - tile(minValues, (m, 1))normDataSet = normDataSet / tile(ranges, (m, 1))return normDataSet, ranges, minValues6、使用算法:輸入特征數據以判斷對方是否是自己喜歡的類型
# !/usr/bin/env python # -*- coding: utf-8 -*-from chapter2.KNN import *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?"))datingMat, datingLabels = fileToMatrix("datingTestSet2.txt")normMat, ranges, minValues = autoNorm(datingMat)inArry = [ffMiles, percentTats, iceCream]classifierResult = classfiy0(inArry, datingMat, datingLabels, 3)print("You will probably like this person: " + resultList[classifierResult - 1])classifyPerson()2.3 示例:手寫識別系統
1、收集數據:見上
2、準備數據:編寫imgToVector(), 將圖像格式轉換為分類器使用的向量格式
# 將二進制圖像矩陣轉換成一維數組 def imgToVector(filename):returnVect = zeros((1, 1024))# 打開文件fr = open(filename)for i in range(32):linestr = fr.readline()for j in range(32):returnVect[0, 32*i+j] = int(linestr[j])return returnVect3、測試算法:編寫函數使用提供的部分數據集作為測試樣本,測試樣本與非測試樣本的區別在于測試樣本是已經完成分類的數據,如果預測分類與實際類別不同,則標記為一個錯誤。
# !/usr/bin/env python # -*- coding: utf-8 -*- from os import listdirfrom chapter2.KNN import *# 將二進制圖像矩陣轉換成一維數組 def imgToVector(filename):returnVect = zeros((1, 1024))# 打開文件fr = open(filename)for i in range(32):linestr = fr.readline()for j in range(32):returnVect[0, 32*i+j] = int(linestr[j])return returnVect# 手寫數字識別 def handwritingClassTest():hwLabels = []# 訓練數據集trainingFileList = listdir('trainingDigits')m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):# 獲取文件名fileNameStr = trainingFileList[i]filestr = fileNameStr.split('.')[0]classNumStr = int(filestr.split('_')[0])hwLabels.append(classNumStr)trainingMat[i, :] = imgToVector("trainingDigits/%s" % fileNameStr)# 測試數據集testFileList = listdir("testDigits")errorCount = 0.0mTest = len(testFileList)for i in range(mTest):fileNameStr = testFileList[i]filestr = fileNameStr.split('.')[0]classNumStr = int(filestr.split('_')[0])vectorUnderTest = imgToVector("trainingDigits/%s" % fileNameStr)classifierResult = classfiy0(vectorUnderTest, trainingMat, hwLabels, 3)print("the classifier came back with: %d, the real answer is : %d" % (classifierResult, classNumStr))if classifierResult != classNumStr:errorCount += 1.0print("the total number of errors is : %d" % errorCount)print("the total error rate is : %f" % (errorCount / float(mTest)))handwritingClassTest()個人問題及總結:
- 自己的測試結果與樹上的測試結果不一樣,有細微差距,不知道具體是什么原因
- KNN文件中歸一化數據時(autoNorm(dataSet))中在進行初始化矩陣時,Pycharm總提示變量未被使用,感覺是normDataSet指向了一個全零矩陣,然后normDataSet又指向了dataSet - tile(minValues, (m, 1)),初始化全零矩陣完全沒有起到作用,感覺這可能是測試結果不一樣的原因吧,希望了解的兄弟能告知一下該怎么處理
總結
以上是生活随笔為你收集整理的《机器学习实战》chapter02 K-近邻算法(KNN)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蚂蚁Service Mesh大规模落地实
- 下一篇: CTO怒了:再写if-else,逮着罚款