1.创建训练集样本
2.k-*邻分类算法
3.从文本文件中解析和导人数据
4.使用 Matplotlib 创建扩散图
5.归一化数值
#编写一些基本的通用函数 def createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) #创建训练样本集,其中坐标[x,y]为已知的属性或特征值 labels = ['A','A','B','B'] #样本集中每个数据都存在标签 return group, labels #返回样本集、 标签
#k-*邻算法 #intX:待分类数据(向量) #dataSet,labels:样本训练集 #k: 选择样本数据集中前k个最相似的数据, 通常 k 是不大于 20 的整数 def classify(inX,dataSet,labels,k): #-----------计算距离 start----------------- #欧氏距离公式 dataSetSize = dataSet.shape[0] #训练集大小 4 diffMat = tile(inX,(dataSetSize,1)) - dataSet #把待分类数据向量复制成与训练集等阶,对应项求差 #1.[[0,0],[0,0],[0,0],[0,0]] #2.[[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]] sqDiffMat = diffMat**2 #各项平方 sqDistances = sqDiffMat.sum(axis = 1) #axis=1,将一个矩阵的每一行向量相加 distances = sqDistances ** 0.5 #开方,求出距离 #-----------计算距离 end----------------- sortedDistIndicies = distances.argsort() #从小到大排序,返回数组的索引[2,3,1,0] classCount = {} #{'B':2,'A':1} #选择距离最小的key个点 for i in range(k): #遍历前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] #选择k个最相似数据中出现次数最多的分类,作为新数据的分类。即返回发生频率最高的元素标签 #sortedClassCount:[('B',2),('A',1)] ,sortedClassCount[0][0]=B
#从文本文件中解析和导人数据 #将文本记录到转换 NumPy的解析程序,处理输入格式问题 def file2matrix(filename): fr = open(filename) #打开文件 arrayOLines = fr.readlines() numberOfLines = len(arrayOLines) #获取文件行数 #创建以零填充的矩阵NumPy #NumPy为二维数组,另一维度设置固定值3 #returnMat 返回的特征矩阵 returnMat = zeros((numberOfLines,3)) classLabelVector = [] index = 0 for line in arrayOLines: line = line.strip() #截取掉所有的回车字符 #使用 tab 字符\t将上一步得到的整行数据分割成一个元素列表 #数组 listFromLine = line.split('\t') #选取前 3 个元素,将它们存储到特征矩阵中 returnMat[index,:] = listFromLine[0:3] #使用索引值 -1 表示列表中的最后一列元素 #将列表的最后一列存储到向量classLabelVector中 #列表中存储的元素值为整型 int classLabelVector.append(int(listFromLine[-1])) index += 1 return returnMat,classLabelVector
#使用 Matplotlib 创建扩散图 fig = plt.figure() ax = fig.add_subplot(111) # ax.scatter(datingDataMat[:,1], datingDataMat[:,2]) ax.scatter(datingDataMat[:,1], datingDataMat[:,2], 15.0*array(datingLabels),15.0*array(datingLabels)) plt.show()
#归一化处理 #newValue = (oldValue - min)/(max - min) #将特征值转换为0,1之间 #自动将数字特征值转化为 0 到 1 的区间 def autoNorm(dataSet): minVals = dataSet.min(0) #从列中选取最小值(每一列),数组 maxVals = dataSet.max(0) #从列中选取最大值(每一列),数组 ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals, (m,1)) #minVals复制为与dataSet等阶的集合 normDataSet = normDataSet/tile(ranges, (m,1)) #ranges复制为与dataSet等阶的集合 return normDataSet, ranges, minVals
如下图
总结:
1.key*邻算法思想
主要是采用欧氏公式,计算点与点(特征集)之间的距离,从训练集中返回命中次数概率(出现次数)最大的结果(标签)。
2.优缺点
优点:相对比较简单,而且期望值准确率会更加有效。
缺点:如果训练样本集过大,会严重影响训练效率。而且占用存储空间会比较大。
3.应用场景
手写数字识别系统、交友系统(甄别好友质量)。
4.数学公式应用
欧氏距离公式: