K N N ( k 近 邻 ) 机 器 学 习 算 法 详 解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
KNN算法代码详细解释
《机器学习实战》
K-近邻算法采用测量不同特征值之间的距离方法进行分类。适用数据范围:数值型和标称型。
工作原理:存在一个样本数据集(训练样本集),且样本集中每个数据都存在标签,即知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新数据每个特征与样本集中数据对应的特征进行比较,然后提取样本集中特征最相似(最近邻)的分类标签。一般,只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中的K的出处,通常K是不大于20的整数。最后,选择K个最相似数据在中次数出现最多的分类,作为新数据的分类。
代码及注释:
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0] # 计算矩阵的行数
diffMat = tile(inX, (dataSetSize, 1)) - dataSet # 第一个维度重复1次,第二个维度重复dataSetSize次
sqDiffMat = diffMat ** 2
sqDistances = sqDiffMat.sum(axis=1) # 矩阵的每一行相加
distances = sqDistances ** 0.5
sortedDistIndicies = distances.argsort() # argsort()函数返回的是distances元素从小到大排列后相应元素的索引。如
a=array([2,1,5,3]),a.argsort() 的结果为:[1,0,3,2]
classCount = {} # 分类标签字典标签:标签出现次数
for i in range(k): # 选择距离最小的K个点
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 #字典的get(key,default)方法返回字典中key对应的值,若key在字典中不存在,则返回default的值
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) # 排序 sort() 在本地排序,不返回副本;sorted() 返回副本,原始输入不变
return sortedClassCount[0][0]
# iteritems()返回的是一个迭代器
# sorted(iterable, cmp=None, key=None, reverse=False) -- new sorted list
# 第一个参数是可迭代对象,后面的参数都有默认值。cmp,比较的函数,具有两个参数,参数的值从可迭代对象中取,规则为:大于则返回1,小于则返回-1,等于则返回0
# key,用来进行比较的元素,只有一个参数,参数取自可迭代对象,指定可迭代对象中的一个元素来进行排序。itemgetter()用于获取对象指定维的数据,参数为序号
# reverse,排序规则,reverse = True 降序, reverse = False 升序
# 文件数据读取
def file2matrix(filename):
fr = open(filename)
arrayOLines = fr.readlines() # 读取文件所有内容
# .readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for . in . 结构进行处理。另一方面,.readline() 每次只读取一行,
# 通常比 .readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 .readline()
numberOfLines = len(arrayOLines) # 得到文件行数
returnMat = zeros((numberOfLines, 3))
classLabelVector = [] # 分类标签向量
index = 0 # 行索引号
for line in arrayOLines:
line = line.strip()
# s.strip(rm) s为字符串,rm为要删除的字符序列。删除s字符串中开头结尾处rm字符。rm为空时,默认删除空白符(‘’,‘r’,‘t’‘ ’)如a=' 123',a='t123',a='123r' # a.strip()的结果都为123 s.lstrip(rm) 删除s字符串中开头处rm字符 ; s.rstrip(rm) 删除s字符串中结尾处rm字符
listFromLine = line.split('t') # split()将一个字符串分裂成多个字符串组成的列表
returnMat[index, :] = listFromLine[0:3] # 将数据前三列提取出来
classLabelVector.append(listFromLine[-1]) # 将数据最后一列标签提取出来
index += 1
# ?数据归一化处理
def autoNorm(dataSet): # 数据归一化处理
minValues = dataSet.min(0) # 参数0使得函数可以从列中选取最小值,而不是选取当前行的最小值
maxValues = dataSet.max(0)
ranges = maxValues - minValues
normDataSet = zeros(shape(dataSet)) # 归一化结果
m = dataSet.shape[0]
normDataSet = dataSet - tile(minValues, (m, 1))
normDataSet = normDataSet - tile(ranges, (m, 1))
return normDataSet, ranges, minValues
# ?分类器测试
def datingClassTest():
hoRatio = 0.10 # 取10%的数据作为测试集 90%的数据作为训练集 datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)