代码是机器学习实战书上的,略有修改,在python3下运行
#1 导入模块,创建数据集
from numpy import *
import operator
def createDataSet(): #创建简单测试数据
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group, labels
导入numpy和operator模块,注意导入方式不同,使用operator时需要以operator.的形式而
numpy可直接用创建数据集及标签,group和labels一一对应
#2 核心部分 kNN算法实现
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()
有四个输入参数,待分类向量,训练样本集,标签向量,k值使用shape函数方式
如shape(dataSet)可返回一个维度元组信息,shape方法方式shape[0]可得到第一维
也就是行数inX是行向量,使用tile可以将inX整个按dataSetSize行1列进行复制,再
与dataSet做差;得到的diffMat是数组形式,平方可对其中每个元素平方操作,sum
则是对sqDiffMat进行求和,axis=1可对每一行求和得到列向量数组,axis=0则可对
每一列求和得到行向量数组;得到距离后要进行排序操作,argsort方法可以返回升序
排序后的索引
classCount= {}
for i in range(k):
voteIlabel= labels[sortedDistIndicies[i]]
classCount[voteIlabel]= classCount.get(voteIlabel,0)+1
sortedClassCount= sorted(classCount.items(),
key=operator.itemgetter(1), reverse= True)
return sortedClassCount[0][0]
创建classCount用于统计标签次数,循环k次找出最近的k个数据;
sortedDistIndicies[i]可获取索引并找出对应标签,然后统计各
标签出现次数存入classCount中,get方法可以取得voteIlabel的
的值,如果没有voteIlabel则创建并赋值0;得到classCount后要继续
排序,sorted的参数中,items()将字典变为可迭代对象,key指定了
排序规则,按值比较,reverse=True指定降序,最后返回值最大的键
#3 文本处理部分
def file2matrix(filename):#文本转换
fr= open(filename)
arrayOLines= fr.readlines() #按行读取全部行
numberOfLines= len(arrayOLines) #计算行数
returnMat= zeros((numberOfLines, 3)) #创建numberOfLines行3列的零矩阵
classLabelVector= []
index= 0
for line in arrayOLines: #遍历每一行
line= line.strip() #去掉每一行前后的空白
listFromLine= line.split('\t') #按'\t'切分每一行
returnMat[index,:]= listFromLine[0:3] #特征值放入returnMat
classLabelVector.append(int(listFromLine[-1])) #类别放入classLabelVector
index+=1
return returnMat, classLabelVector
def autoNorm(dataSet): #归一化数值
minVals= dataSet.min(0) #取得dataSet中一列的最小值,即每个属性的最小特征值
maxVals= dataSet.max(0) #同上
ranges= maxVals- minVals
m= dataSet.shape[0]
normDataSet= dataSet- tile(minVals,(m,1))
normDataSet= normDataSet/tile(ranges,(m,1))
return normDataSet, ranges, minVals
#4 测试部分
def datingClassTest():
hoRatio = 0.10 #使用10%的数据作为测试集,90%则为训练集
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #注意打开的文件,书上有误
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:],\
normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
print("the classifier came back with: %d, the real answer is: %d" \
% (classifierResult, datingLabels[i]))
if (classifierResult != datingLabels[i]):
errorCount += 1.0
print("the total error rate is: %f" % (errorCount/float(numTestVecs)))
print(errorCount)
完整代码
from numpy import *
import operator
def createDataSet(): #创建简单测试数据
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group, labels
def classify0(inX, dataSet, labels, k): #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()
classCount= {}
for i in range(k):
voteIlabel= labels[sortedDistIndicies[i]]
classCount[voteIlabel]= classCount.get(voteIlabel,0)+1
sortedClassCount= sorted(classCount.items(),
key=operator.itemgetter(1), reverse= True)
return sortedClassCount[0][0]
def file2matrix(filename):#文本转换
fr= open(filename)
arrayOLines= fr.readlines()
numberOfLines= len(arrayOLines)
returnMat= zeros((numberOfLines, 3))
classLabelVector= []
index= 0
for line in arrayOLines:
line= line.strip()
listFromLine= line.split('\t')
returnMat[index,:]= listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index+=1
return returnMat, classLabelVector
def autoNorm(dataSet): #归一化数值
minVals= dataSet.min(0)
maxVals= dataSet.max(0)
ranges= maxVals- minVals
m= dataSet.shape[0]
normDataSet= dataSet- tile(minVals,(m,1))
normDataSet= normDataSet/tile(ranges,(m,1))
return normDataSet, ranges, minVals
def datingClassTest():
hoRatio = 0.10
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:],\
normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
print("the classifier came back with: %d, the real answer is: %d" \
% (classifierResult, datingLabels[i]))
if (classifierResult != datingLabels[i]):
errorCount += 1.0
print("the total error rate is: %f" % (errorCount/float(numTestVecs)))
print(errorCount)
group, labels= createDataSet()
print(group)
print(labels)
print(classify0([0,0], group, labels, 3))
datingClassTest()
KNN代码解析
最新推荐文章于 2022-07-16 08:00:00 发布