k-近邻算法

---恢复内容开始---

k-近邻算法

2.1 算法优缺点

优点:精度高,对异常值不敏感,无数据输入假定。

缺点:计算复杂度高,空间复杂度高。

适用数据范围:数值型,标称型。

2.11-2.12 k-近邻算法的一般流程

算法:

def classify0(inX,dataSet,labels,k):
   dataSetSize = dataSet.shape[0] #样本维度
   diffMat = tile(inX,(dataSetSize,1))-dataSet     #创建一个(dataSetSize维度)
   sqDiffMat = diffMat**2
   sqDistances = sqDiffMat .sum(axis=1)
   distances = sqDistances**0.5
   sortedDistIndicies = distances.argsort()   #返回distances 从小到大的index
   classCount = {} #分类
   for i in range(k):
       voteIlabel =labels[sortedDistIndicies[i]]  #取出排K的分类
       classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1  #error  dict[obj]    'int' object has no attribute 'get'
   sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse =True) #根据第二项进行降序排序
   # classCount.iteritems()  #返回迭代器方法同items()
   #items()方法是将字典中的每个项分别做为元组,添加到一个列表中,形成了一个新的列表容器。如果有需要也可以将返回的结果赋值给新变量,这个新的变量就会是一个列表数据类型。
   print sortedClassCount   #[('B', 2), ('A', 1)]
   return sortedClassCount[0][0]
   '''
    a = [1,2,3] 
    >>> b=operator.itemgetter(1)      //定义函数b,获取对象的第1个域的值
    >>> b(a) 
    2 
    >>> b=operator.itemgetter(1,0)  //定义函数b,获取对象的第1个域和第0个的值
    >>> b(a) 
    (2, 1)
    要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。
    sorted函数
    Python内置的排序函数sorted可以对list或者iterator进行排序,官网文档见:http://docs.python.org/2/library/functions.html?highlight=sorted#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时将按降序排列。
   '''

1,收集数据:可以使用任何方法。

2,准备数据:距离计算所需的数值,最好是结构化的数据格式。

def creatDataSet():
     group = array([1.0,1.1],[1.0,1.0],[0,0],[0,0.1])
     labels = ['A','A','B','B']
     return group,labels

3,分析数据:可以使用任何方法。

4,训练算法:此步骤不适用k-近邻算法。

5,测试算法:测试错误率。

6,使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。

2.2.1 准备数据:从文本中解析数据

def file2matrix(filename):
    fr = open(filename)
    arrayOLines = fr.readlines()    #读取文件
    numberOfLines = len(arrayOLines)    #得到文件行数
    returnMat = zeros((numberOfLines,3))   #返回一个为0的矩阵
    '''
    zeros(shape[, dtype, order])
    依据给定形状和类型(shape[, dtype, order])返回一个新的元素全部为0的数组。
    参数:
    shape:int或者ints元组;
    定义返回数组的形状,形如:(2, 3)或2。
    dtype:数据类型,可选。 
    返回数组的数据类型,例如:numpy.int8、默认为numpy.float64。  
    order:{‘C’, ‘F’},可选,返回数组为多维时,元素在内存的排列方式是按C语言还是Fortran语言顺序(row- or columnwise)。    
    输出:ndarray
    给定形状,数据类型的数组。
    '''
    classLabelVector = []
    index = 0 
    for line in arrayOLines:
        line = line.strip()
        listFromLine = line.split('	')
        returnMat[index,:]=listFromLine[0:3]    #每行前3个放入矩阵
        classLabelVector.append(int(listFromLine[-1]))
        index+=1
    return returnMat,classLabelVector

2.2.2 分析数据:使用Matplotlib创建散点图

import matplotlib
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)   #绘制子图1行,1列,第一个
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))   #行,列,数据颜色
plt.show()

2.2.3 准备数据:归一化数值

公式:(oldValue - min)/(max-min)     {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))   
    normDataSet = normDataSet/(tile(maxVals, (m,1))-tile(minVals, (m,1)))
    return normDataSet,ranges,minVals

a.min()取a中最小值

a.min(0)区列中最小值

a.min(1)取行中最小值

2.2.4 测试算法

def datingClassTest():
    hoRatio = 0.1
    datingDataMat,datingLabels = file2matrix(r'C:UsershomeDesktopDjango
arCh02datingTestSet2.txt')
    normMat,ranges,minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount = 0.0
    #print numTestVecs
    for i in range(numTestVecs):   #计算前numTestVecs个是否符合
        
        classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m],3)
        if classifierResult!=datingLabels[i]:
            errorCount+=1.0
    print 'toal error rate is %f'%(errorCount/float(numTestVecs))   #错误率

2.2.5 使用算法:构建完整可用系统

---恢复内容结束---

k-近邻算法

1,算法优缺点

优点:精度高,对异常值不敏感,无数据输入假定。

缺点:计算复杂度高,空间复杂度高。

适用数据范围:数值型,标称型。

2,k-近邻算法的一般流程

算法:

def classify0(inX,dataSet,labels,k):
   dataSetSize = dataSet.shape[0] #样本维度
   diffMat = tile(inX,(dataSetSize,1))-dataSet     #创建一个(dataSetSize维度)
   sqDiffMat = diffMat**2
   sqDistances = sqDiffMat .sum(axis=1)
   distances = sqDistances**0.5
   sortedDistIndicies = distances.argsort()   #返回distances 从小到大的index
   classCount = {} #分类
   for i in range(k):
       voteIlabel =labels[sortedDistIndicies[i]]  #取出排K的分类
       classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1  #error  dict[obj]    'int' object has no attribute 'get'
   sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse =True) #从大到小概率高的排序
   # classCount.iteritems()  #返回迭代器方法同items()
   #items()方法是将字典中的每个项分别做为元组,添加到一个列表中,形成了一个新的列表容器。如果有需要也可以将返回的结果赋值给新变量,这个新的变量就会是一个列表数据类型。
   print sortedClassCount   #[('B', 2), ('A', 1)]
   return sortedClassCount[0][0]
   '''
    a = [1,2,3] 
    >>> b=operator.itemgetter(1)      //定义函数b,获取对象的第1个域的值
    >>> b(a) 
    2 
    >>> b=operator.itemgetter(1,0)  //定义函数b,获取对象的第1个域和第0个的值
    >>> b(a) 
    (2, 1)
    要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。
    sorted函数
    Python内置的排序函数sorted可以对list或者iterator进行排序,官网文档见:http://docs.python.org/2/library/functions.html?highlight=sorted#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时将按降序排列。
   '''

1,收集数据:可以使用任何方法。

2,准备数据:距离计算所需的数值,最好是结构化的数据格式。

def creatDataSet():
     group = array([1.0,1.1],[1.0,1.0],[0,0],[0,0.1])
     labels = ['A','A','B','B']
     return group,labels

3,分析数据:可以使用任何方法。

4,训练算法:此步骤不适用k-近邻算法。

5,测试算法:测试错误率。

6,使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。

原文地址:https://www.cnblogs.com/Zidon/p/5089972.html