<转载+随笔>机器学习实战_01_k邻近算法

原文地址:http://www.cnblogs.com/hemiy/p/6155425.html#3837219

本文主要对其中的函数用法作总结。

  1 #coding=UTF8
  2 from numpy import *
  3 import operator
  4 
  5 def createDataSet():
  6     """
  7     函数作用:构建一组训练数据(训练样本),共4个样本
  8     同时给出了这4个样本的标签,及labels
  9     """
 10     group = array([
 11         [1.0, 1.1],
 12         [1.0, 1.0],
 13         [0. , 0. ],
 14         [0. , 0.1]
 15     ])
 16     labels = ['A', 'A', 'B', 'B']
 17     return group, labels
 18 
 19 def classify0(inX, dataset, labels, k):
 20     """
 21     inX 是输入的测试样本,是一个[x, y]样式的
 22     dataset 是训练样本集
 23     labels 是训练样本标签
 24     k 是top k最相近的
 25     """
 26     # shape返回矩阵的[行数,列数],
 27     # 那么shape[0]获取数据集的行数,shape[1]返回列数。
    # shape 函数用法详见注解0
28 # 行数就是样本的数量 29 dataSetSize = dataset.shape[0] 30 31 """ 32 下面的求距离过程就是按照欧氏距离的公式计算的。 33 即 根号(x^2+y^2) 34 """ 35 # tile属于numpy模块下边的函数 !!详见注解1 36 # tile(A, reps)返回一个shape=reps的矩阵,矩阵的每个元素是A 37 # 比如 A=[0,1,2] 那么,tile(A, 2)= [0, 1, 2, 0, 1, 2] 38 # tile(A,(2,2)) = [[0, 1, 2, 0, 1, 2], 39 # [0, 1, 2, 0, 1, 2]] 40 # tile(A,(2,1,2)) = [[[0, 1, 2, 0, 1, 2]], 41 # [[0, 1, 2, 0, 1, 2]]] 42 # 上边那个结果的分开理解就是: 43 # 最外层是2个元素,即最外边的[]中包含2个元素,类似于[C,D],而此处的C=D,因为是复制出来的 44 # 然后C包含1个元素,即C=[E],同理D=[E] 45 # 最后E包含2个元素,即E=[F,G],此处F=G,因为是复制出来的 46 # F就是A了,基础元素 47 # 综合起来就是(2,1,2)= [C, C] = [[E], [E]] = [[[F, F]], [[F, F]]] = [[[A, A]], [[A, A]]] 48 # 这个地方就是为了把输入的测试样本扩展为和dataset的shape一样,然后就可以直接做矩阵减法了。 49 # 比如,dataset有4个样本,就是4*2的矩阵,输入测试样本肯定是一个了,就是1*2,为了计算输入样本与训练样本的距离 50 # 那么,需要对这个数据进行作差。这是一次比较,因为训练样本有n个,那么就要进行n次比较; 51 # 为了方便计算,把输入样本复制n次,然后直接与训练样本作矩阵差运算,就可以一次性比较了n个样本。 52 # 比如inX = [0,1],dataset就用函数返回的结果,那么 53 # tile(inX, (4,1))= [[ 0.0, 1.0], 54 # [ 0.0, 1.0], 55 # [ 0.0, 1.0], 56 # [ 0.0, 1.0]] 57 # 作差之后 58 # diffMat = [[-1.0,-0.1], 59 # [-1.0, 0.0], 60 # [ 0.0, 1.0], 61 # [ 0.0, 0.9]] 62 diffMat = tile(inX, (dataSetSize, 1)) - dataset 63 64 # diffMat就是输入样本与每个训练样本的差值,然后对其每个x和y的差值进行平方运算。 65 # diffMat是一个矩阵,矩阵**2表示对矩阵中的每个元素进行**2操作,即平方。 66 # sqDiffMat = [[1.0, 0.01], 67 # [1.0, 0.0 ], 68 # [0.0, 1.0 ], 69 # [0.0, 0.81]] 70 sqDiffMat = diffMat ** 2 71 72 # axis=1表示按照横轴,sum表示累加,即按照行进行累加。
#axis=0 就是普通的相加 ;加入axis=1以后就是将一个矩阵的每一行向量相加
73 # sqDistance = [[1.01], 74 # [1.0 ], 75 # [1.0 ], 76 # [0.81]] 77 sqDistance = sqDiffMat.sum(axis=1) 78 79 # 对平方和进行开根号 80 distance = sqDistance ** 0.5 81 82 # 按照升序进行快速排序,返回的是原数组的下标。 83 # 比如,x = [30, 10, 20, 40] 84 # 升序排序后应该是[10,20,30,40],他们的原下标是[1,2,0,3] 85 # 那么,numpy.argsort(x) = [1, 2, 0, 3] 86 sortedDistIndicies = distance.argsort() 87 88 # 存放最终的分类结果及相应的结果投票数 89 classCount = {} 90 91 # 投票过程,就是统计前k个最近的样本所属类别包含的样本个数 92 for i in range(k): 93 # index = sortedDistIndicies[i]是第i个最相近的样本下标 94 # voteIlabel = labels[index]是样本index对应的分类结果('A' or 'B') 95 voteIlabel = labels[sortedDistIndicies[i]] 96 # classCount.get(voteIlabel, 0)返回voteIlabel的值,如果不存在,则返回0 97 # 然后将票数增1 98 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 99 100 # 把分类结果进行排序,然后返回得票数最多的分类结果
    #sorted()函数详见注解3
101 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) 102 return sortedClassCount[0][0] 103 104 if __name__== "__main__": 105 # 导入数据 106 dataset, labels = createDataSet() 107 inX = [0.1, 0.1] 108 # 简单分类 109 className = classify0(inX, dataset, labels, 3) 110 print('the class of test sample is %s' %className)

注解0:shape函数

是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数。

      举例说明:          

from numpy.core import *
if __name__== "__main__":
    e = array([[1, 2],
         [3, 4],
         [5, 6]])
    print(e.shape)
(3, 2)
print(e.shape[0])
3
print(e.shape[1])
2
from numpy.core import *
if __name__== "__main__":
    e = array([1,1,1])
    print(e.shape)
(3,)

注解1:tile()函数

tile函数是模板numpy.lib.shape_base中的函数。函数的形式是tile(A,reps)  具体方法可以在pycharm中看源码  这是源码中的例子

    >>> a = np.array([0, 1, 2])
    >>> np.tile(a, 2)
    array([0, 1, 2, 0, 1, 2])
    >>> np.tile(a, (2, 2))
    array([[0, 1, 2, 0, 1, 2],
           [0, 1, 2, 0, 1, 2]])
#tile(a,(b, c))
#b表示将a中每一个列表复制b-1次按顺序加入a中,c表示将每一个列表里的元素复制(c-1)遍后加入该列表中
>>> np.tile(a, (2, 1, 2)) array([[[0, 1, 2, 0, 1, 2]], [[0, 1, 2, 0, 1, 2]]])    #(d,b,c)将(b,c)构成的矩阵复制d份 >>> b = np.array([[1, 2], [3, 4]]) >>> np.tile(b, 2) array([[1, 2, 1, 2], [3, 4, 3, 4]]) >>> np.tile(b, (2, 1)) array([[1, 2], [3, 4], [1, 2], [3, 4]]) >>> c = np.array([1,2,3,4]) >>> np.tile(c,(4,1)) array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])

注解2 zeros()函数

B=zeros(n):生成n×n全零阵。

B=zeros(m,n):生成m×n全零阵。

B=zeros([m n]):生成m×n全零阵。

B=zeros(d1,d2,d3……):生成d1×d2×d3×……全零阵或数组。

B=zeros([d1 d2 d3……]):生成d1×d2×d3×……全零阵或数组。

B=zeros(size(A)):生成与矩阵A相同大小的全零阵。

注解3:sorted()函数

sorted(iterable[, cmp[, key[, reverse]]])

参数解释:

(1)iterable指定要排序的list或者iterable,不用多说;

(2)cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数,如:

      students为类对象的list,没个成员有三个域,用sorted进行比较时可以自己定cmp函数,例如这里要通过比较第三个数据成员来排序,代码可以这样写:
      students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
      sorted(students, key=lambda student : student[2])
(3)key为函数,指定取待排序元素的哪一项进行排序,函数用上面的例子来说明,代码如下:
      sorted(students, key=lambda student : student[2])

      key指定的lambda函数功能是去元素student的第三个域(即:student[2]),因此sorted排序时,会以students所有元素的第三个域来进行排序。

有了上面的operator.itemgetter函数,也可以用该函数来实现,例如要通过student的第三个域排序,可以这么写:
sorted(students, key=operator.itemgetter(2)) 
sorted函数也可以进行多级排序,例如要根据第二个域和第三个域进行排序,可以这么写:
sorted(students, key=operator.itemgetter(1,2))

即先根据第二个域排序,再根据第三个域排序。
(4)reverse参数就不用多说了,是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列。

          

posted on 2017-12-12 22:04  wastelands  阅读(96)  评论(0)    收藏  举报

导航