介绍
通过计算特征值之间的距离来进行分类;
计算将当前的对象与已知分类的对象特征值距离,对距离进行排序,取前k个里面的类别最多的即是当前对象的最有可能的类别;
python实现
from numpy import * from operator import itemgetter def classify0(inx,dataset,lables,k): ''' kNN algorithm idx: 输入的带分类对象特征值 dataset: 已知的数据集 lables:数据集对应的类别集 k:选取排序的前k个对象 ''' dataSetSize = shape(dataset)[0] #行数 dffMat = tile(inx, (dataSetSize, 1)) - dataset #复制datasetsize份 sqDiffMat = dffMat**2 sqDistance = sqDiffMat.sum(axis=1) distance = sqDistance**0.5 sortedDistIdx = argsort(distance) #排序结果返回的是按照distace里对应的的序号 classCount = {} for i in range(k): #取前k个 volLable = lables[sortedDistIdx[i]] #前k个的类别 classCount[volLable] = classCount.get(volLable,0) + 1 #计数 sortedClassCount = sorted(classCount.iteritems(),key=itemgetter(1),reverse=True) return sortedClassCount[0][0] #返回第一个类别
上面的代码中, classCount是一个字典, 保存的是一类别:个数的结构;
classCount.iteritems()是字典的迭代器;
sqDiffMat.sum(axis=1);是对数组按列求和, axis=0代表按行求和;
itemgetter(1);是返回一个函数,用于取当前对象的第1个对象,如:
f=itergetter(1) a=[1,2,3] f(a) # ⇒ 2
分类示例
#tM是已知数据的特征对象, lb对应的类别 tM = [[1,1,2],[0,1,1],[2,1,2],[8,9,9],[7,9,8],[8,7,9]] lb = ['a','a','a','b','b','b'] #tc 测试对象 tc = [9,8,10] re = classify0.classify0(tc,tM,lb,3) print(re)
结果: b
总结:
这个分类算法比较简单,就是把分类对象的特征值与已经分类的数据的特征值的欧几里的空间距离进行排列, 获得最大概率类别(最近的类别);
特征值归一化
def autoNorm(dataset):
"""
normalize the data features
"""
minV = dataset.min(0)
maxV = dataset.max(0)
ranges = maxV - minV
normDataSet = zeros(shape(dataset))
m = dataset.shape[0]
normDataSet = dataset - tile(minV,(m,1))
normDataSet = normDataSet/tile(ranges,(m,1))
return normDataSet
文件读取示例
文件的读取有.read(), .readline(), .readlines()三个函数, .read()一次性读取全部内容, .readline()读取一行, .readlines()读取所有的行放到一个list中, 速度比readline()快;
.strip()去掉行前的空格;
.split(‘.’) 将字符串按’.’分开得到的每段组成一list;
os.listdir(“dirpath”); 得到当前路径文件夹下的所有文件;
def file2maxtrix(filename): f = open(filename) arrayOLines = f.readlines() numberOfLines = len(arrayOLines) retMtx = zeros((numberOfLines,3)) classLableVec = [] idx = 0 for line in arrayOLines: line = line.strip() listFromLine = line.split('\t') retMtx[idx,:] = listFromLine[0:3] classLableVec.append(int(listFromLine[-1])) idx += 1 return retMtx,classLableVec