KNN分類器(十折交叉驗證)


k-近鄰算法采用測量不同特征值之間的距離方法(上面寫的公式)進行分類。

優點:精度高、對異常值不敏感、無數據輸入假定。

缺點:計算復雜度高、空間復雜度高。

原理:1.存在一個訓練樣本集,並且樣本集中每個數據都存在標簽,即我們知道樣本集中每一數據與所屬分類的對應關系。

  2.輸入沒有標簽的新數據后,將新數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本集中特征最相思數據(最近鄰)的分類標簽。

  3.一般的,我們只選擇樣本數據集中前k個最相似的數據,通常k是不大於20的整數,最后選擇k個最相似數據中出現次數最多的分類,作為新數據的分類。

 1 '''
 2     1、計算已知類別數據集中的點與當前點之間的距離
 3     2、按照距離遞增次序排序
 4     3、選取與當前點距離最小的k個點
 5     4、確定前k個點所在類別的出現概率
 6     5、返回前k個點出現頻率最高的類別作為當前點的預測分類
 7 '''
 8 import numpy as np
 9 import operator
10 
11 #處理文本
12 def fileToMatrix(filename):
13     fr = open(filename)
14     arrayOLines = fr.readlines()
15     numberOfLines = len(arrayOLines)
16     returnMat = np.zeros((numberOfLines, 5))
17     classLabelVector = []
18     index = 0
19     for line in arrayOLines:
20         line = line.strip()
21         listFromLine = line.split(',')
22         returnMat[index,:] = listFromLine[0:5]
23         classLabelVector.append(listFromLine[-1])
24         index += 1
25     return returnMat, classLabelVector
26 
27 #功能:歸一化數據,避免某些數據的特征值過大
28 def autoNorm(dataSet):
29     minVals = dataSet.min(0)#取列值的最小值
30     maxVals = dataSet.max(0)
31     ranges = maxVals - minVals
32     normDataSet = np.zeros(np.shape(dataSet))
33     m = dataSet.shape[0]
34     normDataSet = dataSet - np.tile(minVals, (m,1))
35     normDataSet = normDataSet/np.tile(ranges, (m, 1))#特征值相除
36     return normDataSet, ranges, minVals
37 
38 #功能:kNN核心算法
39 #intX - 輸入向量,dataSet - 輸入訓練樣本集,labels - 標簽向量
40 def classify(inX, dataSet, labels, k):
41     #歐式距離的計算
42     dataSize = dataSet.shape[0]#數據的行數
43     diffMat = np.tile(inX, (dataSize,1)) - dataSet#將輸入向量inX縱向重復dataSet的行數次
44     sqDiffMat = diffMat ** 2
45     sqDistances = sqDiffMat.sum(axis = 1)# 每行數據相加
46     distances = sqDistances ** 0.5#得到訓練樣本集每一點與當前點的距離
47     sortedDistIndicies = distances.argsort()
48     #選擇距離最小的k個點
49     classCount = {}
50     for i in range(k):
51         voteIlabel = labels[sortedDistIndicies[i]]#最近K個的距離對應的類別
52         classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#類別分別出現的概率
53     sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)#選擇發生頻率最高的元素標簽
54     return sortedClassCount[0][0]
55 
56 #功能:#功能:十折交叉驗證
57 #思路:將數據集分成十份,輪流將其中9份做訓練1份做測試,10次結果的均值作為對算法精度的估計
58 #一般還要進行多次10倍交叉驗證
59 def dataClassTest(filename,k):
60     testRate = 0.1
61     datingDataMat, datingLabels = fileToMatrix(filename)
62     datingDataMat = datingDataMat[:,:k-1]
63     normMat, ranges, minVals = autoNorm(datingDataMat)
64     m = normMat.shape[0]
65     numTestVecs = int(m * testRate)
66     all = 0
67     for k in range(1,11):
68         t = normMat[0:numTestVecs]
69         p = datingLabels[0:numTestVecs]
70         for i in range(numTestVecs):
71             errorCount = 0
72             classifierResult = classify(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
73             if(classifierResult != datingLabels[i]):    errorCount += 1.0
74         #----------將第幾折的數據拿出來,放回到normMat的前面
75         b = normMat[numTestVecs*(k-1):numTestVecs*k]
76         normMat[0:numTestVecs] = b
77         normMat[numTestVecs*(k-1):numTestVecs*k] = t
78         errorRate = errorCount/float(numTestVecs)
79         #----------將第幾折類別拿出來,放回到datingLabels的前面
80         c = datingLabels[numTestVecs*(k-1):numTestVecs*k]
81         datingLabels[0:numTestVecs] = c
82         datingLabels[numTestVecs*(k-1):numTestVecs*k] = p
83         errorRate = errorCount/float(numTestVecs)
84         all = all + errorRate
85         #------------------------------------------------------------------
86         print("第%d折分類的錯誤率為%f" % (k,(errorCount/float(numTestVecs))))
87     #獲得平均錯誤率
88     print("平均錯誤率為%f" % (all/10))

歡迎加郵箱一起討論機器學習~=v=934363224@qq.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM