改变变量k的值,修改函数handwritingClassTest随机选取训练样本,改变训练样本的数目,都会对k-近邻算法的错误率产生影响
import operator
from numpy import *
from scipy import *
from matplotlib import *
"""
KNN近邻分类思路:
1,用shape[0]得到行数
2,把带划分数据用tile扩展成一个矩阵
3,(用该矩阵-训练数据)平方后开方得到一个列表
4,对列表按距离升序排列
5,选取前K个中标签出现次数后按降序排列,[0][0]即为出现最多的标签作为带预测的划分标签
"""
#inx为自己输入要分类的测试数,dataset为训练集,labels为标签集,k为kNN中的K值
#shape[0]得到训练样本多少行
#tile建立inx,dataSetSize行,1列
#sum(axis=1),按行相加
#argsort递增排序
def classify0(inX,dataSet,labels,k):
dataSetSize=dataSet.shape[0]
diffMat=tile(inX,(dataSetSize,1))-dataSet
sqDiffMat=diffMat**2
sqDistances=sqDiffMat.sum(axis=1) #
distances=sqDistances**0.5
sortedDistIndicies=distances.argsort() #生成的不是距离而是标号列表
#print(sortedDistIndicies)
classCount={}
for i in range(k):
#print(sortedDistIndicies[i])
voteIlabel=labels[sortedDistIndicies[i]]
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1 #这一步是做相同标签的统计(+1),找到键voteIlabel对应的值,如果不存在这样的键则返回默认值0
#print(classCount.get(voteIlabel,0))
sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) #sorted排序做升序,返回副本,原始输入不变,里面的参数设置请参考https://www.cnblogs.com/timtike/p/6562402.html,https://blog.csdn.net/hshl1214/article/details/40587985#print(sortedClassCount[0][0]) #或者参考https://www.cnblogs.com/zhoufankui/p/6274172.html
return sortedClassCount[0][0]
def img2vector(filename):
returnVect=zeros((1,1024))
fr=open(filename)
for i in range(32):
lineStr=fr.readline()
for j in range(32):
returnVect[0,32*i+j]=int(lineStr[j])
return returnVect
from os import listdir
def handwritingClassTest():
hwLabels=[]
trainingFileList=listdir(r'C:\Users\Administrator\Desktop\DL\digits\trainingDigits')
m=len(trainingFileList)
trainingMat=zeros((m,1024))
for i in range(m):
fileNameStr=trainingFileList[i]
fileStr=fileNameStr.split('.')[0] #提取文件名
classNumStr=int(fileStr.split('_')[0]) #提取文件名前面的数字
hwLabels.append(classNumStr)
trainingMat[i,:]=img2vector(r'C:\Users\Administrator\Desktop\DL\digits\trainingDigits/%s'%fileNameStr) #/代表子文件夹
testFileList=listdir(r'C:\Users\Administrator\Desktop\DL\digits\testDigits')
errorCount=0.0
mTest=len(testFileList)
for i in range(mTest):
fileNameStr=testFileList[i]
fileStr=fileNameStr.split('.')[0] #提取文件名
classNumStr=int(fileStr.split('_')[0]) #提取文件名前面的数字
vectorUnderTest=img2vector(r'C:\Users\Administrator\Desktop\DL\digits\testDigits/%s'%fileNameStr) #/代表子文件夹
classifierResult=classify0(vectorUnderTest,trainingMat,hwLabels,3)
print("the classifier come back with %d,the real result is %d"%(classifierResult,classNumStr))
if(classifierResult!=classNumStr):errorCount+=1
print('\n the total numer of errors is %d'%errorCount)
print('\n the total error rate is %f'%(errorCount/float(mTest)))
#可以选择显示一下
#handwritingClassTest()
"""
字符预测函数思路:
1,输入特征值
2、建立特征值数组
3、归一化特征值
4、输入预测文档如:4_0.txt
5、返回预测值
"""
def classifyChrct():
hwLabels=[]
trainingFileList=listdir(r'C:\Users\Administrator\Desktop\DL\digits\trainingDigits')
m=len(trainingFileList)
trainingMat=zeros((m,1024))
for i in range(m):
fileNameStr=trainingFileList[i]
fileStr=fileNameStr.split('.')[0] #提取文件名
classNumStr=int(fileStr.split('_')[0]) #提取文件名前面的数字
hwLabels.append(classNumStr)
trainingMat[i,:]=img2vector(r'C:\Users\Administrator\Desktop\DL\digits\trainingDigits/%s'%fileNameStr) #/代表子文件夹
inputDocument=input('Please input the document with .txt that you want forecast\n')
vectorUnderTest=img2vector(r'C:\Users\Administrator\Desktop\DL\digits\testDigits/%s'%(inputDocument))
classifierResult=classify0(vectorUnderTest,trainingMat,hwLabels,3)
print("the classifier come back with %d"%(classifierResult))
#预测看结果
classifyChrct()
文本文件链接:https://pan.baidu.com/s/1Lhxzz98EI2hdJBTDaz6sfg
提取码:od8y