機器學習可分為監督學習和無監督學習。有監督學習就是有具體的分類信息,比如用來判定輸入的是輸入[a,b,c]中的一類;無監督學習就是不清楚最后的分類情況,也不會給目標值。
K-近鄰算法屬於一種監督學習分類算法,該方法的思路是:如果一個樣本在特征空間中的k個最相似(即特征空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。
需要進行分類,分類的依據是什么呢,每個物體都有它的特征點,這個就是分類的依據,特征點可以是很多,越多分類就越精確。
機器學習就是從樣本中學習分類的方式,那么就需要輸入我們的樣本,也就是已經分好類的樣本,比如特征點是A , B2個特征,輸入的樣本甲乙丙丁,分別為[[1.0, 1.1], [1.0, 1.0], [0., 0.], [0.0, 0.1]]。 那么就開始輸入目標值,當然也要給特征了,最終的目標就是看特征接近A的多還是B的多,如果把這些當做坐標,幾個特征點就是幾緯坐標,那么就是坐標之間的距離。那么問題來了,要怎么看接近A的多還是B的多。
我就直接貼代碼了,基於python,首先輸入特征量labels和樣本group。
一開始需要導入的模塊
#coding=utf-8 #科學計算包 #from numpy import * import numpy #運算符模塊 import operator
數據樣本和分類模擬
#手動建立一個數據源矩陣group,和數據源的分類結果labels def createDataSet(): group = numpy.array([[1.0, 1.1], [1.0, 1.0], [5., 2.], [5.0, 0.1]]) labels = ['A', 'A', 'B', 'B'] return group, labels
然后進行KNN算法。
# newInput為輸入的目標,dataset是樣本的矩陣,label是分類,k是需要取的個數 def kNNClassify(newInput, dataSet, labels, k): #讀取矩陣的行數,也就是樣本數量 numSamples = dataSet.shape[0] print 'numSamples: ' ,numSamples #變成和dataSet一樣的行數,行數=原來*numSamples,列數=原來*1 ,然后每個特征點和樣本的點進行相減 diff = numpy.tile(newInput, (numSamples, 1)) - dataSet print 'diff: ',diff #平方 squaredDiff = diff ** 2 print "squaredDiff: ",squaredDiff #axis=0 按列求和,1為按行求和 squaredDist = numpy.sum(squaredDiff, axis = 1) print "squaredDist: ",squaredDist #開根號,距離就出來了 distance = squaredDist ** 0.5 print "distance: ",distance #按大小逆序排列 sortedDistIndices = numpy.argsort(distance) print "sortedDistIndices: ",sortedDistIndices classCount = {} for i in range(k): #返回距離(key)對應類別(value) voteLabel = labels[sortedDistIndices[i]] print "voteLabel: " ,voteLabel # 取前幾個K值,但是K前幾個值的大小沒有去比較,都是等效的 classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 print "classCount: " ,classCount maxCount = 0 #返回占有率最大的 sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True) return sortedClassCount[0][0]
最后進行測試
dataSet, labels = createDataSet() testX = numpy.array([0, 0]) k = 3 outputLabel = kNNClassify(testX, dataSet, labels, k) print "Your input is:", testX, "and classified to class: ", outputLabel
可以發現輸出
numSamples: 4 diff: [[-1. -1.1] [-1. -1. ] [-5. -2. ] [-5. -0.1]] squaredDiff: [[ 1.00000000e+00 1.21000000e+00] [ 1.00000000e+00 1.00000000e+00] [ 2.50000000e+01 4.00000000e+00] [ 2.50000000e+01 1.00000000e-02]] squaredDist: [ 2.21 2. 29. 25.01] distance: [ 1.48660687 1.41421356 5.38516481 5.0009999 ] sortedDistIndices: [1 0 3 2] voteLabel: A voteLabel: A voteLabel: B classCount: {'A': 2, 'B': 1} Your input is: [0 0] and classified to class: A
這里我之前一直有個疑問,關於K的取值,結果也許跟K的取值產生變化,只要在K的取值范圍內們所有特征點距離遠近也就沒有關系了。所以才叫K近鄰分類算法