流程步骤

1.创建训练集样本
2.k-*邻分类算法
3.从文本文件中解析和导人数据
4.使用 Matplotlib 创建扩散图
5.归一化数值

机器学*__k*邻算法_邻算法机器学*__k*邻算法_邻算法_02
#编写一些基本的通用函数 
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*邻算法_邻算法机器学*__k*邻算法_邻算法_02
#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
k*邻算法
机器学*__k*邻算法_邻算法机器学*__k*邻算法_邻算法_02
#从文本文件中解析和导人数据
#将文本记录到转换 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    
从文本中解析和导入数据
机器学*__k*邻算法_邻算法机器学*__k*邻算法_邻算法_02
#使用 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()
使用 Matplotlib 创建扩散图
机器学*__k*邻算法_邻算法机器学*__k*邻算法_邻算法_02
#归一化处理
#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
归一化数值
机器学*__k*邻算法_邻算法机器学*__k*邻算法_邻算法_02
如下图
运行结果

 

机器学*__k*邻算法_邻算法_13

 

总结:

1.key*邻算法思想

主要是采用欧氏公式,计算点与点(特征集)之间的距离,从训练集中返回命中次数概率(出现次数)最大的结果(标签)。

2.优缺点

优点:相对比较简单,而且期望值准确率会更加有效。

缺点:如果训练样本集过大,会严重影响训练效率。而且占用存储空间会比较大。

3.应用场景

 手写数字识别系统、交友系统(甄别好友质量)。

4.数学公式应用

  欧氏距离公式:

 机器学*__k*邻算法_邻算法_14