knn
1.k近邻算法:k值的选择,距离度量,分类决策规则--三个基本要素
2.归一化特征值,消除特征之间量级不同导致的影响,归一化是为了后面数据处理的方便,其次是保正程序运行时收敛加快。
3.K值的确定:
(1)当K的取值过小时,会出现偏差,容易发生过拟合;
(2)当K的值取过大时,就相当于用较大邻域中的训练实例进行预测,学习的近似误差会增大。使预测发生错误,容易导致欠拟合。
(3) 所以K值的选取一般都比较小且基本都是奇数,同时也需要进行交叉验证。
1 import operator 2 import numpy as np 3 from numpy import tile 4 5 def createDataSet(): 6 # 八组特征 7 group = np.array([[1, 180, 80], [1, 175, 55], [1, 170, 98], [1, 165, 110], [2, 170, 60], [2, 165, 50], [2, 155, 80], 8 [2, 160, 75]]) 9 # 八组特征的标签 10 labels = ['正常', '偏瘦', '偏胖', '很胖', '正常', '偏瘦', '偏胖', '很胖'] 11 return group, labels 12 13 def classify(inX, dataSet, labels, k): 14 datsSetSize = dataSet.shape[0] #行数 15 diffMat = tile(inX,(datsSetSize,1)) - dataSet #(纵向平铺,横向平铺) datsSetSize为复制的行数 16 sqDiffMat = diffMat**2 17 sqDistance = sqDiffMat.sum(axis = 1)#axis=0表示列方向,axis=1表示行方向 18 distances = sqDistance**0.5 19 20 #argsort的作用是对列表内的数据升序排列, 21 sortedDistIndices = distances.argsort() #从小到大排序[ 3.16227766 22.36067977 22.84731932 35.84689666 19.26136028 30.43024811] 22 classCount = {} 23 for i in range(k): 24 voteIlabel = labels[sortedDistIndices[i]] 25 26 #get函数是返回字典classCount中voteIlabel元素对应的值,若无,则进行初始化,0为初始化 27 #后赋的值。 28 #这里是统计前k个中出现的次数, 29 # 在字典中将该类型加一 30 # 字典的get方法 31 # 如: list.get(k,d) 其中 get相当于一条if...else...语句,参数k在字典中,字典将返回list[k]; 如果参数k不在字典中则返回参数d,如果K在字典中则返回k对应的value值 32 # l = {5:2,3:4} 33 # print l.get(3,0)返回的值是4; 34 # Print l.get(1,0)返回值是0; 35 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #{'正常': 2, '很胖': 1} 36 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) 37 # python字典中还存在items()方法。两者有些许区别。 38 # items方法是可以将字典中的所有项,以列表方式返回。 39 # iteritems方法与items方法相比作用大致相同,只是它的返回值不是列表,而是一个迭代器。 40 # 返回一个可调用对象,用于从运算对象中获取元素,其实是采用运算对象的_getitem_()方法。如果指定了多个项目,返回一个元组形式。 41 # operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。 42 43 return sortedClassCount[0][0] 44 ''' 45 list = sorted(iterable, key=None, reverse=False) 46 其中,iterable 表示指定的序列,key 参数可以自定义排序规则; 47 reverse 参数指定以升序(False,默认)还是降序(True)进行排序。 48 sorted() 函数会返回一个排好序的列表。 49 注意,key 参数和 reverse 参数是可选参数,即可以使用,也可以忽略。 50 ''' 51 # 字典的 items() 方法,以列表返回可遍历的(键,值)元组数组。 52 # 例如: dict = {'Name': 'Zara', 'Age': 7} print "Value : %s" % dict.items() Value : [('Age', 7), ('Name', 'Zara')] 53 # sorted 中的第2个参数 key=operator.itemgetter(1) 这个参数的意思是先比较第几个元素 54 # 例如: a=[('b',2),('a',1),('c',0)] b=sorted(a,key=operator.itemgetter(1)) >>>b=[('c',0),('a',1),('b',2)] 可以看到排序是按照后边的0,1,2进行排序的,而不是a,b,c 55 # b=sorted(a,key=operator.itemgetter(0)) >>>b=[('a',1),('b',2),('c',0)] 这次比较的是前边的a,b,c而不是0,1,2 56 # b=sorted(a,key=opertator.itemgetter(1,0)) >>>b=[('c',0),('a',1),('b',2)] 这个是先比较第2个元素,然后对第一个元素进行排序,形成多级排序。 57 58 if __name__ == '__main__': 59 # 创建数据集 60 group, labels = createDataSet() 61 print("group:\n", group, '\n', "labels:\n", labels) 62 test1 = classify([1, 179, 77], group, labels, 3) 63 print('该同学指标为:', test1)
1 def file2matrix(filename): 2 fr = open(filename,'r') 3 4 #readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表, 5 #其中每一行的数据为一个元素。 6 arrayOLines = fr.readlines() 7 8 # 计算有多少行数据 9 numberOfLines = len(arrayOLines) 10 11 # 返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列 12 returnMat = np.zeros((numberOfLines,3)) 13 14 # 创建分类标签向量 15 classLabelVector = [] 16 index = 0 17 18 # 这里是以元素为循坏条件 19 for line in arrayOLines: 20 #s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ') 21 #该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。 22 line = line.strip() 23 # 使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。 24 listFromLine = line.split('\t') 25 listFromLine = [float(x) for x in listFromLine] 26 # 将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵 27 returnMat[index] = listFromLine[0:3] 28 # 根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力 29 #if listFromLine[-1] == 'didntLike': 30 # append()方法将一个项目添加到列表的末尾 31 #classLabelVector.append(1) 32 #elif listFromLine[-1] == 'smallDoses': 33 #classLabelVector.append(2) 34 #elif listFromLine[-1] == 'largeDoses': 35 #classLabelVector.append(3) 36 classLabelVector.append(int(listFromLine[-1])) 37 index += 1 38 return returnMat, classLabelVector
浙公网安备 33010602011771号