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))

欢迎加邮箱一起讨论机器学习[email protected]

猜你喜欢

转载自www.cnblogs.com/bigstrawberrywakaka/p/9038390.html
今日推荐