k近邻算法php能用吗,k-近邻算法(kNN)完整代码

本文介绍了使用Python实现k-最近邻(kNN)算法,包括数据集创建、分类器操作、自动归一化处理以及手写数字识别的应用,通过实例展示了约会网站预测和个人特征分类的过程。同时涵盖了文件读取、图像转换和数据预处理技术。
摘要由CSDN通过智能技术生成

1 from numpy import *#科学计算包

2 from numpy importtile3 from numpy importzeros4 import operator #运算符模块

5 importimportlib6 importsys7 importlib.reload(sys)8

9 defcreateDataSet():10 group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])11 labels = ['A','A','B','B']12 returngroup,labels13

14 defclassify0(inX, dataSet, labels, k):15 dataSetSize =dataSet.shape[0]16 #距离计算

17 diffMat = tile(inX, (dataSetSize,1)) -dataSet18 sqDiffMat = diffMat**2 #平方

19 sqDistances = sqDiffMat.sum(axis=1) #根号下平方相加

20 distances = sqDistances**0.5 #根号

21 sortedDistIndicies = distances.argsort() #排序

22 classCount={}23 #选择距离最小的k个点

24 for i inrange(k):25 voteIlabel =labels[sortedDistIndicies[i]]26 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1

27 #排序,将classCount字典分解为元祖列表,导入itemgeeter方法,按照第二个元素的次序对元祖进行排序

28 #此处排序为逆序,即从大到小排序,最后返回发生频率最高的元素标签。

29 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)30 returnsortedClassCount[0][0]31 #为预测数据所在分类:kNN.classify0([0,0], group, labels, 3)

32

33 #mat()函数可以将数组(array)转化为矩阵(matrix)

34 #randMat = mat(random.rand(4,4))

35 #求逆矩阵:randMat.I

36 #存储逆矩阵:invRandMat = randMat.I

37 #矩阵乘法:randMat*invRandMat

38 #求误差值:myEye = randMat*invRandMat

39 #myEye - eye(4)

40 #eye(4)创建4*4的单位矩阵

41 #使用createDataSet()函数,创建数据集和标签

42 #创建变量group和labels:group,labels = kNN.createDataSet()

43 #labels包含的元素个数 = group矩阵的行数

44 #输入变量名字检验是否正确:group和labels

45 #46 #47 #准备数据:从文本文件中解析数据

48 #在kNN.py中创建名为file2matrix的函数,处理输入格式问题

49 #该函数的输入为文件名字符串,输出为训练样本矩阵和类标签向量

50 #将文本记录到转换Numpy的解析程序

51 deffile2matrix(filename):52 fr =open(filename)53 arrayOLines =fr.readlines()54 numberOfLines = len(arrayOLines) #得到文件行数

55 returnMat = zeros((numberOfLines,3)) #创建返回的Numpy矩阵

56 classLabelVector =[]57 index =058 for line in arrayOLines: #解析文件数据列表

59 line = line.strip() #使用line.strip()截取掉所有的回车字符

60 listFromLine = line.split('\t') #使用tab字符\t将上一步得到的整行数据分割成一个元素列表

61 returnMat[index,:] = listFromLine[0:3] #选取前三个元素,存储到特征矩阵中

62 classLabelVector.append(int(listFromLine[-1])) #-1表示列表中的最后一列元素,存储到向量classLabelVector中

63 index += 1

64 returnreturnMat,classLabelVector65

66 #准备数据:归一化数值

67 def autoNorm(dataSet): #autoNorm()函数可以自动将数字特征值转换为0到1的区间

68 minVals =dataSet.min(0)69 maxVals = dataSet.max(0) #ddataSet.max(0)中的参数0使得函数可以从列中选取最小值

70 ranges = maxVals -minVals71 normDataSet =zeros(shape(dataSet))72 m =dataSet.shape[0]73 #newValue = (oldValue-min)/(max-min),该公式可以将任意取值范围的特征值转换为0到1区间内的值

74 #tile()函数将变量内容复制成输入矩阵同样大小的矩阵(具体特征值相除)

75 #在numpy库中,矩阵除法需要使用函数linalg.solve(matA,matB)

76 normDataSet = dataSet - tile(minVals, (m,1))77 normDataSet = normDataSet/tile(ranges, (m,1))78 returnnormDataSet, ranges, minVals79

80 #测试算法:作为完整程序验证分类器

81 defdatingClassTest():82 hoRatio = 0.10 #设置测试集比重,前10%作为测试集,后90%作为训练集

83 datingDataMat,datingLabels = file2matrix('datingTestSet.txt')84 normMat, ranges, minVals =autoNorm(datingDataMat)85 m = normMat.shape[0] #得到样本数量m

86 numTestVecs = int(m*hoRatio) #得到测试集最后一个样本的位置

87 errorCount = 0.0 #初始化定义错误个数为0

88 for i inrange(numTestVecs):89 #测试集中元素逐一放进分类器测试,k = 3

90 classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)91 #输出分类结果与实际label

92 print("the classifier came back with: %d, the real answer is: %d"%(classifierResult, datingLabels[i]))93 #若预测结果与实际label不同,则errorCount+1

94 if (classifierResult !=datingLabels[i]): errorCount += 1.0

95 #输出错误率 = 错误的个数 / 总样本个数

96 print("the total error rate is: %f" % (errorCount/float(numTestVecs)))97

98

99 #约会网站预测数据

100 defclassifyPersion():101 resultList = ['not at all','in small doses','in large doses']102 #input()函数允许用户输入文本行命令并返回用户所输入的命令

103 percentTats = float(input("percentage of time spent playing video games?"))104 ffMiles = float(input("frequent year?"))105 iceCream = float(input("liters years?"))106 datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')107 normMat, ranges, minVals =autoNorm(datingDataMat)108 inArr =array([ffMiles,percentTats, iceCream])109 classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)110 print("you like person:",resultList[classifierResult - 1])111

112

113 #准备数据:将图像转换为测试向量

114 #img2vector函数,将图像转换为向量:该函数创建1*2014的numpy数组,

115 #然后打开给定的文件,循环读出文件的前32行,并将每行的头32个字符值存储在numpy数组中,最后返回数组

116 defimg2vector(filename):117 returnVect = zeros((1,1024))118 fr =open(filename)119 for i in range(32):120 lineStr =fr.readline()121 for j in range(32):122 returnVect[0,32*i+j] =int(lineStr[j])123 returnreturnVect124

125 #测试算法:识别手写数字

126 defhandwritingClassTest():127 hwLabels =[]128 trainingFileList = os.listdir('trainingDigits')129 m =len(trainingFileList)130 trainingMat = zeros((m,1024))131 #文件名下划线_左边的数字是标签

132 for i inrange(m):133 fileNameStr =trainingFileList[i]134 fileStr = fileNameStr.split(".")[0]135 classNumStr = int(fileStr.split('_')[0])136 hwLabels.append(classNumStr)137 trainingMat[i,:] = img2vector('trainingDigits/%s' %fileNameStr)138 testFileList = os.listdir('trainingDigits')139 errorCount = 0.0

140 mTest =len(testFileList)141 for i inrange(mTest):142 fileNameStr =testFileList[i]143 fileStr = fileNameStr.split('.')[0] #take off .txt

144 classNumStr = int(fileStr.split('_')[0])145 vectorUnderTest = img2vector('digits/testDigits/%s' %fileNameStr)146 classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)147 print("the classifier came back with: %d, the real answer is: %d" %(classifierResult, classNumStr))148 if (classifierResult != classNumStr): errorCount += 1.0

149 print("the total number of errors is: %d" %errorCount)150 print("the total error rate is: %f" % (errorCount / float(mTest)))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值